圖像銳化主要影響圖像中的低頻分量,不影響圖像中的高頻分量。
圖像銳化的主要目的有兩個:
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的選取可以根據具體的圖像特點。這樣既增亮了圖像的邊界,同時又保留了圖像背景原來的狀態,比傳統的梯度銳化具有更好的增強效果和適用性。
另外拉普拉斯算子也可用于圖像銳化,這里不再贅述。
算法實現:
******************************************************************************************************************************************
紅:數字圖像處理視頻教程(兩部)
{中科院版36講視頻教程 + 電子科大版70講視頻教程(岡薩雷斯 第二版)}
? ? 橙:halcon軟件、halcon軟件手把手教破解視頻教程
? ? 黃:數字圖像模式識別demo(C++編寫,在公司也是用C++哦)
? ? 綠:halcon軟件視頻教程、halcon軟件在vs2010中配置
? ? 青:面向對象C++視頻教程
? ? 藍:MFC C++視頻教程
? ? 紫:海量相關文檔資料
? ? http://item.taobao.com/item.htm?spm=a1z10.3.w4002-9510581636.11.VUYzOY&id=43025290175
******************************************************************************************************************************************
/*************************************************************************
* 函數名稱:
* ? GradSharp()
* 參數:
* ? BYTE ?bThre ? ? ? ?- 閾值
* 返回值:
* ? BOOL ? ? ? ? ? ?- 成功返回TRUE,否則返回FALSE。
* 說明:
* ? 該函數用來對圖像進行梯度銳化,設定梯度銳化的閾值為30
/************************************************************************/
void CImgEnhance::GradSharp(unsigned char Thre)
{
? ? ? ?unsigned char* ? ?pSrc; ? ? ? // 指向源圖像的指針
? ? unsigned char* ? ?pDst; ? ??
? ? unsigned char* ? ?pSrc1;
? ? unsigned char* ? ?pSrc2; ? ?
? ? LONG ? ?i,j; ? ? ? ? ? ? ? ?// 循環變量
? ? int ? ?bTemp;
? ? if(m_pImgDataOut != NULL)
? ? {
? ? ? ? delete []m_pImgDataOut;
? ? ? ? m_pImgDataOut = NULL;
? ? }
? ??
? ? if(m_nBitCount != 8)
? ? {
? ? ? ? AfxMessageBox("只能處理8位灰度圖像!");
? ? ? ? return ;
? ? }
? ? ? ?int lineByte = (m_imgWidth * m_nBitCount / 8 + 3) / 4 * 4;
? ? //創建要復制的圖像區域
? ? m_nBitCountOut = m_nBitCount;
? ? int lineByteOut = lineByte;
? ? if (!m_pImgDataOut)
? ? {
? ? ? ? m_pImgDataOut = new unsigned char[lineByteOut * m_imgHeight];
? ? }
? ??
? ? int pixelByte = m_nBitCountOut / 8; // 此處實際就是1,因為只處理8位圖像
? ? for(i = 0; i < m_imgHeight; i++)
? ? {
? ? ? ? for(j = 0; j < m_imgWidth * pixelByte; j++)
? ? ? ? ? ? *(m_pImgDataOut + i * lineByteOut + j) = *(m_pImgData + i * lineByteOut + j);
? ? }
? ??
? ? for(i = 0; i < m_imgHeight; i++) ? ? ? ?// 每行
? ? { ? ? ? ?
? ? ? ? for(j = 0; j < m_imgWidth; j++) ? ? ? ?// 每列
? ? ? ? {
? ? ? ? ? ? ? ? //指向新DIB第i行第j列的像素的指針
? ? ? ? ? ? pDst = m_pImgDataOut + lineByte * i + j;
? ? ? ? ? ??
? ? ? ? ? ? // 進行梯度運算
? ? ? ? ? ? // 指向DIB第i行,第j個象素的指針
? ? ? ? ? ? pSrc ?= (unsigned char*)m_pImgData + lineByte * i + j; ? ? ? ? ? ?
? ? ? ? ? ? // 指向DIB第i+1行,第j個象素的指針
? ? ? ? ? ? pSrc1 = (unsigned char*)m_pImgData + lineByte * (i+1) + j; ? ? ? ? ? ?
? ? ? ? ? ? // 指向DIB第i行,第j+1個象素的指針
? ? ? ? ? ? pSrc2 = (unsigned char*)m_pImgData + lineByte * i + j + 1;?
? ? ? ? ? ? bTemp = abs((*pSrc)-(*pSrc1)) + abs((*pSrc)-(*pSrc2));
? ? ? ? ? ??
? ? ? ? ? ? // 判斷是否小于閾值
? ? ? ? ? ? if ((bTemp+120) < 255)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // 判斷是否大于閾值,對于小于情況,灰度值不變。
? ? ? ? ? ? ? ? if (bTemp >= Thre)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? *pSrc = bTemp + 120;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? *pSrc = 255;
? ? ? ? ? ? }
? ? ? ? ? ? //生成新的DIB像素值
? ? ? ? ? ? *pDst = *pSrc;
? ? ? ? }
? ? }
? ??
}