Harris角点检测算法优化

一、综述

用 Harris 算法进行检测,有三点不足:(1 )该算法不具有尺度不变性;(2 )该算法提取的角点是像素级的;(3 )该算法检测时间不是很令人满意。

基于以上认识,我主要针对第(3 )点对Harris 角点检测算法提出了改进。

二、改进 Harris 算法原理

在介绍我的方法之前,我先提出如下概念:图像区域像素的相似度。我们知道, Harris 角点检测是基于图像像素灰度值变化梯度的, 灰度值图像的角点附近,是其像素灰度值变化非常大的区域,其梯度也非常大。换句话说,在非角点位置邻域里,各点的像素值变化不大,甚至几乎相等,其梯度相对也比较小。从这个角度着眼,我提出了图像区域像素的相似度的概念,它是指检测窗口中心点灰度值与其周围n 邻域内其他像素点灰度值的相似程度,这种相似程度是用其灰度值之差来描述的。如果邻域内点的灰度值与中心点Image (i,j) 的灰度值之差 的绝对值 在一个阈值t 范围 内,那我就认为这个点与中心点是相似的。与此同时,属于该 Image (i,j) 点的相似点计数器nlike(i,j) 也随之加一。在 Image (i,j) 点的n 邻域 全部被遍历一边之后,就能得到 在这个邻域范围内 与中心点相似的 点个数的统计值nlike(i,j) 。根据nlike(i,j) 的大小,就可以判断这个中心点是否可能为角点。

由于我选择3*3 的检测窗口,所以, 对于中心像素点 , 在下面的讨论中只考虑其8 邻域内像素点的相似度。 计算该范围的像素点与中心像素点的灰度值之差的绝对值 ( 记为 Δ )  , 如果该值小于等于设定的阈值 ( 记为 t)  , 则认为该像素点与目标像素点相似 。

nlike(i,j)=sum(R(i+x,j+y))

( -  1 ≤ x ≤ 1 , -  1 ≤ y ≤ 1 , 且 x ≠ 0 , y ≠ 0)   ,

其中 :

1 ,  Δ( i + x , j + y)  ≤ t

 R(i+x, j+y)=

0 ,  Δ( i + x , j + y)  >  t

从定义中可以看出 : 0 ≤ nlike ( i , j ) ≤ 8 。 现在讨论 nlike( i , j) 值的含义 。

(1)   nlike (i , j) = 8 , 表示当前中心像素点的 8 邻域范围内都是与之相似的像素点 , 所以该像素点邻域范围内的梯度不会很大 , 因此角点检测时 , 应该排除此类像素点,不将其作为角点的候选点 。

(2)   nlike (i , j) = 0 , 表示当前中心像素点的 8 邻域范围内没有与之相似的像素点 , 所以该像素点为孤立像素点或者是噪声点 , 因此角点检测时 , 也应该排除此类像素点 。

(3)   nlike (i , j) = 7 , 可以归结为以下的两者情况 , 其他情形都可以通过旋转来得到 ( 图中黑色区域仅表示与中心像素相似 , 而两个黑色区域像素可能是相似的 , 也可能不相似 ) 。 对于图 1(a) 中 , 可能的角点应该是中心像素点的正上方的那个像素点 , 1(b) 图中可能的角点应该是中心像素点右上方的那个像素点 , 故这种情况下 , 中心像素点不应该作为角点的候选点 。

图 1 ( a )

图1(b)

(4)   nlike (i , j) = 1 , 可以归结为图 2 中的两种情况 ( 图中白色区域仅表示与中心像素不相似 , 而两个白色区域像素可能是相似的 , 也可能不相似 ) , 在这两种情况下 , 中心像素点也不可能为角点 。

图 2 ( a )

图 2 ( b )

(5)  2 ≤ nlike ( i , j) ≤ 6 , 情况比较复杂 , 无法确认像素点准确的性质。我采取的方法是先将其列入候选角点之列,对其进行计算CRF 等后续操作。

三、改进 Harris 算法效率性能分析

作为对比,我用未加改进的 Harris 算法计算了图像中的每一个像素点( 离边界boundary 个像素之内的点除外,boundary 为程序中定义的一个整数,名同其意) 的 CRF 值。Harris 算法采用9*9 的矩形高斯窗口( 共 81 个像素)  , 方向导数采用 Prewitt 算子 , 则在计算每个像素的自相关矩阵M 过程中乘法次数为: (9*9+1 )*3=246 次,加法次数为: (9*9-1 )*3=240 次 ,因此,计算点(i,j )的CRF 就要花费(1 )乘法246+2=248 次,(2 )加法240+1=241 次,(3)行列式计算det(M) 一次,(4 )对角和计算trace(M) 一次。对于分辨率为 Height*Width 的图像, 不考虑边界的影响, 其算法时间复杂度为 248* (Height-boundary)*(Width-boundary) 次乘法 + 241* (Height-boundary)*(Width-boundary) 次加法+1* (Height-boundary)* (Width-boundary)+ det(M) 一次+ trace(M) 一次,由于一次乘法的时间要远多于一次加法 , 因此在实时性要求较高的场合 , Harris 算法就显得速度较慢了。

改进 Harris 算法主要是在计算 CRF 值之前对像素点做了一个初始选择 , 这一部分主要是加法运算 , 运算量为 8 *(Height-boundary)*(Width-boundary) 次 。由于不涉及乘法运算 , 虽然在此增加了计算量 , 但为后续的 焦点提取剔除了大量的非角点像素点 , 而不必计算每个像素点的 CRF 值 , 大大减少了乘法的计算次数 , 计算效率在分辨率高的图像中可以明显地体现出来。

对于我们所采集的图像 , 预处理后 , 剔除像素点比例占总像素点的 60 % 以上 ,乘法计算量一般都能降低一半。表 1 为改进前的传统 Harris 算法与改进 后的Harris 算法在对一组6 幅图像进行角点提取时,于核心部分(计算CRF 与确认角点)所耗费的平均计算时间的比较。从表中可以看出改进算法的时间约为原算法的 21.58 % , 在不使用其他技巧的情况下,大大缩短了计算时间 , 有利于在实时处理中的应用。

表 1  Harris 算法与改进 Harris 算法在核心部分

平均消耗消耗时间上的对比( 单位 : 秒)

图像名

Z1.jpg

Z2.jpg

Z3.jpg

Z4.jpg

Z5.jpg

Z6.jpg

改进前

7.466712

7.456286

7.655664

7.581580

7.501732

7.469117

改进后

1.270748

1.241037

1.698029

2.272551

2.025614

1.230464

四、其他

这样检测出来的角点,有可能会在真正的角点附近小的邻域里同时存在几个“ 伪角点” 。 我采用的解决方法是,对以该点为中心7*7 的邻域内进行搜索,看是否存在这样的伪角点;如果存在,则用算数平均的方法求出全部这些点的平均坐标 row_ave 和 column_ave (见程序137 和138行),并以此作为真正的角点坐标并将其用绿色的点标志出来。

但是,这样处理方法的一个缺点是,对于图像边缘上(程序会检测出比较多的“角点”)杂点比较多的地方,会由于“角点”的聚集而导致更多的角点出现。

与此同时,削弱了噪声的影响(噪声点的CRF 一般会比较大),会使图像CRFmax 值变小,这也是导致用这种方法产生更多角点的一个原因。

表2 给出了传统Harris 算法与改进 Harris 算法在结果性能(检测出的角点个数)方面的对比。表3 给出了传统Harris 算法与改进 Harris 算法在计算图像CRFmax 上的对比。

表 2 Harris 算法与改进 Harris 算法在结果性能方面的

对比(检测出的角点个数)(单位:个)

图像名

Z1.jpg

Z2.jpg

Z3.jpg

Z4.jpg

Z5.jpg

Z6.jpg

改进前

77

71

76

71

70

76

改进后

79

72

99

86

98

78

表3 改进前后CRFmax 对比(单位1 )

图像名

Z1.jpg

Z2.jpg

Z3.jpg

Z4.jpg

Z5.jpg

Z6.jpg

改进前

3.2947e+08

2.8773e+08

1.5712e+09

1.3835e+09

1.5645e+08

2.4432e+09

改进后

3.2947e+08

2.8773e+08

1.5598e+09

1.3389e+09

1.5645e+08

2.4432e+09

附:matlab源代码

%%%Prewitt Operator Corner Detection.m
%%%时间优化--相邻像素用取差的方法
%%
clear;
for nfigure=1:6
    
switch nfigure  %选择图片
    case  1 
        t='z1.jpg';
    case  2 
        t='z2.jpg';
    case  3 
        t='z3.jpg';
    case  4 
        t='z4.jpg';
    case  5 
        t='z5.jpg';
    case  6 
        t='z6.jpg';
end
% t1 = tic;                        %测算时间
FileInfo = imfinfo(t);             % 保存图像的所有信息
Image = imread(t);                 % 读取图像
% 转为灰度值图像(Intensity Image)
if(strcmp('truecolor',FileInfo.ColorType) == 1) %转为灰度值图像
Image = im2uint8(rgb2gray(Image));   
end

dx = [-1 0 1;-1 0 1;-1 0 1];  %dx:横向Prewitt差分模版
Ix2 = filter2(dx,Image).^2;   
Iy2 = filter2(dx',Image).^2;                                         
Ixy = filter2(dx,Image).*filter2(dx',Image);

%生成 9*9高斯窗口。窗口越大,探测到的角点越少。
h= fspecial('gaussian',9,2);     
A = filter2(h,Ix2);       % 用高斯窗口差分Ix2得到A 
B = filter2(h,Iy2);                                 
C = filter2(h,Ixy);                                  
nrow = size(Image,1);                            
ncol = size(Image,2);                             
Corner = zeros(nrow,ncol); %矩阵Corner用来保存候选角点位置,初值全零,值为1的点是角点
                           %真正的角点在137和138行由(row_ave,column_ave)得到
%参数t:点(i,j)八邻域的“相似度”参数,只有中心点与邻域其他八个点的像素值之差在
%(-t,+t)之间,才确认它们为相似点,相似点不在候选角点之列
t=20;
%我并没有全部检测图像每个点,而是除去了边界上boundary个像素,
%因为我们感兴趣的角点并不出现在边界上
boundary=8;
for i=boundary:nrow-boundary+1 
    for j=boundary:ncol-boundary+1
        nlike=0; %相似点个数
        if Image(i-1,j-1)>Image(i,j)-t && Image(i-1,j-1)<Image(i,j)+t 
            nlike=nlike+1;
        end
        if Image(i-1,j)>Image(i,j)-t && Image(i-1,j)<Image(i,j)+t  
            nlike=nlike+1;
        end
        if Image(i-1,j+1)>Image(i,j)-t && Image(i-1,j+1)<Image(i,j)+t  
            nlike=nlike+1;
        end  
        if Image(i,j-1)>Image(i,j)-t && Image(i,j-1)<Image(i,j)+t  
            nlike=nlike+1;
        end
        if Image(i,j+1)>Image(i,j)-t && Image(i,j+1)<Image(i,j)+t  
            nlike=nlike+1;
        end
        if Image(i+1,j-1)>Image(i,j)-t && Image(i+1,j-1)<Image(i,j)+t  
            nlike=nlike+1;
        end
        if Image(i+1,j)>Image(i,j)-t && Image(i+1,j)<Image(i,j)+t  
            nlike=nlike+1;
        end
        if Image(i+1,j+1)>Image(i,j)-t && Image(i+1,j+1)<Image(i,j)+t  
            nlike=nlike+1;
        end
        if nlike>=2 && nlike<=6
            Corner(i,j)=1;%如果周围有0,1,7,8个相似与中心的(i,j)
                          %那(i,j)就不是角点,所以,直接忽略
        end;
    end;
end;

CRF = zeros(nrow,ncol);    % CRF用来保存角点响应函数值,初值全零
CRFmax = 0;                % 图像中角点响应函数的最大值,作阈值之用 
t=0.05;   
% 计算CRF
%工程上常用CRF(i,j) =det(M)/trace(M)计算CRF,那么此时应该将下面第103行的
%比例系数t设置大一些,t=0.1对采集的这几幅图像来说是一个比较合理的经验值
for i = boundary:nrow-boundary+1 
for j = boundary:ncol-boundary+1
    if Corner(i,j)==1  %只关注候选点
        M = [A(i,j) C(i,j);
             C(i,j) B(i,j)];      
         CRF(i,j) = det(M)-t*(trace(M))^2;
        if CRF(i,j) > CRFmax 
            CRFmax = CRF(i,j);    
        end;            
    end
end;             
end;

count = 0;       % 用来记录角点的个数
t=0.01;         
% 下面通过一个3*3的窗口来判断当前位置是否为角点
for i = boundary:nrow-boundary+1 
for j = boundary:ncol-boundary+1
        if Corner(i,j)==1  %只关注候选点的八邻域
            if CRF(i,j) > t*CRFmax && CRF(i,j) >CRF(i-1,j-1) ......
               && CRF(i,j) > CRF(i-1,j) && CRF(i,j) > CRF(i-1,j+1) ......
               && CRF(i,j) > CRF(i,j-1) && CRF(i,j) > CRF(i,j+1) ......
               && CRF(i,j) > CRF(i+1,j-1) && CRF(i,j) > CRF(i+1,j)......
               && CRF(i,j) > CRF(i+1,j+1) 
            count=count+1;%这个是角点,count加1
            else % 如果当前位置(i,j)不是角点,则在Corner(i,j)中删除对该候选角点的记录
                Corner(i,j) = 0;     
            end;
        end; 
end; 
end; 
% disp('角点个数');
% disp(count)
figure,imshow(Image);      % display Intensity Image
hold on; 
% toc(t1)
for i=boundary:nrow-boundary+1 
for j=boundary:ncol-boundary+1
        column_ave=0;
        row_ave=0;
        k=0;
       if Corner(i,j)==1
            for x=i-3:i+3  %7*7邻域
                for y=j-3:j+3
                    if Corner(x,y)==1
% 用算数平均数作为角点坐标,如果改用几何平均数求点的平均坐标,对角点的提取意义不大
                        row_ave=row_ave+x;
                        column_ave=column_ave+y;
                        k=k+1;
                    end
                end
            end
        end
        if k>0 %周围不止一个角点           
             plot( column_ave/k,row_ave/k ,'r.');
        end
end; 
end;

end

Harris角点检测算法优化的更多相关文章

  1. OpenCV计算机视觉学习(13)——图像特征点检测(Harris角点检测,sift算法)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 前言 ...

  2. Harris角点检测算原理

    主要参考了:http://blog.csdn.net/yudingjun0611/article/details/7991601  Harris角点检测算子 本文将该文拷贝了过来,并做了一些数学方面的 ...

  3. Harris角点检测原理分析

    看到一篇从数学意义上讲解Harris角点检测很透彻的文章,转载自:http://blog.csdn.net/newthinker_wei/article/details/45603583 主要参考了: ...

  4. Win8 Metro(C#)数字图像处理--2.36角点检测算法

    原文:Win8 Metro(C#)数字图像处理--2.36角点检测算法  [函数名称] Harris角点检测函数    HarrisDetect(WriteableBitmap src, int  ...

  5. opencv-角点检测之Harris角点检测

    转自:https://blog.csdn.net/poem_qianmo/article/details/29356187 先看看程序运行截图:   一.引言:关于兴趣点(interest point ...

  6. harris角点检测的简要总结

    目录 1. 概述相关 2. 原理详解 1) 算法思想 2) 数学模型 3) 优化推导 3. 具体实现 1) 详细步骤 2) 最终实现 4. 参考文献 1. 概述相关 harris角点检测是一种特征提取 ...

  7. harris角点检测的学习

    Harris通过运用微分运算和自相关矩阵改进了Moravec角点检测算法.用微分算子重新定义灰度强度变化的公式,其灰度强度变化表示为: 式中的wu,v为高斯窗口在(u,v)处的系数.X,Y它们是像素点 ...

  8. Opencv学习笔记------Harris角点检测

    image算法测试iteratoralgorithmfeatures 原创文章,转载请注明出处:http://blog.csdn.net/crzy_sparrow/article/details/73 ...

  9. 第十一节、Harris角点检测原理(附源码)

    OpenCV可以检测图像的主要特征,然后提取这些特征.使其成为图像描述符,这类似于人的眼睛和大脑.这些图像特征可作为图像搜索的数据库.此外,人们可以利用这些关键点将图像拼接起来,组成一个更大的图像,比 ...

随机推荐

  1. 关于CSS动画效果的图片展示

    animation:帧动画 animation-name:定义绑定Keyframes的动画名称 @keyframes XXX 定义动画,里面是动画具体内容 animation-duration:过渡动 ...

  2. 工具:使用jekyll生成静态网站

    在使用前端框架构建网页而不使用后端平台与数据库,即没有服务器的条件下读取文件夹其他文件,浏览器可能会阻止访问.对于这种静态构建可以使用简单的生成工具jekyll.它主要适用于将静态文件生成静态网站,在 ...

  3. Swift3.0语言教程使用Unicode范式标准化获取字符串

    Swift3.0语言教程使用Unicode范式标准化获取字符串 Swift3.0语言教程使用Unicode范式标准化获取字符串,在NSString中可以使用4个属性去使用Unicode范式标准化获取字 ...

  4. CSS3-给网页添加图片

    给网页添加图片: 1.background-attachment: scroll--------随文本一块滚动 ; background-attachment: fixed-----固定在一个位置上 ...

  5. stack

    stack介绍:先进后出 实现C++STL,栈有两个参数:template<class T,class Container = deque<T>> class stack: 参 ...

  6. jQuery跨域

    其实jQuery跨域很简单很简单,你记住格式就好,跨域的原理请参考 <jsonp跨域> jQuery跨域代码: $.ajax({ url:'https://suggest.taobao.c ...

  7. webservice 学习笔记

    1.webservice的概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的 ...

  8. 隐式调用 Intent 大全, 很全

    http://ming-fanglin.iteye.com/blog/1061312 //调用浏览器 Uri uri = Uri.parse(""); Intent it  = n ...

  9. Codeforces Round #243 (Div. 2) B. Sereja and Mirroring

    #include <iostream> #include <vector> #include <algorithm> using namespace std; in ...

  10. ACM: 敌兵布阵 解题报告 -线段树

    敌兵布阵 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description Li ...