我在视图类中定义了响应菜单命令的边缘检测Sobel算子实现灰度图像边缘检测的函数:
void CDibView::OnMENUSobel() //灰度图像数据的获得参见天极网9.10日发表的拙作//VC数字图像处理一文 { HANDLE data1handle; LPBITMAPINFOHEADER lpBi; CDibDoc *pDoc=GetDocument(); HDIB hdib; unsigned char *hData; unsigned char *data;
hdib=pDoc->m_hDIB; BeginWaitCursor(); lpBi=(LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)hdib); hData= lpbi +* (LPDWORD)lpbi + 256*sizeof(RGBQUAD); //得到指向位图像素值的指针 pDoc->SetModifiedFlag(TRUE);//设修改标志为"TRUE" data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight); //申请存放处理后的像素值的缓冲区 data=(unsigned char*)GlobalLock((HGLOBAL)data1handle); AfxGetApp()->BeginWaitCursor(); int i,j,buf,buf1,buf2; for( j=0; jbiHeight; j++)//以下循环求(x,y)位置的灰度值 for( i=0; ibiWidth; i++) { if(((i-1)>=0)&&((i+1)biWidth)&&((j-1)>=0)&&((j+1)biHeight)) {//对于图像四周边界处的向素点不处理 buf1=(int)*(hData+(i+1)*WIDTHBYTES(lpBi->biWidth*8)+(j-1)) +2*(int)*(hData+(i+1)*WIDTHBYTES(lpBi->biWidth*8)+(j)) +(int)(int)*(hData+(i+1)*WIDTHBYTES(lpBi->biWidth*8)+(j+1)); buf1=buf1-(int)(int)*(hData+(i-1)*WIDTHBYTES(lpBi->biWidth*8)+(j-1)) -2*(int)(int)*(hData+(i-1)*WIDTHBYTES(lpBi->biWidth*8)+(j)) -(int)(int)*(hData+(i-1)*WIDTHBYTES(lpBi->biWidth*8)+(j+1)); //x方向加权微分 buf2=(int)(int)*(hData+(i-1)*WIDTHBYTES(lpBi->biWidth*8)+(j+1)) +2*(int)(int)*(hData+(i)*WIDTHBYTES(lpBi->biWidth*8)+(j+1)) +(int)(int)*(hData+(i+1)*WIDTHBYTES(lpBi->biWidth*8)+(j+1)); buf2=buf2-(int)(int)*(hData+(i-1)*WIDTHBYTES(lpBi->biWidth*8)+(j-1)) -2*(int)(int)*(hData+(i)*WIDTHBYTES(lpBi->biWidth*8)+(j-1)) -(int)(int)*(hData+(i+1)*WIDTHBYTES(lpBi->biWidth*8)+(j-1)); //y方向加权微分 buf=abs(buf1)+abs(buf2);//求梯度 if(buf>255) buf=255; if(buf<0){buf=0; *(data+i*WIDTHBYTES(lpBi->biWidth*8)+j)=(BYTE)buf; }
else *(data+i*lpBi->biWidth+j)=(BYTE)0; } for( j=0; jbiHeight; j++) for( i=0; ibiWidth; i++) *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)=*(data+i*WIDTHBYTES(lpBi->biWidth*8)+j); //处理后的数据写回原缓冲区 AfxGetApp()->EndWaitCursor(); GlobalUnlock((HGLOBAL)hdib); GlobalUnlock(data1handle); GlobalFree(date1handle); EndWaitCursor(); Invalidate(TRUE); } |
上述的数学分析读者可能看起来有些吃力,不过不要紧,对与边缘检测,大家只要知道有若干个检测模板(既边缘检测矩阵)可以直接实现检测功能就行了,现在将常用的检测实现公式列出如下:
Roberts算子:G[i,i]=|f[i,j]-f[i+1,j+1]|+|f[i+1,j]-f[i,j+1]|;
Sobe算子:G[i,i]=|f[i-1,j+1]+2f[i,j+1]+f[i+1,j+1]-f[i-1,j-1]-2f[i,j-1]-f[i+1,j-1]| +|f[i-1,j-1]+2f[i-1,j]+f[i-1,j+1]-f[i+1,j-1]-2f[i+1,j]-f[i+1,j+1]|;
拉普拉斯算子:G[I,j]=|f[i+1,j]+f[i-1,j]+f(i,j+1)+f[i,j-1]-4f[i,j]|;
其中G[i,j]表示处理后(i,j)点的灰度值,f[i,j]表示处理前该点的灰度值。
笔者开发的该图像处理程序在Windows2000环境下编译通过,下面图2给出了依据图像处理算法得到的图像二值化、高通滤波、Sobel边缘算子的处理结果,读者需要注意的是我在进行Sobel算子进行处理后,又对它进行了二值化处理,这才得到C图。关于如何实现二值化图像,我会后续撰文对相关知识进行介绍。 
说明:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。
2/2 首页 上一页 1 2 |