基於OpenCV的同態濾波

在4.0.1節中,咱們已經介紹了一個簡單的圖像造成模型,即照射-反射模型。這個模型能夠開發一種頻率處理程序,該程序能夠同時壓縮灰度範圍和加強對比度來改善一幅圖像的表現。圖像造成的照射-反射模型的表達式以下:函數

f(x,y)=i(x,y)r(x,y)                                         6.4- 16spa

上式不能直接用於對照射和反射的頻率份量進行操做,由於兩個份量的傅里葉變換之積,不等於原圖像的傅里葉變換:3d

                                6.4- 17code

可是,咱們能夠定義以下變換關係:orm

                    6.4- 18blog

而後再對上式兩邊作傅里葉變換:ci

       6.4- 19element

獲得下面的傅里葉變換域的等式:開發


                                 6.4- 20it

其中, 分別是 的傅里葉變換。

咱們能夠用一個濾波器 對 濾波,故有:

         6.4- 21

在空間域中,濾波後的圖像爲:

        6.4- 22

咱們能夠將上式改寫成簡略形式:

                                    6.4- 23

其中,

                                  6.4- 24

                                 6.4- 25

最後,由於 是經過取輸入圖像的天然對數造成的,咱們可經過取濾波後的結果的指數這一反處理來造成輸出圖像:

                6.4- 26

                        6.4- 27

                                            6.4- 28

經濾波處理後的照射和反射份量。

以上推到的濾波方法流程圖,如圖6. 26所示。該濾波方法是針對特定成像系統,在此稱爲同態系統。在這種特殊應用中,方法的關鍵在於照射份量和反射份量的分離,其實現形式(6.4-20)所示。而後,如式(6.4-21)那樣,用同態濾波器 對這些份量進行濾波操做。

 圖像的照射份量一般由慢的空間變化來表徵,而反射份量每每引發突變,特別是在不一樣物體的鏈接部分。這些特性致使圖像取對數後的傅里葉變換的低頻成分與照射份量相聯繫,而高頻成分與反射份量相聯繫。雖然這些聯繫只是粗略的近似,但它們用在圖像濾波中是有益的。

 

圖6. 27所示的函數形狀可用高通濾波器的基本形式來近似。例如,採用形式稍微變化一下的高斯高通濾波器可獲得函數:使用同態濾波器可更好地控制照射份量和反射份量。這種控制須要指定一個濾波器函數 ,它可用不一樣的可控方法影響傅里葉變換的低頻和高頻份量。圖6. 27顯示了這種濾波器的剖面圖。若是 和 選定, 且 ,那麼圖6. 27所示濾波器函數趨向於衰減低頻(照射)的貢獻。

                                                                        6.4- 29

其中 由式(6.3-2)定義,常數c控制函數坡度的銳利度,它在 和 之間過渡。這個濾波器相似於前面6.4.3節討論的高頻強調濾波器。

例6. 10 使用同態濾波加強圖像

圖6. 28(a)顯示了一幅大小爲1162×746像素的全身PET掃描圖像。圖像稍微有些模糊,而且因爲主導顯示動態範圍的高灰度「熱點」使得其許多低灰度特徵很朦朧(這些「熱點」是由腦部的腫瘤和肺部的腫瘤致使的)。

圖6. 28(b)是圖6. 28(a)經同態濾波湖獲得的結果,使用式(6.4-8)中的濾波器, 。改濾波器的剖面看上去正好像圖6. 27,只是坡度有點陡峭。

 


下面是主程序:
Mat homoMorphicFilter(const Mat& src,double D0, double gammaH,double gammaL,double c) { int rows=src.rows,cols=src.cols,channels=src.channels(); Mat srcLog,src64d; src.convertTo(src64d,CV_64FC1); cv::log(src64d+1,srcLog); Mat srcLogFft=fft(srcLog); dftshift(srcLogFft); //建立同態濾波器 Mat Huv(rows,cols,CV_64FC2,Scalar::all(0));//頻域濾波器 int cx=cols/2,cy=rows/2; double D2=D0*D0; for(int i=0;i<rows;i++) { Vec2d* p=Huv.ptr<Vec2d>(i); for(int j=0;j<cols;j++) { double x=j-cx,y=i-cy; p[j][0]=(gammaH-gammaL)*(1-c*exp(-(x*x+y*y)/D2))+gammaL; p[j][1]=p[j][0]; } } Huv /=(rows*cols); //頻域濾波,在頻域與Huv逐點相乘 Mat ftProduct=srcLogFft.mul(Huv); //逆傅里葉變換 Mat ftInv=fft(ftProduct,DFT_INVERSE); //計算逆傅里葉變換的幅值 Mat mag= myMagnitude(ftInv); Mat edst; cv::exp(mag,edst); normalize(edst,edst,255,0,NORM_MINMAX); edst.convertTo(edst,CV_8UC1); return edst; }
int main()
{
    Mat img=imread("D:/CodeWork/MyImage/Fig0462a.tif",0);
    imshow("rogin img",img);
    Mat imgHomo=homoMorphicFilter(img,80,3,0.25,1.);
    imshow("homoMorphic filter",(imgHomo+img)/2);
    waitKey();
    return 0;
}

下面左圖是通過同態濾波後的結果,右圖是原圖像:

 

   

例6.9中的胸部透視圖像的同態濾波:

int main()
{
    Mat img=imread("D:/CodeWork/MyImage/Fig0459a.tif",0);
    imshow("rogin img",img);
    Mat imgHomo=homoMorphicFilter(img,60,2,0.25,1.);
    imgHomo =imgHomo*0.5+img*0.5;
    equalizeHist(imgHomo,imgHomo);
    imshow("homoMorphic filter",imgHomo);
    waitKey();
    return 0;
}

 

下面是胸部透視圖像,左邊是原圖,右邊是同態濾波的結果:

 

相關文章
相關標籤/搜索