大锅饭 ST (
网学)贡献 Harris 算法原理: 角点:最直观的印象就是在水平、竖直两个方向上变化均较大的点,即 Ix、Iy 都较大 边缘:仅在水平、或者仅在竖直方向有较大的变化量,即 Ix 和 Iy 只有其一较大 平坦地区:在水平、竖直方向的变化量均较小,即 Ix、Iy 都较小 VC 编程实现: void CImagetestDoc::OnImgHarris() { //gausswidth:二维高斯窗口宽度 //sigma:高斯函数的方差 //size:非极大值抑制的邻域宽度 //thresh:最终确定角点所需的阈值 int i,j,m,n,size,thresh,gausswidth; double sigma; //输入四个参数 CInput2 input; input.m_gausswidth =5; input.m_sigma =0.8; input.m_size =5; input.m_thresh =5000; input.DoModal (); gausswidth=input.m_gausswidth ; sigma=input.m_sigma ; size=input.m_size ; thresh=input.m_thresh ; unsigned char *lpSrc;//一个指向源、目的像素的移动指针 LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB); int cxDIB = (int) ::DIBWidth(lpDIB); // 图像宽度 int cyDIB = (int) ::DIBHeight(lpDIB); // 图像高度 LPSTR lpDIBBits=::FindDIBBits (lpDIB); long lLineBytes = WIDTHBYTES(cxDIB * 8); // 计算灰度图像每行的字节数 //创建 I、Ix、Ix2、Iy、Iy2、Ixy、cim、mx、corner 数组 double *I=new double[cxDIB*cyDIB]; double *Ix=new double[cxDIB*cyDIB]; double *Ix2=new double[cxDIB*cyDIB]; double *Iy=new double[cxDIB*cyDIB]; double *Iy2=new double[cxDIB*cyDIB]; double *Ixy=new double[cxDIB*cyDIB]; double *cim=new double[cxDIB*cyDIB]; double *mx=new double[cxDIB*cyDIB]; corner=new bool[cxDIB*cyDIB]; memset(corner, 0, cxDIB*cyDIB*sizeof(bool)); //定义宏以方便访问元素
#define I(ROW,COL) I[cxDIB*(ROW)+(COL)] #define Ix(ROW,COL) Ix[cxDIB*(ROW)+(COL)] #define Ix2(ROW,COL) Ix2[cxDIB*(ROW)+(COL)] #define Iy(ROW,COL) Iy[cxDIB*(ROW)+(COL)] #define Iy2(ROW,COL) Iy2[cxDIB*(ROW)+(COL)] #define Ixy(ROW,COL) Ixy[cxDIB*(ROW)+(COL)] #define cim(ROW,COL) cim[cxDIB*(ROW)+(COL)] #define mx(ROW,COL) mx[cxDIB*(ROW)+(COL)] #define corner(ROW,COL) corner[cxDIB*(ROW)+(COL)] //将图像灰度值复制到 I 中,这步很重要!想想为什么? for(i = 0; i < cyDIB; i++) { for(j = 0; j < cxDIB; j++) { lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j; //将 256 级灰度图像转化为 double 型 I(i,j)=double(*lpSrc); } } //-------------------------------------------------------------------------// 第一步:利用差分算子对图像进行滤波 //-------------------------------------------------------------------------//定义水平方向差分算子并求 Ix double dx[9]={-1,0,1,-1,0,1,-1,0,1}; Ix=mbys(I,cxDIB,cyDIB,dx,3,3); //定义垂直方向差分算子并求 Iy double dy[9]={-1,-1,-1,0,0,0,1,1,1}; Iy=mbys(I,cxDIB,cyDIB,dy,3,3); //将中间结果 Ix 写入到文本文件以便后续分析 FILE *fp; fp=fopen("Ix.txt","w+"); for(i = 0; i < cyDIB; i++) { for(j = 0; j < cxDIB; j++) fprintf(fp,"%f ",Ix(i,j)); fprintf(fp,"\n"); } fp=fopen("Iy.txt","w+"); for(i = 0; i <
cyDIB; i++) { for(j = 0; j < cxDIB; j++) fprintf(fp,"%f ",Iy(i,j));
fprintf(fp,"\n"); } //计算 Ix2、Iy2、Ixy for(i = 0; i < cyDIB; i++) { for(j = 0; j < cxDIB; j++) { Ix2(i,j)=Ix(i,j)*Ix(i,j); Iy2(i,j)=Iy(i,j)*Iy(i,j); Ixy(i,j)=Ix(i,j)*Iy(i,j); } } //-------------------------------------------------------------------------// 第二步:对 Ix2/Iy2/Ixy 进行高斯平滑,以去除噪声 //-------------------------------------------------------------------------//本例中使用 5×5 的高