-(int)(int)*(lpDIBBits+(i+1)*WIDTHBYTES(lpDIBHdr->biWidth*8)+(j-1)); //以上是对图像进行垂直(y)方向加权微分
buf=abs(buf1)+abs(buf2);//求梯度
if(buf>255) buf=255; if(buf<0)buf=0; *(data+i*WIDTHBYTES(lpDIBHdr->biWidth*8)+j)=(BYTE)buf; } else *(data+i*lpDIBHdr->biWidth+j)=(BYTE)0; } for( j=0; jbiHeight; j++) for( i=0; ibiWidth; i++) *(lpDIBBits+i*WIDTHBYTES(lpDIBHdr->biWidth*8)+j)=*(data+i*WIDTHBYTES(lpDIBHdr->biWidth*8)+j); //处理后的数据写回原缓冲区 StretchDIBits (hDC,0,0,lpDIBHdr->biWidth,lpDIBHdr->biHeight,0,0, lpDIBHdr->biWidth,lpDIBHdr->biHeight, lpDIBBits,(LPDIBHDRTMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY); }
上述的数学分析读者可能看起来有些吃力,不过不要紧,对与边缘检测,大家只要知道有若干个检测模板(既边缘检测矩阵)可以直接实现检测功能就行了,现在将常用的检测实现公式列出如下(检测模版可以从相应的算法很容易的得到):
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]表示处理后(i,j)点的灰度值,f[i,j]表示处理前该点的灰度值。Photoshop教程 数据结构 五笔输入法专题 QQ病毒专题 共享上网专题 Google工具和服务专题
Kirsch算子实现起来相对来说稍微麻烦一些,它采用8个模板对图像上的每一个像素点进行卷积求导数,这8个模板代表8个方向,对图像上的8个特定边缘方向作出最大响应,运算中取最大值作为图像的边缘输出(上述算法中用到的8个模板在下面的实现代码中给出)。为了便于读者理解该算法的实现,这里我们给出实现该算法的函数代码,读者可以稍加改动应用到自己的项目中去。
BOOL Kirsch(BYTE *pData,int Width,int Height) {//定义实现Kirsch算法的8个模板; int i,j,s,t,k,max,sum[8]; static a[3][3]={{+5,+5,+5},{-3,0,-3},{-3,-3,-3}}; static a1[3][3]={{-3,+5,+5},{-3,0,+5},{-3,-3,-3}}; static a2[3][3]={{-3,-3,+5},{-3,0,+5},{-3,-3,+5}}; static a3[3][3]={{-3,-3,-3},{-3,0,+5},{-3,+5,+5}}; static a4[3][3]={{-3,-3,-3},{-3,0,-3},{+5,+5,+5}}; static a5[3][3]={{-3,-3,-3},{+5,0,-3},{+5,+5,-3}}; static a6[3][3]={{+5,-3,-3},{+5,0,-3},{+5,-3,-3}}; static a7[3][3]={{+5,+5,-3},{+5,0,-3},{-3,-3,-3}}; BYTE *pData1; if(pData==NULL) { AfxMessageBox("图像数据为空,请读取图像数据!"); return FALSE; } pData1=(BYTE*)new char[Width*Height]; if(pData1==NULL) { AfxMessageBox("图像缓冲数据区申请失败,请重新申请图像数据缓冲区!"); return FALSE ; } memcpy(pData1,pData, Width*8*Height); //kirsch算子处理,对每一像素点求取八个方向的导数;; for(i=1;i<Height-1;i++) for(j=1;j<Width-1;j++) { sum[1]=sum[2]=sum[3]=sum[4]=sum[5]=sum[6]=sum[7]=sum[8]=0; for(t=-1;t<2;t++) { for(s=-1;s<2;s++) { sum[1]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a[1+t][1+s]; sum[2]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a1[1+t][1+s]; sum[3]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a2[1+t][1+s]; sum[4]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a3[1+t][1+s]; sum[5]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a4[1+t][1+s]; sum[6]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a5[1+t][1+s]; sum[7]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a6[1+t][1+s]; sum[8]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a7[1+t][1+s];
上一篇:用Win32 API枚举应用程序窗口和进程
下一篇:C语言嵌入式系统编程修炼之内存操作
|