您的位置:首页 > 编程语言 > Python开发

Harris算子总结

2017-05-22 16:03 381 查看
一. Harris基本原理

Harris算子是一种基于信号的点特征提取算子,它是对Moravec算子的改进。其基本思想是:在图像中设计一个局部

检测窗口,当该窗口沿各个方向做微小移动时,考察窗口的平均能量变化,当该能量变化超过设定的阈值时,就将窗

口的中心像素点提取为角点。

二. Harris计算过程

Harris算子数学方程,如下所示:



进行泰勒级数展开等,矩阵形成如下所示:





其中,



是图像在



方向的导数,可使用cv2.Sobel()计算结果。

根据一个用来判定窗口内是否包含角点的等式进行打分。如下所示:



其中,







是矩阵

的特征值。

根据这些特征值,可以判断一个区域是否是角点,边界或者是平面,如下所示:



1. 当



都小时,

也小,表示这个区域是一个平坦区域。

2. 当



时,

小于0,表示这个区域是边缘。

3. 当



都很大,并且

时,

也很大(



中的最小值都大于阈值),表示这个区域是角点。

Harris角点检测的结果是一个由角点分数构成的灰度图像,选取适当的阈值对结果图像进行二值化就检测到了图像中

的角点。

三. OpenCV中的Harris算子

函数原型:cv2.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]]) → dst。其中,img表示数据类型为float32的

输入图像。blockSize表示角点检测中要考虑的领域大小。ksize表示Sobel求导中使用的窗口大小。k表示Harris角点检

测方程中的自由参数。

import cv2
import numpy as np
filename = 'chessboard.jpg'
img = cv2.imread(filename)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv2.cornerHarris(gray,2,3,0.04)
# result is dilated for marking the corners, not important
dst = cv2.dilate(dst,None)
# threshold for an optimal value, it may vary depending on the image
img[dst>0.01*dst.max()]=[0,0,255]
cv2.imshow('dst',img)
if cv2.waitKey(0) & 0xff == 27:
cv2.destroyAllWindows()
结果输出,如下所示:



四. 亚像素级精确度的角点

OpenCV中的函数cv2.cornerSubPix()可以提供亚像素级别的角点检测。首先找到Harris角点,然后将角点的重心传给

该函数进行修正。Harris角点用红色像素标出,绿色像素是修正后的像素。如下所示:

import cv2
import numpy as np
filename = 'chessboard2.jpg'
img = cv2.imread(filename)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# find Harris corners
gray = np.float32(gray)
dst = cv2.cornerHarris(gray,2,3,0.04)
dst = cv2.dilate(dst,None)
ret, dst = cv2.threshold(dst,0.01*dst.max(),255,0)
dst = np.uint8(dst)
# find centroids
ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)
# define the criteria to stop and refine the corners
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001)
corners = cv2.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria)
# now draw them
res = np.hstack((centroids,corners))
res = np.int0(res)
img[res[:,1],res[:,0]]=[0,0,255]
img[res[:,3],res[:,2]] = [0,255,0]
cv2.imwrite('subpixel5.png',img)

为了方便查看对角点的部分进行了放大,如下所示:



1. cv2.connectedComponentsWithStats(OpenCV 3.X)
解析:函数原型int connectedComponentsWithStats(InputArray image, OutputArray labels, OutputArray stats, 
OutputArray centroids, int connectivity=8, int ltype=CV_32S)。
2. cv2.cornerSubPix
解析:函数原型void cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, 
TermCriteria criteria)。

参考文献:
[1] A Combined Corner and Edge Detector

[2] Harris Corner Detection:http://docs.opencv.org/3.0-

beta/doc/py_tutorials/py_feature2d/py_features_harris/py_features_harris.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息