岡薩雷斯《數字圖像處理》第3版課后習題


 

   

 

 

第3章

 

 

3.6

原題:試解釋為什么離散直方圖均衡技術一般不能得到平坦的直方圖?

答:假設有一副圖像,共有像素個數為n=MN(M行N列),像素灰度值取值范圍為(0~255),那么該圖像的灰度值的個數為L=256,為了提高圖像的對比度,通常我們都希望像素的灰度值不要都局促到某一個狹窄的范圍,也就是我們通常說的圖像灰度值的動態分布小。最好是在有效灰度值取值范圍上,每個灰度值都有MN/L個像素,這個時候我們就可以得到一張對比度最理想的圖像,也就是說像素的取值跨度大,像素灰度值的動態范圍大。

因為直方圖是PDF(概率密度函數)的近似,而且在處理中,不允許造成新的灰度級,所以在實際的直方圖均衡應用中,很少見到完美平坦的直方圖。因此,直方圖均衡技術不能保證直方圖的均勻分布,但是卻可以擴展直方圖的分布范圍,也就意味着在直方圖上,偏向左的暗區和偏向右的亮區都有像素分布,只是不能保證每個灰度級上都有像素分布。

(百度答案:)由於離散圖像的直方圖也是離散的,其灰度累積分布函數是一個不減的階梯函數。如果映射后的圖像仍然能取到所有灰度級,則不發生任何變化。如果映射的灰度級小於256,變換后的直方圖會有某些灰度級空缺。即調整后灰度級的概率基本不能取得相同的值,故產生的直方圖不完全平坦。

 

 3.8

原題:在某些應用中,將輸入圖像的直方圖模型化為高斯概率密度函數效果會是比較好的,高斯概率密度函數為:

                                         

其中m和σ分別是高斯概率密度函數的均值和標准差。具體處理方法是將m和σ看成是給定圖像的平均灰度級和對比度。對於直方圖均衡,您所用的變換函數是什么?

答:直方圖均衡變換函數的一般表達式如下:
                                                

在回答這個問題時,有兩點非常重要,需要學生表達清楚。

第一,   這個表達式假定灰度值r只有正值,然而,高斯密度函數通常的取值范圍是-∞~∞,認識到這點是非常重要的,認識到這點,學生才能以多種不同的方式來解決問題。對於像標准差這樣的假設,好的答案是,需要足夠小,以便於當r為小於0時,在pr(r)曲線下的面積可以被忽略。另一種回答就是,將值(不知道什么值)按比例增大,直到r小於0部分的曲線下的面積可以被忽略。

第二,要讓學生認識到,變換函數本身,
                                              

並沒有閉合形式解(closed-form solution)。這是高斯密度函數的累積分布函數,該函數或者是數字可積的,或者其值有表可查。

第三點,不是很重要,但學生要說清楚,那就是r的高端值(high-end value)。再強調一遍,高斯PDF是趨於正無窮(+∞)的,一個可行性的方法就是根據標准差,和前面一樣對其做個假設。另一個可行方法就是除以一個足夠大的值,使得在大於r部分函數曲線下的面積可以忽略(這實際上就是相當於比例縮小標准差)。

學生還需做的工作就是處理直方圖,此時的變換函數是一種和的形式。負值和超過r的正值問題還是需要說明白,對於這些問題,前面建議的答案依然適用。學生需要指出,直方圖是通過對連續函數采樣得到的,所以對於采樣的比特位數應該給出建議。最可能的答案是8比特,此時學生還需描述函數縮放比例,以便其取值在[0,255]范圍之內。

 

Opencv中的均值和標准差函數meanStdDev

C++: void meanStdDev(InputArray src, OutputArray mean, OutputArray stddev, InputArray

mask=noArray())

C: void cvAvgSdv(const CvArr* arr, CvScalar* mean, CvScalar* std_dev, const CvArr* mask=NULL )

Python: cv.AvgSdv(arr, mask=None) -> (mean, stdDev)

Parameters

  src – 輸入矩陣,通道數為1~4,input array that should have from 1 to 4 channels so that the results can be stored in

    Scalar_ ‘s.

  mean – 輸出參數,數據類型為Match,用於保存均值。

  stddev –輸出參數,數據類型為Mat,用於保存標准差。

  mask – 可選的mask運算。

函數meanStdDev 用於計算每個通道上的均值和標准差,分別保存在mean和std_dev中。

meanStdDev實例

#include <iostream>

#include <opencv2/opencv.hpp>

using namespace cv;

using namespace std;

int main()

{

    Mat img=imread("D:/CodeWork/MyImage/baboon.jpg",0);

   // imshow("my test image!",img);

    Mat mat_mean,mat_stddev;

    meanStdDev(img,mat_mean,mat_stddev);

    double m,s;

    m=mat_mean.at<double>(0,0);

    s=mat_stddev.at<double>(0,0);

    cout<<"mean="<<m<<endl;

    cout<<"stddev="<<s<<endl;

    waitKey();

    return 0;

}

輸出結果如下:

 

高斯PDF函數實例

在本例中,依然借用上一個實例中的圖片的均值和方差,根據本題中的高斯PDF公式:

                                        

創建高斯概率密度函數曲線,即高斯PDF,該“曲線”實際上就是一個一維Mat型數據,用pr表示,p表示概率,r表示灰度級。上面的公式中的σ用s表示,只是為了方便,與前面的s不要弄混。

void plot(const Mat&src,const string winName="PlotWindow")
{
    int rows=src.rows,cols=src.cols ;
    if(rows!=1&&cols!=1)
    {
        cout<<"your input is not one dim!"<<endl;
        return;
    }
    double minv,maxv;
    minMaxLoc(src,&minv,&maxv);
    int wx=cols*1.4,wy=maxv*1.2;
    int blankLeft=cols*0.2;
    int blankBottom=maxv*0.1;
    namedWindow(winName);
    Mat img(wy,wx,CV_8UC3,Scalar::all(0));
    //繪制坐標軸
    Point origin(blankLeft,wy-blankBottom);
    Point arrowx(wx-10,wy-blankBottom);
    Point arrowy(blankLeft,10);
    plotCoordinate(img,origin,arrowx,arrowy,Scalar(0,255,255));
    //繪制高斯PDF曲線
    Point p1,p2;
    if(rows==1)
    {
        for(int i=0;i<cols-1;i++)
        {
            p1.x=i+blankLeft;
            p1.y=src.at<uchar>(0,i);
            p1.y =wy-p1.y-blankBottom;

            p2.x=i+1+blankLeft;
            p2.y=src.at<uchar>(0,i+1);
            p2.y=wy-p2.y-blankBottom;
            line(img,p1,p2,Scalar(255,0,255),3);
        }
    }
    else
    {
        for(int i=0;i<rows-1;i++)
        {
            p1.y=i;
            p1.x=src.at<uchar>(0,i);

            p2.y=i+1;
            p2.x=src.at<uchar>(0,i+1);
            line(img,p1,p2,Scalar(255,0,255),3);
        }
    }
    //cv::resize(img,img,Size(img.cols*2,img.rows*2));
    imshow(winName,img);
//有些系統不能按“alt+PrtSc”會直接退出,所以要用waitKey等待5秒,同時在主程序中也要有waitKey(),否則還是會自動退出。

  waitKey(500000);


}

 在plot()函數還調用了繪制坐標函數
void plotCoordinate(Mat& src,Point origin,Point px,Point py,Scalar color)

  src--准備繪制坐標軸的矩陣;
  origin--坐標原點;
  px     --x軸坐標端點;
  py   ----y軸坐標端點;
繪制坐標函數定義如下:

void plotCoordinate(Mat& src,Point origin,Point px,Point py,Scalar color)
{
    line(src,origin,px,color);
    line(src,origin,py,color);
    line(src,px,Point(px.x-10,px.y-3),color);
    line(src,px,Point(px.x-10,px.y+3),color);
    line(src,py,Point(py.x+3,py.y+10),color);
    line(src,py,Point(py.x-3,py.y+10),color);
}

下面是主程序:

int main()
{
    Mat img=imread("D:/CodeWork/MyImage/baboon.jpg",0);
    // imshow("my test image!",img);
    Mat mat_mean,mat_stddev;
    meanStdDev(img,mat_mean,mat_stddev);
    double m,s;//m是均值,s是標准差
    m=mat_mean.at<double>(0,0);
    s=mat_stddev.at<double>(0,0);
//    cout<<"mean="<<m<<endl;
//    cout<<"stddev="<<s<<endl;
    Mat pr(1,256,CV_64F,Scalar::all(0));
    s *=0.2;//標准差s分別乘以0.2,0.5,1,1.5,2時,觀察高斯曲線的變化
    for(int r=0;r<256;r++)
    {
        pr.at<double>(0,r)= std::exp(-(r-m)*(r-m)/(2*s*s))/(sqrt(2*3.14)*s);
    }
    cv::normalize(pr,pr,1,0,NORM_MINMAX);
    pr=pr*255;//將取值范圍擴展到255
    pr.convertTo(pr,CV_8U);

    cout<<"pr="<<endl<<pr<<endl;
    plot(pr,"s*0.2");
    waitKey();
    return 0;
}

下面是標准差s乘以0.2、0.5、1、1.5、2時,高斯PDF函數曲線的變化情況:

     

  

 

接下來,我們利用上面五個不同標准差值,根據公式(3)將高斯概率密度分布函數轉換成高斯概率累積分布函數,實現程序如下:
   
  

從T(r)曲線的變化我們可以發現,隨着標准差的增大,T(r)曲線越來越接近45°直線,當標准差放大6倍時,已經是一條45°直線了,這意味着標准差越大,該變換曲線,對變換結果的影響越小。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.24

 

原題:證明如式(3.6-3)所示的拉普拉斯變換是各向同性的(即旋轉不變)。您需要下列軸旋轉θ角的坐標方程為:
                  

其中(x,y)為未旋轉的坐標,而為旋轉后的坐標。

答案:

坐標未旋轉時的拉普拉斯運算表達式如下:
                        

坐標旋轉后的表達式如下:
                       

我們已經知道,坐標旋轉公式為:
                    

其中θ為旋轉角度,為了證明前面兩個拉普拉斯表達式的右邊相等,我們先求解fx’的一階導數在原坐標中的表達式:
                     

對上面的表達式繼續微分得到:
               

同理,我們也可以求得的原坐標表達式:
               

將兩個二階微分表達式相加,我們就得到:
              
這樣我們就證明了,拉普拉斯運算是旋轉無關的運算。

 

 

 

 

3.25 

中心為-4的拉普拉斯模板,執行的是水平和垂直方向上的差分運算。我們可以先考察一個 3×3的拉普拉斯模板,模板的中心值為-2,中心上下都為1,其它元素值為0,這樣的模板只是執行了垂直方向的差分,

而與之正交的亮度值的變化卻被忽略了,經過該模板處理的圖像,只有在垂直方向的像素會被銳化增強。而中心值為-4的模板則同時對垂直和水平兩個方向上進行微分處理,因此在垂直和水平兩個方向的像素都得到了銳化增強,
這樣的增強效果也會比單方向的銳化更明顯。同樣的,中心值為-8的模板對圖像執行了四個方向上的銳化增強,這樣通常會得到更好的銳化結果。

3.26

          

                                      圖3.26

 (a)  3×3 拉普拉斯模板的尺寸和系數是直接有方程(3.6-6)得到的,該方程為

2f(x,y)=f(x+1,y)+f(x-1,y)+f(x,y+1)+f(x,y-1)-4f(x,y)
換句話說,拉普拉斯模板中的數字,就是二階微分方程中的系數。如果用一個更大的“類拉普拉斯模板”與圖像卷積,並不會實現圖像的二階微分,所以我們也不要指望能夠給出一個更加銳化的結果。
實際上,正如在(b)中解釋的,不但不會銳化,反而變得模糊了。
(b)通常,增大“類拉普拉斯模板”的尺寸,會使圖像變得模糊。為什么會這樣呢?我們先假設有一個圖像,該圖像是由兩個垂直的條帶組成,左邊是黑色條帶右邊是白色條帶,黑白的分界線剛好通過
圖像的中心,也就是說圖像的中心有一個銳利的垂直邊線,如圖3.26所示。在書上正文98頁,圖3.36中,我們知道,當3×3拉普拉斯模板中心位於垂直邊線上時,二階微分會在垂直邊線區域產生一
個雙邊線;這是由於當模板中心在垂直邊線上繼續移動超過兩個像素時,該模板所包圍的區域像素值相同,經卷積計算后該區域的值為0。然而,如果模板太大,當模板中心位於黑色區域時,模板的
一半完全處於黑色區域,而依據模板尺寸的大小,模板的一部分會處於圖像的白色區域,這樣卷積結果將不再是二階微分的0,這意味着卷積后,本該為0的區域不再是0,圖3.26顯示了卷積效果。
圖中左上角就是准備被處理的圖像,緊挨着的圖像是用中心為8的 3×3 拉普拉斯模板卷積結果。其它圖像是分別用尺度 15×15, 35×35, 75×75,and 125 ×125類拉普拉斯模板卷積后的結果。隨着模板尺寸
的增加,圖像變得越來越模糊。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM