利用Harris检测子进行角点特征检测

转载来自 http://blog.csdn.net/anymake_ren/article/details/21298807
    计算机视觉中常用的图像特征包括:点、边缘、直线、曲线等,其中,点特征属于局部特征,对遮挡有一定鲁棒性。图像中点特征数量多,提取速度快,并且容易辨识区分,因此在图像处理中占有重要地位。

    好的点特征如图1所示,在角点处,图像上的一个小窗口沿任何方向移动,窗口内的图像都有明显的灰度变化,因此角点是好的点特征。

                                               图1


那么,我们要怎样识别角点呢?由图2可以看出,角点具有类似图2中的第一列所展示的性质:

                                              图2


    假设窗口W发生位置偏移(u,v);比较偏移前后窗口中每一个像素点的灰度变化值;使用灰度误差平方和来构造一个误差函数E(u,v),其中的窗口函数是用来滤波的。

    H称为自相关矩阵, λmax和λmin是自相关矩阵的特征值。其中E(u,v)是一个二次型函数,二次型函数的本质就是一个椭圆,椭圆的扁率和尺寸是由H的特征λmax和λmin值λmax和λmin决定的,椭圆的方向由H的特征向量决定。图3-3表示的是点线面与椭圆的关系,其中(d)图中的椭圆跑哪去了,我也不知道,你问我我也还是不知道得意。因为图是从扫描版的PDF中截取的,本来就模糊。

   下面这幅图是王永明等在《图像局部不变性特征与描述》一书中阐述椭圆与点线面的关系用的。第一行是不同典型图像的灰度梯度分布图,第二行是对梯度分别的椭圆拟合。不过有一点没有明白,如果按照哈里斯的理论线性边缘时,R不应该为负值的吗?那王永明的这幅图中的R代表什么含义啊到底?为什么线性边缘时,R=0.3328?搞不懂啊搞不懂!!!大哭


    正如图3所示,只有当两者都比较大,并且大小相当时对应点才为角点,两者都非常小时为平坦区域;一大一小时为边界。

                                         图3


    在1988年,哈里斯在其论文《A combined corner and edge detector》里给出了更有效的角点响应函数

R为正值时,检测到的是角点;R为负时检测到的是边;R很小时检测到的是平坦区域,由此也就有了更便于计算的数学公式。哈老先生对此做的图如下:

下面是对Harris算法的Matlab实现,源码参考自http://blog.csdn.net/aflyeagle/article/details/5116799

个人对一些地方做了修改说明。


运行环境windows8.1+Matlab R2013b

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. %%%Prewitt Operator Corner Detection.m  
  2. %%%时间优化--相邻像素用取差的方法求Harris角点  
  3.  %%   
  4.  clear;  
  5.  Image = imread('884.jpg');                 % 读取图像  
  6.  Image = im2uint8(rgb2gray(Image));     
  7.     
  8.   
  9. dx = [-1 0 1;-1 0 1;-1 0 1];  %dx:横向Prewitt差分模版  
  10. Ix2 = filter2(dx,Image).^2;     
  11. Iy2 = filter2(dx',Image).^2;                                          
  12. Ixy = filter2(dx,Image).*filter2(dx',Image);  
  13.    
  14. %生成 9*9高斯窗口。窗口越大,探测到的角点越少。  
  15. h= fspecial('gaussian',9,2);  
  16. A = filter2(h,Ix2);       % 用高斯窗口差分Ix2得到A   
  17. B = filter2(h,Iy2);                                   
  18. C = filter2(h,Ixy);                                    
  19. nrow = size(Image,1);                              
  20. ncol = size(Image,2);                               
  21. Corner = zeros(nrow,ncol); %zeros用来产生一个全零矩阵,故矩阵Corner用来保存候选角点位置,初值全零,值为1的点是角点  
  22.   
  23.  %参数t:点(i,j)八邻域的“相似度”参数,只有中心点与邻域其他八个点的像素值之差在  
  24.  %(-t,+t)之间,才确认它们为相似点,相似点不在候选角点之列  
  25.  t=20;  
  26.    
  27.  %我并没有全部检测图像每个点,而是除去了边界上boundary个像素,也就是从第8行第8列开始遍历。  
  28.  %因为我们感兴趣的角点并不出现在边界上  
  29.  %个人觉得这一部分是的主要目的是找出可能是角点的点,缩小范围,加快运算速度。  
  30.  %具体思想是如果中心点(i,j)周围8个点中有7、8个点灰度值与之相似,那么该中心点应该处于平坦区域,不可能为角点,  
  31.  %如果中心点(i,j)周围只有1个点或者没有点与之相似,那么该中心点也不可能为角点。  
  32.  boundary=8;  
  33.  for i=boundary:nrow-boundary+1   
  34.     for j=boundary:ncol-boundary+1  
  35.          nlike=0; %相似点个数  
  36.          if Image(i-1,j-1)>Image(i,j)-t && Image(i-1,j-1)<Image(i,j)+t   
  37.             nlike=nlike+1;  
  38.          end  
  39.          if Image(i-1,j)>Image(i,j)-t && Image(i-1,j)<Image(i,j)+t    
  40.             nlike=nlike+1;  
  41.          end  
  42.          if Image(i-1,j+1)>Image(i,j)-t && Image(i-1,j+1)<Image(i,j)+t    
  43.             nlike=nlike+1;  
  44.          end    
  45.         if Image(i,j-1)>Image(i,j)-t && Image(i,j-1)<Image(i,j)+t    
  46.             nlike=nlike+1;  
  47.          end  
  48.          if Image(i,j+1)>Image(i,j)-t && Image(i,j+1)<Image(i,j)+t    
  49.             nlike=nlike+1;  
  50.          end  
  51.          if Image(i+1,j-1)>Image(i,j)-t && Image(i+1,j-1)<Image(i,j)+t    
  52.             nlike=nlike+1;  
  53.          end  
  54.          if Image(i+1,j)>Image(i,j)-t && Image(i+1,j)<Image(i,j)+t    
  55.             nlike=nlike+1;  
  56.          end  
  57.          if Image(i+1,j+1)>Image(i,j)-t && Image(i+1,j+1)<Image(i,j)+t    
  58.             nlike=nlike+1;  
  59.          end  
  60.          if nlike>=2 && nlike<=6  
  61.              Corner(i,j)=1;%如果周围有2~6个相似点,那(i,j)就是角点  
  62.          end;  
  63.      end;  
  64.  end;  
  65. CRF = zeros(nrow,ncol);    % CRF用来保存角点响应函数值,初值全零  
  66.  CRFmax = 0;                % 图像中角点响应函数的最大值,作阈值之用   
  67. k=0.05;     
  68. % 计算CRF  
  69.  %工程上常用CRF(i,j) =det(M)/trace(M)计算CRF,那么此时应该将下面第105行的  
  70.  %比例系数k设置大一些,k=0.1对采集的这几幅图像来说是一个比较合理的经验值  
  71.  for i = boundary:nrow-boundary+1  
  72.      for j = boundary:ncol-boundary+1  
  73.      if Corner(i,j)==1  %只关注候选点  
  74.          M = [A(i,j) C(i,j);  
  75.               C(i,j) B(i,j)];        
  76.          CRF(i,j) = det(M)-k*(trace(M))^2;  
  77.          if CRF(i,j) > CRFmax   
  78.             CRFmax = CRF(i,j);      
  79.         end;              
  80.     end  
  81.  end;               
  82. end;    
  83. %CRFmax  
  84.  count = 0;       % 用来记录角点的个数  
  85.  t=0.01;          
  86. % 下面通过一个3*3的窗口来判断当前位置是否为角点  
  87.  for i = boundary:nrow-boundary+1   
  88. for j = boundary:ncol-boundary+1  
  89.          if Corner(i,j)==1  %只关注候选点的八邻域  
  90.              if CRF(i,j) > t*CRFmax && CRF(i,j) >CRF(i-1,j-1) ......%?????为什么要CRF(i,j) > t*CRFmax啊?求大神告知  
  91.                 && CRF(i,j) > CRF(i-1,j) && CRF(i,j) > CRF(i-1,j+1) ......  
  92.                 && CRF(i,j) > CRF(i,j-1) && CRF(i,j) > CRF(i,j+1) ......  
  93.                 && CRF(i,j) > CRF(i+1,j-1) && CRF(i,j) > CRF(i+1,j)......  
  94.                 && CRF(i,j) > CRF(i+1,j+1)   
  95.             count=count+1;%这个是角点,count加1  
  96.              else % 如果当前位置(i,j)不是角点,则在Corner(i,j)中删除对该候选角点的记录  
  97.                  Corner(i,j) = 0;       
  98.             end;  
  99.          end;   
  100. end;   
  101. end;   
  102. % disp('角点个数');  
  103.  % disp(count)  
  104.  figure,imshow(Image);      % display Intensity Image  
  105.  hold on;   
  106. % toc(t1)  
  107.  for i=boundary:nrow-boundary+1   
  108. for j=boundary:ncol-boundary+1  
  109.          column_ave=0;  
  110.          row_ave=0;  
  111.          k=0;  
  112.         if Corner(i,j)==1  
  113.              for x=i-3:i+3  %7*7邻域  
  114.                  for y=j-3:j+3  
  115.                      if Corner(x,y)==1  
  116.  % 用算数平均数作为角点坐标,如果改用几何平均数求点的平均坐标,对角点的提取意义不大  
  117.                          row_ave=row_ave+x;  
  118.                          column_ave=column_ave+y;  
  119.                          k=k+1;  
  120.                      end  
  121.                  end  
  122.              end  
  123.          end  
  124.          if k>0 %周围不止一个角点             
  125.              plot( column_ave/k,row_ave/k ,'g.');  
  126.          end  
  127.  end;   
  128. end;   



采用国际会议中心的图片进行实验,效果如下:

原图:

标记效果图:

为了验证Harris的旋转不变性,将原图旋转后实验效果如下:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值