zoukankan      html  css  js  c++  java
  • Matlab图像处理学习笔记(五):Harris角点检测

    本文将从Harries角点检测的原理出发,讲述怎么用matlab一步步实现Harris角点检测算法。

    matlab可以用corner直接调用Harris角点检测算法,但为了学习如何提取特征点,本文用matlab将其实现,纯粹出于学习目的。由于harris角点特征点相对比较简单,容易实现,这位学习别的特征点检测打下基础。程序中出现的定常数均采用Matlab中corner实现该算法时的默认值。

    在实现的过程中,主要是参考了Chris Harris & Mike Stephens在1988年发表的那篇文章A COMBINED CORNER AND EDGE DETECTOR。

    本文一部分图像及公式来源于百度文库的一篇PPT:Harris角点检测,可自行检索获得。

    转载请注明出处:http://blog.csdn.net/u010278305

    本文涉及到的知识点如下:

    1、高斯卷积。

    2、Harris角点检测。

    程序设计流程如下:

    1、先将论文涉及该算法的主要部分给出截图:


    设计程序时,首先要完成论文的这一部分,计算出A、B、C。

    2、运用高斯窗对其进行滤波。

    高斯函数如下:

    用matlab生成一个高斯卷积核的方法:

    h=fspecial('gaussian',[5 1],1.5);
    w=h*h';


    3、遍历图像的每一点,求其M矩阵,并计算出R(之后用于判断是否是角点)。

    M矩阵为:


    R的计算方法为:

    4、判断是否是角点。

    如果R大于0且大于Q*RMax,则认为它是角点,RMax为R的最大值,Q为一个常数系数。

    5、对角点进行筛选。只有在8邻域内是最大值的店才会被认为是角点。

    下面给出源代码:

    %function:
    %       Harris角点检测
    %注意:
    %       matlab自带的corner函数即可实现harris角点检测。但考虑到harris角点的经典性,本程序将其实现,纯粹出于学习目的,了解特征点检测的方法。
    %       其中所有参数均与matlab默认保持一致
    %referrence:
    %      Chris Harris & Mike Stephens,A COMBINED CORNER AND EDGE DETECTOR
    %date:2015-1-11
    %author:chenyanan
    %转载请注明出处:http://blog.csdn.net/u010278305
    
    %清空变量,读取图像
    clear;close all
    src= imread('images/girl.jpg');
    
    gray=rgb2gray(src);  
    gray = im2double(gray);
    %缩放图像,减少运算时间
    gray = imresize(gray, 0.2);
    
    %计算X方向和Y方向的梯度及其平方
    X=imfilter(gray,[-1 0 1]);
    X2=X.^2;
    Y=imfilter(gray,[-1 0 1]');
    Y2=Y.^2;
    XY=X.*Y;
    
    %生成高斯卷积核,对X2、Y2、XY进行平滑
    h=fspecial('gaussian',[5 1],1.5);
    w=h*h';
    A=imfilter(X2,w);
    B=imfilter(Y2,w);
    C=imfilter(XY,w);
    
    %k一般取值0.04-0.06
    k=0.04;
    RMax=0;
    size=size(gray);
    height=size(1);
    width=size(2);
    R=zeros(height,width);
    for h=1:height
        for w=1:width
            %计算M矩阵
            M=[A(h,w) C(h,w);C(h,w) B(h,w)];
            %计算R用于判断是否是边缘
            R(h,w)=det(M) - k*(trace(M))^2;
            %获得R的最大值,之后用于确定判断角点的阈值
            if(R(h,w)>RMax)
                RMax=R(h,w);
            end
        end
    end
    
    %用Q*RMax作为阈值,判断一个点是不是角点
    Q=0.01;
    R_corner=(R>=(Q*RMax)).*R;
    
    %寻找3x3邻域内的最大值,只有一个交点在8邻域内是该邻域的最大点时,才认为该点是角点
    fun = @(x) max(x(:)); 
    R_localMax = nlfilter(R,[3 3],fun); 
    
    %寻找既满足角点阈值,又在其8邻域内是最大值点的点作为角点
    %注意:需要剔除边缘点
    [row,col]=find(R_localMax(2:height-1,2:width-1)==R_corner(2:height-1,2:width-1));
    
    %绘制提取到的角点
    figure('name','Result');
    subplot(1,2,1),imshow(gray),title('my-Harris'),
    hold on
    plot(col,row, 'b*'),
    hold off
    
    %用matlab自带的edge函数提取Harris角点,对比效果
    C = corner(gray);
    subplot(1,2,2),imshow(gray),title('matlab-conner'),
    hold on
    plot(C(:,1), C(:,2), 'r*');
    hold off


    下面给出本程序运行效果与matlab的corner运行效果的对比图:


    测试文件你可以仔细选取,或者在之前发布的博客中找到。

    转载请注明出处:http://blog.csdn.net/u010278305

  • 相关阅读:
    自定义注解 使用反射实现切面编程
    JPA学习(基于hibernate)
    MySql数据库优化可以从哪几个方面进行?
    mybatis注解开发-动态SQL
    mybatis注解开发
    mybatis动态sql
    Java8新特性之forEach遍历
    mybatis一对多映射
    CentOS7.* 查询开机启动项
    CentOS7 升级openssh到openssh-8.0p1版本
  • 原文地址:https://www.cnblogs.com/chenyn2014/p/4220199.html
Copyright © 2011-2022 走看看