天天看點

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

大家好,又見面了,我是你們的朋友全棧君。

第3章

3.6

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

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

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

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

3.8

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

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

其中m和σ分别是高斯機率密度函數的均值和标準差。具體處理方法是将m和σ看成是給定圖像的平均灰階級和對比度。對于直方圖均衡,您所用的變換函數是什麼?

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

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

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

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

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

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

并沒有閉合形式解(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;

}

輸出結果如下:

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

高斯PDF函數執行個體

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

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

建立高斯機率密度函數曲線,即高斯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版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

接下來,我們利用上面五個不同标準內插補點,根據公式(3)将高斯機率密度分布函數轉換成高斯機率累積分布函數,實作程式如下:

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

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

3.24

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

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

其中(x,y)為未旋轉的坐标,而為旋轉後的坐标。

答案:

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

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

坐标旋轉後的表達式如下:

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

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

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

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

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

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

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

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

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

将兩個二階微分表達式相加,我們就得到:

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

這樣我們就證明了,拉普拉斯運算是旋轉無關的運算。

3.25

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

而與之正交的亮度值的變化卻被忽略了,經過該模闆處理的圖像,隻有在垂直方向的像素會被銳化增強。而中心值為-4的模闆則同時對垂直和水準兩個方向上進行微分處理,是以在垂直和水準兩個方向的像素都得到了銳化增強,

這樣的增強效果也會比單方向的銳化更明顯。同樣的,中心值為-8的模闆對圖像執行了四個方向上的銳化增強,這樣通常會得到更好的銳化結果。

3.26

岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章
岡薩雷斯《數字圖像處理》第3版課後習題[通俗易懂]第3章

圖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類拉普拉斯模闆卷積後的結果。随着模闆尺寸的增加,圖像變得越來越模糊。

釋出者:全棧程式員棧長,轉載請注明出處:https://javaforall.cn/167516.html原文連結:https://javaforall.cn