圖像銳化主要影響圖像中的低頻分量,不影響圖像中的高頻分量。
圖像銳化的主要目的有兩個:
1.增強圖像邊緣,使模糊的圖像變得更加清晰,顏色變得鮮明突出,圖像的質量有所改善,產生更適合人眼觀察和識別的圖像;
2.希望通過銳化處理后,目標物體的邊緣鮮明,以便於提取目標的邊緣、對圖像進行分割、目標區域識別、區域形狀提取等,進一步的圖像理解與分析奠定基礎。
圖像銳化一般有兩種方法:
1.微分法
2.高通濾波法
這里主要介紹一下兩種常用的微分銳化方法:梯度銳化和拉普拉斯銳化。
注意:由於銳化使噪聲受到比信號還要強的增強,所以要求銳化處理的圖像有較高的信噪比;否則,銳化后的圖像的信噪比更低。
1.梯度銳化
基本理論
鄰域平均法或加權平均法可以平滑圖像,反過來利用對應的微分算法可以銳化圖像。微分算法是求信號的變化率,有加強高頻分量胡作用,從而使圖像輪廓清晰。
由於圖像模糊胡實質是圖像受到平均或積分運算造成的,所以為了把圖像中任何方向伸展的邊緣肯模糊的輪廓變得清晰,可以對圖像進行逆運算如微分運算,從而使圖像清晰化。
在圖像處理中,一階微分是通過梯度算法來實現的,對於一幅圖像用函數f(x,y)表示,定義在f(x,y)在點(x,y)處的梯度是一個矢量,定義為:
梯度的方向在函數f(x,y)最大變化率的方向上,梯度的幅度G[f(x,y)]可以由以下公式算出:
由上式可知:梯度的數值就是f(x,y)在其最大變化率方向上的單位距離所增加的量。
對於數字圖像而言,微分可用差分來近似。因此上式可以寫成:
為了便於編程和提高運算速度,在計算精度允許的情況下,可采用絕對差算法近似為:
這種算法又稱為水平垂直差分法,另一種梯度算法是交叉的進行查分計算,稱為羅伯特梯度法,表示為:
同樣可采用絕對差算法近似:
運用上述兩種梯度近似算法,在圖像的最后一行后最后一列無法計算像素的梯度時,一般用前一行或前一列的梯度值近似代替。
為了不破壞圖像背景的前提下更好地增強邊緣,也可以對上述直接用梯度值代替灰度值的方法進行改進,可以引入一個閾值來判斷是否對某一像素點進行銳化。具體公式如下:
對於圖像而言,物體與物體之間,背景與背景之間的梯度變化很小,灰度變化較大的地方一般集中在圖像的邊緣上,也就是物體和背景交接的地方。當我們設定一個閾值時,G[f(i,j)]大於閾值就認為該像素點處於圖像的邊緣,對結果加上常數C,以使邊緣變亮;而對於G[f(i,j)]不大於閾值就認為該像素點為同類像素,即同為物體或同為背景,常數C的選取可以根據具體的圖像特點。這樣既增亮了圖像的邊界,同時又保留了圖像背景原來的狀態,比傳統的梯度銳化具有更好的增強效果和適用性。
另外拉普拉斯算子也可用於圖像銳化,這里不再贅述。
算法實現:

1 /************************************************************************* 2 * 函數名稱: 3 * GradSharp() 4 * 參數: 5 * BYTE bThre - 閾值 6 * 返回值: 7 * BOOL - 成功返回TRUE,否則返回FALSE。 8 * 說明: 9 * 該函數用來對圖像進行梯度銳化,設定梯度銳化的閾值為30 10 /************************************************************************/ 11 void CImgEnhance::GradSharp(unsigned char Thre) 12 { 13 unsigned char* pSrc; // 指向源圖像的指針 14 unsigned char* pDst; 15 unsigned char* pSrc1; 16 unsigned char* pSrc2; 17 LONG i,j; // 循環變量 18 int bTemp; 19 if(m_pImgDataOut != NULL) 20 { 21 delete []m_pImgDataOut; 22 m_pImgDataOut = NULL; 23 } 24 25 if(m_nBitCount != 8) 26 { 27 AfxMessageBox("只能處理8位灰度圖像!"); 28 return ; 29 } 30 int lineByte = (m_imgWidth * m_nBitCount / 8 + 3) / 4 * 4; 31 32 //創建要復制的圖像區域 33 m_nBitCountOut = m_nBitCount; 34 int lineByteOut = lineByte; 35 if (!m_pImgDataOut) 36 { 37 m_pImgDataOut = new unsigned char[lineByteOut * m_imgHeight]; 38 } 39 40 int pixelByte = m_nBitCountOut / 8; // 此處實際就是1,因為只處理8位圖像 41 for(i = 0; i < m_imgHeight; i++) 42 { 43 for(j = 0; j < m_imgWidth * pixelByte; j++) 44 *(m_pImgDataOut + i * lineByteOut + j) = *(m_pImgData + i * lineByteOut + j); 45 } 46 47 for(i = 0; i < m_imgHeight; i++) // 每行 48 { 49 for(j = 0; j < m_imgWidth; j++) // 每列 50 { 51 //指向新DIB第i行第j列的像素的指針 52 pDst = m_pImgDataOut + lineByte * i + j; 53 54 // 進行梯度運算 55 // 指向DIB第i行,第j個象素的指針 56 pSrc = (unsigned char*)m_pImgData + lineByte * i + j; 57 // 指向DIB第i+1行,第j個象素的指針 58 pSrc1 = (unsigned char*)m_pImgData + lineByte * (i+1) + j; 59 // 指向DIB第i行,第j+1個象素的指針 60 pSrc2 = (unsigned char*)m_pImgData + lineByte * i + j + 1; 61 bTemp = abs((*pSrc)-(*pSrc1)) + abs((*pSrc)-(*pSrc2)); 62 63 // 判斷是否小於閾值 64 if ((bTemp+120) < 255) 65 { 66 // 判斷是否大於閾值,對於小於情況,灰度值不變。 67 if (bTemp >= Thre) 68 { 69 *pSrc = bTemp + 120; 70 } 71 } 72 else 73 { 74 *pSrc = 255; 75 } 76 //生成新的DIB像素值 77 *pDst = *pSrc; 78 } 79 } 80 81 }