一、原理概述
灰度变化平缓区域,灰度积分值保持近似不变;灰度沿边缘方向积分值保持不变,其他方向灰度积分值变化剧烈;角点除,任意方向剧烈变化。如下图所示:
二、数学推导
简言之,灰度积分值可以转化为一个二次型,通过矩阵运算可知,二次型可转化为如下数学公式:
进而,可转化为椭圆公式,如下所示:
原二次型就是一个斜置的椭圆,A与B分别影响了椭圆的长边和短边,根据几何性质,可以得知,椭圆的长短轴即可反映出椭圆面积,椭圆面积可反映灰度积分值,最终得到如下结论:
由于无法确定长短轴具体多少数值是大,多少数值是小,则使用一个角点相应函数,通过数学转化为与0的比较,如下所示:
当R约等于0,说明长轴与短轴都很小,灰度积分值很小,灰度变化平缓;
当R小于0,说明长轴短轴有一个很大,一个很小,灰度沿一个方向变化平缓,其他方向变化剧烈,为边缘区域;
当R大于0,说明长短轴数值都很大,灰度沿任意方向变化剧烈,为角点。
三、相关opencv函数
四、代码实例
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
baboon = cv.imread("E:/A_linpan/cv_code_tom/hello_world/data/baboon.jpg")
gray = cv.cvtColor(baboon, cv.COLOR_BGR2GRAY)
# harris 角点检测函数只能输入float32的数据,所以需要用np进行转化
gray = np.float32(gray)
dst = cv.cornerHarris(gray, 2, 3, 0.04)
cv.imshow('harris', dst)
cv.imshow('lena', baboon)
plt.show()
cv.waitKey()
cv.destroyAllWindows()
如下图所示,猩猩头像的焦点检测不是很明显
添加如下一行代码后,显示图像如下:红色的小点点就是检测出来的角点,0.02相当于一个阈值,大于这个阈值的点被认为是角点,后面的(0,0,255)是RGB三个通道颜色的设置,可以绘制不同的颜色点出来。
baboon[dst > 0.02 * dst.max()] = (0, 0, 255)
上面的例子显示效果不好,因为harris角点检测本身就有缺陷,我们换一个图片,代码不变,效果如下:
总结:
Harris角点检测算法对规则角点检测效果好,对不规则角点检测效果不好。
参考链接:
1. https://www.cnblogs.com/jsxyhelu/p/7439655.html