《數字影象處理》學習筆記(三)--空間域影象增強
X. 銳化空間濾波器
銳化處理的主要目的是突出影象中的細節或者增強被模糊了的細節,這種模糊不是由於錯誤操作,就是特殊影象獲取方法的固有印象。總的來說,微分運算元的響應強度與影象在該店(應用了運算元)的突變程度有關。這樣一來,影象微分增強了邊緣和其他突變(如噪聲)並削弱了灰度變化緩慢的區域。
為了說明簡單,主要集中討論一階微分的性質。我們最高興去的微分性質是恆定灰度區域(平坦段)、突變的開頭與結尾(階梯和斜坡突變)及沿著灰度級斜坡處的特性。這些型別的突變可以用來對影象中的噪聲點、細線與邊緣模型化。
這裡我們首先了解下數學函式的微分,微分可以用不同的術語定義,也有各種方法定義這些差別,然而,對於一階微分任何定義都必須保證以下幾點:(1)在平坦段(灰度不變區域)微分值為零;(2)在灰度階梯或斜坡的起始點處微分值非零;(3)沿著斜坡面微分值非零。任何二階微分的定義也類似:(1)在平坦去微分值必為零;(2)在灰度階梯或斜坡的起始點處微分值非零;(3)沿著斜坡面微分值非零。
因為我們處理的是數字量,其值是有限的,故最大灰度級的變換也是有限的,變化發生最短距離是在兩相鄰畫素之間。對於一元函式f(x)表達一階微分定義是一個差值:
這裡,為了與對二元影象函式f(x,y)求微分時的表示式保持一致,使用偏導數符號,對二元函式,我們將沿著兩個空間軸處理偏微分,類似地,用差分定義二階微分:
XX. 基於二階微分的影象增強--拉普拉斯運算元
這裡介紹二階微分在影象增強處理中的應用。首先定義一個二階微分的離散公式,然後構造一個基於此式的濾波器。我們最關注的是一種各向同性濾波器,這種濾波器的響應與濾波器作用的影象的突變方向無關。也就是說,各向同性濾波器是旋轉不變的,即將原始影象旋轉後進行濾波處理給出的結果與先對影象濾波,然後再旋轉的結果相同。
處理方法
最簡單的各向同性微分運算元是拉普拉斯運算元,一個二元影象函式f(x,y)的拉普拉斯變換定義為:
因為任意階微分都是線型操作,所以拉普拉斯變換也是一個線性操作。
考慮到有兩個變數,因此,我們在x,y方向上對二階偏微分採用下倆定義:
因此二維拉維拉斯數字實現可由這兩個分量相加得到:
,這裡關注係數矩陣即掩膜:
這個矩陣給出了在90度方向上旋轉的各向同性結果,如果向得到45度方向上旋轉的各向同性結果則,將中心對角點標為1,中心點為-8即可。
由於拉普拉斯是一種微分運算元,它的應用強調影象中灰度的突變及降低灰度慢變化的區域。將原始影象和拉普拉斯影象疊加在一起的簡單方法可以保護拉普拉斯銳化處理的效果,同時又能復原背景資訊。我們使用拉普拉斯變換對影象增強的基本方法可表示為下式:
在Opencv上做了下試驗,分別是原圖,laplace變換後圖,和做差圖。很明顯經過拉普拉斯變換後圖像銳化,同時儘可能保留了其灰度色調。而經過做差後的影象細節更加清晰(感覺有點小問題,希望大家指正,應該是顏色空間搞錯了,不過細節確實更加清晰了)
#include "dipHeader.h"
void enhanceImage(IplImage* srcImg,IplImage* dstImg)
{
if (srcImg->nChannels==3)
{
IplImage* lapbur=cvCreateImage(cvGetSize(srcImg),IPL_DEPTH_16S,1);
IplImage* lapbur8U=cvCreateImage(cvGetSize(srcImg),IPL_DEPTH_8U,1);
IplImage* temp[3];
IplImage* tempsrc;
tempsrc = cvCreateImage(cvGetSize(srcImg),IPL_DEPTH_8U,1);
for (int j=0;j<3;j++)
{
temp[j] = cvCreateImage(cvGetSize(srcImg),8,1);
}
cvSplit(srcImg,temp[0],temp[1],temp[2],0);
for (int i=0;i<3;i++)
{
cvSmooth(temp[i],tempsrc,CV_GAUSSIAN);
cvLaplace(tempsrc,lapbur,1);
cvConvertScale(lapbur,lapbur8U);
cvSub(temp[i],lapbur8U,temp[i]);
}
cvMerge(temp[0],temp[1],temp[2],0,dstImg);
}
if (srcImg->nChannels==1)
{
IplImage* lapbur=cvCreateImage(cvGetSize(srcImg),IPL_DEPTH_16S,1);
IplImage* tempsrc;
tempsrc = cvCreateImage(cvGetSize(srcImg),IPL_DEPTH_8U,1);
cvSmooth(srcImg,tempsrc,CV_GAUSSIAN);
cvLaplace(tempsrc,lapbur,1);
cvConvertScale(lapbur,tempsrc);
cvSub(srcImg,tempsrc,dstImg);
}
}
void main()
{
IplImage* src = cvLoadImage("moon.tif");
cvNamedWindow("src",0);
cvShowImage("src",src);
#if 1//1.影象增強laplace
IplImage* enImg = cvCreateImage(cvGetSize(src),8,src->nChannels);
enhanceImage(src,enImg);
cvNamedWindow("enImg",0);
cvShowImage("enImg",enImg);
cvWaitKey(0);
#endif
#if 1 //灰度
IplImage* gray = cvCreateImage(cvGetSize(src),8,1);
IplImage* graydst = cvCreateImage(cvGetSize(src),8,1);
cvCvtColor(src,gray,CV_BGR2GRAY);
enhanceImage(gray,graydst);
cvNamedWindow("gray",0);
cvShowImage("gray",gray);
cvNamedWindow("graydst",0);
cvShowImage("graydst",graydst);
cvWaitKey(0);
#endif
}