求梯度时对于平方和运算及开方运算,可以用两个分量的绝对值之和表示,即:

Sobel梯度算子是先做成加权平均,再微分,然后求梯度,即:
△xf(x,y)= f(x-1,y+1) + 2f(x,y+1) + f(x+1,y+1)- f(x-1,y-1) - 2f(x,y-1) - f(x+1,y-1); △yf(x,y)= f(x-1,y-1) + 2f(x-1,y) + f(x-1,y+1)- f(x+1,y-1) - 2f(x+1,y) - f(x+1,y+1); G[f(x,y)]=△xf(x,y)+△yf(x,y);
上述各式中的像素之间的关系见图二 F(x-1,y-1) F(x,y-1) F(x+1,y-1) F(x-1,y) F(x,y) F(x+1,y) F(x-1,y+1) F(x,y+1) F(x+1,y+1) 图二 Sober算子中各个像素点的关系图
我在视图类中定义了响应菜单命令的边缘检测Sobel算子实现灰度图像边缘检测的函数(图像数据的获取可以参见我在天极网上发表的的相关文章):
void CDibView::OnMENUSobel() { CClientDC pDC(this); HDC hDC=pDC.GetSafeHdc();//获取当前设备上下文的句柄; SetStretchBltMode(hDC,COLORONCOLOR); HANDLE data1handle; LPDIBHDRTMAPINFOHEADER lpDIBHdr; CDibDoc *pDoc=GetDocument(); HDIB hdib; unsigned char *lpDIBBits; unsigned char *data; hdib=pDoc->m_hDIB;//得到图象数据; lpDIBHdr=(LPDIBHDRTMAPINFOHEADER)GlobalLock((HGLOBAL)hdib); lpDIBBits= lpDIBHdr +* (LPDWORD)lpDIBHdr + 256*sizeof(RGBQUAD); //得到指向位图像素值的指针; data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpDIBHdr->biWidth*8)*lpDIBHdr->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)*(lpDIBBits+(i+1)*WIDTHBYTES(lpDIBHdr->biWidth*8)+(j-1)) +2*(int)*(lpDIBBits+(i+1)*WIDTHBYTES(lpDIBHdr->biWidth*8)+(j)) +(int)(int)*(lpDIBBits+(i+1)*WIDTHBYTES(lpDIBHdr->biWidth*8)+(j+1)); buf1=buf1-(int)(int)*(lpDIBBits+(i-1)*WIDTHBYTES(lpDIBHdr->biWidth*8)+(j-1)) -2*(int)(int)*(lpDIBBits+(i-1)*WIDTHBYTES(lpDIBHdr->biWidth*8)+(j)) -(int)(int)*(lpDIBBits+(i-1)*WIDTHBYTES(lpDIBHdr->biWidth*8)+(j+1));
//以上是对图像进行水平(x)方向的加权微分
buf2=(int)(int)*(lpDIBBits+(i-1)*WIDTHBYTES(lpDIBHdr->biWidth*8)+(j+1)) +2*(int)(int)*(lpDIBBits+(i)*WIDTHBYTES(lpDIBHdr->biWidth*8)+(j+1)) +(int)(int)*(lpDIBBits+(i+1)*WIDTHBYTES(lpDIBHdr->biWidth*8)+(j+1)); buf2=buf2-(int)(int)*(lpDIBBits+(i-1)*WIDTHBYTES(lpDIBHdr->biWidth*8)+(j-1)) -2*(int)(int)*(lpDIBBits+(i)*WIDTHBYTES(lpDIBHdr->biWidth*8)+(j-1))
上一篇:用Win32 API枚举应用程序窗口和进程
下一篇:C语言嵌入式系统编程修炼之内存操作
|