harris角点检测_(三十六)角点检测----Harris

b8b407f503f79b1ba48e02a37fe3414e.png

时间为友,记录点滴。

额,角点检测?

啥是角点?

先上定义:

  • 一阶导数(即灰度的梯度)的局部最大所对应的像素点;
  • 两条及两条以上边缘的交点;
  • 图像中梯度值和梯度方向的变化速率都很高的点;
  • 角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。

在懵逼之前,可以先看看这个图。

cc67d5ab74c3c6b425605c8c49abd7d3.png

在上面的倒五边形中,从上到下分别取1/2/3三部分,他们分别代表了:

  1. 边缘
  2. 团块
  3. 角点

这么分的依据是什么呢?从肉眼上看,非常容易辨别,当然我们也有过Canny检测这种专门的算法来识别边缘特征。那么怎么从微观或者说让计算机识别角点呢?

如何识别角点?

基本思想是使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化,那么我们可以认为该窗口中存在角点。

角点的特性下面的图更清晰:

de3f4bd8d2fafa56d8a8e02323e16cdc.png

而且当然不用我等工程狗去根据这种特征来设计算法,跟边缘检测一样,大神们早就做过了,单识别角点的算法,比较有名的就有:

  • Harri算法
  • Shi-Tomasi算法
  • 亚像素级角点检测

等好多种,我们这里先拿Harri开刀尝试剖析一下。

什么是Harri角点检测?

公式推导

我们参考上图,用窗口在一张图片上移动的梯度变化再把三个区域定义梳理一下:

  • 平坦区域:窗口移动在所有方向没有明显的梯度变化。
  • 边缘区域:窗口移动在某个方向有明显梯度变化。
  • 角度边缘:窗口移动在各个方向梯度值都有明显变化。

有了这个差异就好办了,我们设窗口平移

产生灰度变化
,可以找到公式

其中:

  • :窗口偏移量
  • :窗口内像素坐标
  • :窗口函数,内含权重信息,
    常用的有权重为1和呈二元高斯正太分布的权重,意在突出像素值变化明显的程度
  • 函数
    :像素密度函数,类比与像素值

当窗口处在平坦区域上滑动,可以想象的到,灰度不会发生变化,那么E(u,v) = 0;如果窗口处在比纹理比较丰富的区域上滑动,那么灰度变化会很大。算法最终思想就是计算灰度发生较大变化时所对应的位置,当然这个较大是指针任意方向上的滑动,并非单指某个方向。

公式变换

下面的核心就是找到

的最大值,对于给定的窗口函数
,我们就是要找
的最大值。

我们先回忆一下泰勒展开式:

所以,

那么

这里的M是矩阵

参考下图的说明:

b69c2fed3eccae5e7ba4eff57f2aea26.png

矩阵M的关键性

这个时候问题的关键转到了矩阵M上,它是怎么影响

的值得呢?

Harris角点检测是通过对窗口内的每个像素的x方向上的梯度与y方向上的梯度进行统计分析。这里以

为坐标轴,因此每个像素的梯度坐标可以表示成(
) (这里
是图像在x和y方向的导数)。针对平坦区域,边缘区域以及角点区域三种情形进行分析:

第一步:对X和Y方向分别求导

567bb4363cea3f193a5fee6ccc5d9879.png
求偏导

第二步:梯度绘制

80d8ec18a58def0595efe6c7f4e13631.png
梯度分布

第三步:圈中数据集

59d942319156285d746424aeac3c3eaa.png
以原点为中心,圈中所有数据集

可以认为:

:X轴方向的偏导的特征值;

:Y轴方向的偏导的特征值;

第四步:对

为坐标区分边缘、平坦、角点

d906d50826ba8a4ffa07769ca8290a06.png

结论:

  • 特征值都比较大时,即窗口中含有角点
  • 特征值一个较大,一个较小,窗口中含有边缘
  • 特征值都比较小,窗口处在平坦区域

OpenCV 引入新公式

OpenCV中会直接引入一个新的公式,它以上面的知识为基础,以经验函数为模型,做了R的函数:

不要问我为什么用这个公式,看图,别说话。。。

939f8a6a2ebda76bceb1f5e940b61f17.png

其中:

  • :矩阵行列式,
  • :矩阵的迹,
  • :Harri系数,一般取值为0.04~0.06

所以,Harris的基本步骤就是:

  • 求两个方向梯度,并计算出矩阵M
  • 对矩阵M计算特征值、行列式和迹
  • 根据特征值的关系并使用阈值确定图像特征

好了,长舒一口气。看懂都难,真不知道这些人当年是怎么想起来的。不过,老规矩,OpenCv早就给我们做好了API

CV_EXPORTS_W 
  • dst:Harri算法的输出矩阵(输出图像),CV_32FC1类型,与src有同样的尺寸
  • src:输入图像,单通道,8位或浮点型
  • blockSize:邻域大小
  • ksize:Sobel算子的孔径大小
  • k:Harri算法系数,即第二种表达式中的

下面就让我们试试这个算法的效果吧。。。

C++

注意点:

1. cornerHarris转化出来的Dst是CV_32FC1类型,最好经过归一化和ABS处理。
#include 

运行结果:

1c944da6dd46f9472075ad4965db31df.png
Threshold为180

Python:

注意:

1. np.zeros(imgHarris.shape, dtype=np.float32)定义
#!/usr/bin/env python

64d768e5316eaca46186fda95b3dbc93.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值