Harris角点检测原理与opencv(python)实现 标签: harris特征点检测角点检测opencv 2017-06-14 19:01 65人阅读

在学习时主要参考了1.http://blog.csdn.net/xiaowei_cqu/article/details/7805206和opencv-python官方的关于harris的文档(http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_features_harris/py_features_harris.html#harris-corners)。


1.原理

对于角点的检测,harris依据一下直观判断:角点应该在窗口的各个方向都有变化,而边界会在某个方向基本不变,而平坦区域在各个方向变化都小。

因此我们要衡量在某个方向上的变化大小,定义

Harris角点检测原理与opencv(python)实现                                                                                                         标签:               harris特征点检测角点检测opencv                                            2017-06-14 19:01             65人阅读E(u,v) = sum_{x,y} w(x,y)~[I(x+u, y+v) - I(x,y)]^2

其中,w(x,y)是窗口函数;向量[u, v]表示某个方向,以及在该方向上的位移。由以上公式可知,E(u,v)表示在某个方向上图像灰度的变化。我们首先要研究在那个方向上,灰度变化最大(即令E(u,v)最大)。求解这个问题,我们通过泰勒展开公式(二元公式为:Harris角点检测原理与opencv(python)实现                                                                                                         标签:               harris特征点检测角点检测opencv                                            2017-06-14 19:01             65人阅读)可以得到:

Harris角点检测原理与opencv(python)实现                                                                                                         标签:               harris特征点检测角点检测opencv                                            2017-06-14 19:01             65人阅读

记上式最后的结果为Harris角点检测原理与opencv(python)实现                                                                                                         标签:               harris特征点检测角点检测opencv                                            2017-06-14 19:01             65人阅读,则我们可以得到:

Harris角点检测原理与opencv(python)实现                                                                                                         标签:               harris特征点检测角点检测opencv                                            2017-06-14 19:01             65人阅读

注意这个推导过程在http://blog.csdn.net/xiaowei_cqu/article/details/7805206中有一步是错误的!

这时我们知道找两个特征值中较大的对应的特征方向就是变化较大的方向。


但是我们考虑的问题不是得到窗口沿[u,v]移动变化最大,而是要衡量这个窗口内各个方向变化是否大。这就需要用特征值来衡量。

直观上考虑:

Harris角点检测原理与opencv(python)实现                                                                                                         标签:               harris特征点检测角点检测opencv                                            2017-06-14 19:01             65人阅读都小 : 区域平坦;

Harris角点检测原理与opencv(python)实现                                                                                                         标签:               harris特征点检测角点检测opencv                                            2017-06-14 19:01             65人阅读 : 边界

Harris角点检测原理与opencv(python)实现                                                                                                         标签:               harris特征点检测角点检测opencv                                            2017-06-14 19:01             65人阅读且都大:角点


基于以上原理,我们定义

Harris角点检测原理与opencv(python)实现                                                                                                         标签:               harris特征点检测角点检测opencv                                            2017-06-14 19:01             65人阅读

这时,

R小,说明两个特征值都小,对应区域平坦;

R<0,说明Harris角点检测原理与opencv(python)实现                                                                                                         标签:               harris特征点检测角点检测opencv                                            2017-06-14 19:01             65人阅读,对应边界;

R大,说明Harris角点检测原理与opencv(python)实现                                                                                                         标签:               harris特征点检测角点检测opencv                                            2017-06-14 19:01             65人阅读且都大,对应角点。


所以可以用R>阈值作为条件判断是否是角点。


2.python代码


关键命令是:cv2.cornerHarris(src, blocksize, ksize, k [, dst [, borderType ]]) -> dst

参数如下:

ksize:Sobel的孔径参数(aperture parameter),也就是Sobel核的半径,如1、3、5、7

k:R公式中的k,默认取0.04

blocksize:窗口大小,示例中取2


【python代码如下】


import cv2
import numpy as np

#读入图像并转化为float类型,用于传递给harris函数
filename = 'Dick.jpg'

img = cv2.imread(filename)

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

gray_img = np.float32(gray_img)

#对图像执行harris
Harris_detector = cv2.cornerHarris(gray_img, 2, 3, 0.04)

#腐蚀harris结果
dst = cv2.dilate(Harris_detector, None)

# 设置阈值
thres = 0.01*dst.max()

img[dst > thres] = [255,0,0]

cv2.imshow('show', img)

cv2.waitKey()