Visual C++实现数字图像增强处理(下)

2.图像平滑

  图像平滑主要是为了消除噪声。噪声并不限于人眼所能看的见的失真和变形,有些噪声只有在进行图像处理时才可以发现。图像的常见噪声主要有加性噪声、乘性噪声和量化噪声等。图像中的噪声往往和信号交织在一起,尤其是乘性噪声,如果平滑不当,就会使图像本身的细节如边界轮廓、线条等变的模糊不清,如何既平滑掉噪声有尽量保持图像细节,是图像平滑主要研究的任务。

  一般来说,图像的能量主要集中在其低频部分,噪声所在的频段主要在高频段,同时系统中所要提取的汽车边缘信息也主要集中在其高频部分,因此,如何去掉高频干扰又同时保持边缘信息,是我们研究的内容。为了去除噪声,有必要对图像进行平滑,可以采用低通滤波的方法去除高频干扰。图像平滑包括空域法和频域法两大类,在空域法中,图像平滑的常用方法是采用均值滤波或中值滤波,对于均值滤波,它是用一个有奇数点的滑动窗口在图像上滑动,将窗口中心点对应的图像像素点的灰度值用窗口内的各个点的灰度值的平均值代替,如果滑动窗口规定了在取均值过程中窗口各个像素点所占的权重,也就是各个像素点的系数,这时候就称为加权均值滤波;对于中值滤波,对应的像素点的灰度值用窗口内的中间值代替。实现均值或中值滤波时,为了简便编程工作,可以定义一个n*n的模板数组。另外,读者需要注意一点,在用窗口扫描图像过程中,对于图像的四个边缘的像素点,可以不处理;也可以用灰度值为"0"的像素点扩展图像的边缘。下面给出了采用加权均值滤波的图像平滑函数代码和效果图:

void CDibView::OnImagePh()
{
 CClientDC pDC(this);
 HDC hDC=pDC.GetSafeHdc();//获取当前设备上下文的句柄;
 SetStretchBltMode(hDC,COLORONCOLOR);
 HANDLE data1handle;
 LPBITMAPINFOHEADER lpBi;
 CDibDoc *pDoc=GetDocument();
 HDIB hdib;
 unsigned char *hData;
 unsigned char *data;
 hdib=pDoc->GetHDIB();
 BeginWaitCursor();
 lpBi=(LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)hdib);
 hData=(unsigned char*)FindDIBBits((LPSTR)lpBi);
 pDoc->SetModifiedFlag(TRUE);
 data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight);
 data=(unsigned char*)GlobalLock((HGLOBAL)data1handle);
 AfxGetApp()->BeginWaitCursor();
 int i,j,s,t,ms=1;
 int sum=0,sumw=0;
 int mask[3][3]=,,};//定义的3x3加权平滑模板;
 for(i=0; ibiHeight; i++)
 for(j=0; jbiWidth; j++)
 {
  sumw=0; sum=0;
  for(s=(-ms); s<=ms; s++)
  for(t=(-ms); t<=ms; t++)     if(((i+s)>=0)&&((j+t)>=0)&&((i+s)biHeight)&&((j+t)biWidth))
 {
  sumw += mask[1+s][1+t];   
  sum+=*(hData+(i+s)*WIDTHBYTES(lpBi->biWidth*8)+(j+t))*mask[1+s][1+t];
  }
  if(sumw==0) sumw=1;
   sum/=sumw;
  if(sum>255)sum=255;
  if(sum<0)sum=0;
  *(data+i*WIDTHBYTES(lpBi->biWidth*8)+j)=sum;
 }
 for( j=0; jbiHeight; j++)
 for(i=0;ibiWidth;i++)  *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)=*(data+i*WIDTHBYTES(lpBi->biWidth*8)+j);
  StretchDIBits (hDC,0,0,lpBi->biWidth,lpBi->biHeight,0,0,
         lpBi->biWidth,lpBi->biHeight,
         hData,(LPBITMAPINFO)lpBi,
         DIB_RGB_COLORS,
         SRCCOPY);//显示图像;
}

Visual C++实现数字图像增强处理(下)(图一)

(a)LENA原图
Visual C++实现数字图像增强处理(下)(图二)

(b)平滑后的效果图

                     图三

  中值或均值平滑有时处理图像的效果并不是很好,它虽然去除了一定的噪声,但同时使图像中的边缘变的模糊,这主要和所选取的窗口大小有关,为此下面介绍了一种既能保持边缘清晰又能消除噪声的方法,其算法如图四所示:
Visual C++实现数字图像增强处理(下)(图三)

(a)
Visual C++实现数字图像增强处理(下)(图四)

(b)
Visual C++实现数字图像增强处理(下)(图五)

(c)

                 图 四 图像平滑模板

  上图的含义是在图像中取5*5的区域,包含点(i,j)的五边形和六边形各四个,3*3的区域一个,计算这九个区域的标准差和灰度的平均值,取标准差最小区域的灰度平均值作为点(i,j)的灰度。由于该算法的实现代码和上述代码大同小异,所以代码部分就不再赘述。

 3.图像锐化

  图像平滑往往使图像中的边界、轮廓变的模糊,为了减少这类不利效果的影响,这就需要利用图像鋭化技术,使图像的边缘变的清晰。图像銳化处理的目的是为了使图像的边缘、轮廓线以及图像的细节变的清晰,经过平滑的图像变得模糊的根本原因是因为图像受到了平均或积分运算,因此可以对其进行逆运算(如微分运算)就可以使图像变的清晰。从频率域来考虑,图像模糊的实质是因为其高频分量被衰减,因此可以用高通滤波器来使图像清晰。

  为了要把图像中间任何方向伸展的的边缘和轮廓线变得清晰,我们希望对图像的某种运算是各向同性的。可以证明偏导平方和的运算是各向同性的,既:

Visual C++实现数字图像增强处理(下)(图六)

  式中( Visual C++实现数字图像增强处理(下)(图七))是图像旋转前的坐标,(Visual C++实现数字图像增强处理(下)(图八) )是图像旋转后的坐标。梯度运算就是在这个式子的基础上开方得到的。图像(x,y)点的梯度值:
Visual C++实现数字图像增强处理(下)(图九)

  为了突出物体的边缘,常常采用梯度值的改进算法,将图像各个点的梯度值与某一阈值作比较,如果大于阈值,该像素点的灰度用梯度值表示,否则用一个固定的灰度值表示。

  我们在对图像增强的过程中,采用的是一种简单的高频滤波增强方法:

Visual C++实现数字图像增强处理(下)(图十)

  式中f,g分别为锐化前后的图像, Visual C++实现数字图像增强处理(下)(图十)是与扩散效应有关的系数。 Visual C++实现数字图像增强处理(下)(图十二)表示对图像f进行二次微分的拉普拉斯算子。这表明不模糊的图像可以由模糊的图像减去乘上系数的模糊图像拉普拉斯算子来得到。 Visual C++实现数字图像增强处理(下)(图十三)可以用下面的模板H=,,}来近似。在具体实现时,上述模板H中的各个系数可以改变, Visual C++实现数字图像增强处理(下)(图十四)这个系数的选择也很重要,太大了会使图像的轮廓过冲,太小了则图像锐化不明显。实验表明, Visual C++实现数字图像增强处理(下)(图十四)选取2-8之间往往可以达到比较满意的效果。下面给出 Visual C++实现数字图像增强处理(下)(图十四)等于4的情况下的实现代码和效果图:

void CDibView::OnMenuitem32785()
{
CClientDC pDC(this);
HDC hDC=pDC.GetSafeHdc();//获取当前设备上下文的句柄;
SetStretchBltMode(hDC,COLORONCOLOR);
CDibDoc *pDoc=GetDocument();
HDIB hdib;
hdib=pDoc->GetHDIB();
BITMAPINFOHEADER *lpDIBHdr;//位图信息头结构指针;
BYTE *lpDIBBits;//指向位图像素灰度值的指针;
lpDIBHdr=( BITMAPINFOHEADER *)GlobalLock(hdib);//得到图像的位图头信息 lpDIBBits=(BYTE*)lpDIBHdr+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);//获取图像像素值
BYTE* pData1;
static int a[3][3]=,,};//拉普拉斯算子模板;
int m,n,i,j,sum;
int Width=lpDIBHdr->biWidth;
int Height=lpDIBHdr->biHeight;
pData1=(BYTE*)new char[WIDTHBYTES(Width*8)*Height];
file://进行拉普拉斯滤波运算;
for(i=1;i for(j=1;j {
sum=0;
for(m=-1;m<2;m++)
for(n=-1;n<2;n++) sum+=*(lpDIBBits+WIDTHBYTES(Width*8)*(i+m)+j+n)*a[1+m][1+n];
if(sum<0) sum=0;
if(sum>255) sum=255;
*(pData1+WIDTHBYTES(Width*8)*i+j)=sum;
}
file://原始图像pData减去拉普拉斯滤波处理后的图像pData1
for(i=0;i for(j=0;j { sum=(int)(*(lpDIBBits+WIDTHBYTES(Width*8)*i+j)-4*(*(pData1+WIDTHBYTES(Width*8)*i+j)));
if(sum<0) sum=0;
if(sum>255) sum=255;
*(lpDIBBits+WIDTHBYTES(Width*8)*i+j)=sum;
}
StretchDIBits (hDC,0,0,lpDIBHdr->biWidth,lpDIBHdr->biHeight,0,0,
lpDIBHdr->biWidth,lpDIBHdr->biHeight,
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,
DIB_RGB_COLORS,
SRCCOPY);
}

Visual C++实现数字图像增强处理(下)(图一)

(a)LENA原图
Visual C++实现数字图像增强处理(下)(图十五)
(b)拉普拉斯锐化图

                    图 五

  本文主要讲解了图像直方图的基本概念和图像点处理运算中的增强、平滑、锐化概念和实现算法,并给处理实现代码和处理效果图和广大读者朋友们交流,希望达到抛砖引玉的作用。

posted on 2008-09-10 19:22 wrh 阅读(781) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2010年10月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

统计

常用链接

留言簿(19)

随笔档案

文章档案

收藏夹

搜索

最新评论

阅读排行榜

评论排行榜