锐化滤波能减弱或消除图像中的低频率分量,但不影响高频率分量。因为低频分量对应图像中灰度值缓慢变化的区域,因而与图像的整体特性,如整体对比度和平均灰度值等有关。锐化滤波将这些分量滤去可使图像反差增加,边缘明显。在实际应用中,锐化滤波可用于增强被模糊的细节或者低对比度图像的目标边缘。
图像锐化的主要目的有两个:一是增强图像边缘,使模糊的图像变得更加清晰,颜色变得鲜明突出,图像的质量有所改善,产生更适合人眼观察和识别的图像;二是希望经过锐化处理后,目标物体的边缘鲜明,以便于提取目标的边缘、对图像进行分割、目标区域识别、区域形状提取等,为进一步的图像理解与分析奠定基础。图像锐化一般有两种方法:一是微分法,二是高通滤波法。高通滤波法的工作原理和低通滤波相似,这里不再赘述。下面主要介绍一下两种常用的微分锐化方法:梯度锐化和拉普拉斯锐化。但由于锐化使噪声受到比信号还要强的增强,所以要求锐化处理的图像有较高的信噪比;否则,锐化后图像的信噪比更低。
5.5.1 梯度锐化(1)
1.基本理论
邻域平均法或加权平均法可以平滑图像,反过来利用对应的微分方法可以锐化图像。微分运算是求信号的变化率,有加强高频率分量的作用,从而使图像轮廓清晰。
由于图像模糊的实质是图像受到平均或积分运算造成的,所以为了把图像中任何方向伸展的边缘和模糊的轮廓变得清晰,可以对图像进行逆运算如微分运算,从而使图像清晰化。
在图像处理中,一阶微分是通过梯度法来实现的。对于一幅图像用函数f(x,f)表示,定义 f(x,f)在点(x,f)处的梯度是一个矢量,定义为:
|
(5-5) |
梯度的方向在函数f(x,f)最大变化率的方向上,梯度的幅度G[f(x,f)] 可由下式算出:
|
(5-6) |
由上式可知,梯度的数值就是f(x,f)在其最大变化率方向上的单位距离所增加的量。对于数字图像而言,微分 和 可用差分来近似。式(5-6)按差分运算近似后的梯度表达式为:
|
(5-7) |
为便于编程和提高运算速度,在计算精度允许的情况下,可采用绝对差算法近似为:
|
(5-8) |
这种梯度法又称为水平垂直差分法,另一种梯度法是交叉地进行差分计算,称为罗伯特梯度法(Robert Gradient),表示为:
|
(5-9) |
同样,可以采用绝对差算法近似为:
|
(5-10) |
运用以上两种梯度近似算法,在图像的最后一行或最后一列无法计算像素的梯度时,一般用前一行或前一列的梯度值近似代替。
为了在不破坏图像背景的前提下更好地增强边缘,也可以对上述直接用梯度值代替灰度值的方法进行改进,即利用门限判断来改进梯度锐化方法。具体公式如下:
的计算方法可以采用式(5-8)或式(5-9)。对于图像而言,物体和物体之间、背景和背景之间的梯度变化很小,灰度变化较大的地方一般集中在图像的边缘上,也就是物体和背景交接的地方。当我们设定一个阈值时,大于阈值就认为该像素点处于图像的边缘,对结果加上常数C,以使边缘变亮;而对于 不大于阈值就认为该像素点是同类像素,即为物体或背景,常数C的选取可以根据具体的图像特点。这样,即增亮了物体的边界,同时又保留了图像背景原来的状态,比传统的梯度锐化方法具有更好的增强效果和适用性。
2.算法实现
CImgEnhance类中的成员函数GradSharp()实现梯度锐化操作,本算法程序是根据门限判断的梯度锐化方法编写的,阈值设为20,如果梯度加100大于255,则将其置为255。在对灰度图像进行梯度锐化时直接调用GradSharp()函数即可,以下是GradSharp()函数的代码实现。
/********************************** *************************************** * 函数名称: * GradSharp() * 参数: * BYTE threshold-阈值 * 返回值: * BOOL - 成功返回TRUE,否则返回FALSE * 说明:该函数用来对图像进行梯度锐化 * /************************************ ************************************/ void CImgEnhance::GradSharp(unsigned char threshold) { unsigned char *pSrc, *pDst, *pSrc1, *pSrc2; LONG i,j; //循环变量 int bTemp; if(m_pImgDataOut != NULL) { delete []m_pImgDataOut; m_pImgDataOut = NULL; } int lineByte = (m_imgWidth * m_nBitCount / 8 + 3) / 4 * 4;
if(m_nBitCount != 8) { AfxMessageBox("只能处理8位灰度图像!"); return ; } //创建要复制的图像区域 m_nBitCountOut = m_nBitCount; int lineByteOut = (m_imgWidth * m_nBitCountOut / 8 + 3) / 4 * 4; if (!m_pImgDataOut) { m_pImgDataOut = new unsigned char [lineByteOut * m_imgHeight]; }
int pixelByte = m_nBitCountOut / 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 * (m_imgHeight -1 - i) + j;
//进行梯度运算 //指向DIB第i行第j列像素的指针 pSrc = (unsigned char*)m_pImgData + lineByte * (m_imgHeight - 1 - i) + j; //指向DIB第i+1行第j列像素的指针 pSrc1 = (unsigned char*)m_pImgData + lineByte * (m_imgHeight - 2 - i) + j; //指向DIB第i行第j+1列像素的指针 pSrc2 = (unsigned char*)m_pImgData + lineByte * (m_imgHeight - 1 - i) + j + 1; bTemp = abs((*pSrc)-(*pSrc1)) + abs((*pSrc)-(*pSrc2));
//判断是否小于阈值 if ((bTemp+120) < 255) { //判断是否大于阈值,对于小于情况,灰度值不变 if (bTemp >= threshold) { *pSrc = (bTemp+120); } } else { *pSrc = 255; } //生成新的DIB像素值 *pDst = *pSrc; } } } |
3.函数调用
在视图类CDemoView中映射“梯度锐化”事件的处理函数OnGradesharp()。以下是CDemoView:: OnGradesharp()函数的代码实现。
void CDemoView::OnGradesharp() { CDemoDoc *pDoc=GetDocument(); ImgCenterDib *pDib=pDoc->GetPDib();
if(pDib->m_nBitCount!=8&{ ::MessageBox(0,"只处理灰度图像",MB_OK,0); return ; }
CImgEnhance imgnoise(pDib->GetDimensions(), pDib->m_nBitCount, pDib->m_lpColorTable, pDib->m_pImgData); unsigned char bThre=30; imgnoise.GradSharp(bThre); CMainFrame* pFrame = (CMainFrame *)(AfxGetApp()->m_pMainWnd); pFrame->SendMessage(WM_COMMAND, ID_FILE_NEW);
CDemoView* pView=(CDemoView*)pFrame->MDIGetActive()->GetActiveView(); CDemoDoc* pDocNew=pView->GetDocument(); ImgCenterDib *dibNew=pDocNew->GetPDib();
dibNew->ReplaceDib(imgnoise.GetDimensions(),imgnoise.m_nBitCountOut,imgnoise.m_lpColorTable, imgnoise.m_pImgDataOut); pDocNew->SetModifiedFlag(TRUE); pDocNew->UpdateAllViews(pView);
Invalidate(); } |