OpenCV计算机视觉实战(Python)| 11、Harris角点检测
简介
本节为《OpenCV计算机视觉实战(Python)》版第11讲,Harris角点检测,的总结。
总结
Harris角点检测
1. 角点介绍
定义
角点定义: 不管是在竖直还是水平方向移动,像素值都发生剧烈的变化。 图中,E和F是角点,C和D是边界但不是角点。
相关的数学知识
计算机如何识别角点:
针对图像中的某个像素点I(x,y),移动后灰度级的变化情况(同时考虑x轴和y轴)为: W(x,y)是权重,以点(x,y)为中心的窗口,既可以是常数,也可以是高斯加权函数: 基于泰勒展开,对图像I(x,y)在平移(△x,△y)后进行一阶近似(对差值进行化简): 其中,Ix,Iy是I(x,y)的偏导数。
近似可得:
其中,M的表达式为(对角化矩阵): 化简可得: c(x,y)的表达式,可看成是一个椭圆,但存在包含△x△y的式子的偏移。 虽然不是一个标准的椭圆,但是可以通过一定的方法换成标准化椭圆。将M矩阵对角化后,消除了:2C△x△y这一项。
标准化椭圆的表达式: x2/a + y2/b = 1
标准化后的方程为: 二次项函数本质上就是一个椭圆函数,椭圆方程为: 椭圆方程中的长轴和短轴即为椭圆缓慢变化和快速变化的方向。
边界、平面和角点的数学定义
角点响应R值的计算: 判断方法:
-
R>0: 角点 R~=0: 平坦区域 R<0: 边界
2. 算法流程
- 拿到数据后,计算梯度Ix,Iy
- 构建M矩阵,求矩阵的特征值
- 比较特征值大小(或者计算角点响应函数):判断哪些点是角点
- 非极大值抑制(NMS),将真正角点保留下来,其他邻近的角点去除
3. 程序示例
OpenCV
cv2.cornerHarris()
-
img:数据类型为float32的输入图像(如果不是float32,用np.float32()转换即可) blockSize: 角点检测中指定区域的大小(角点检测中指定的窗口有多大) ksize: Sobel求导中使用的窗口大小(一般为3就可以) k: 取值参数为[0.04, 0.06] (一般用0.04就可以)
示例
import cv2 import numpy as np img = cv2.imread() print(img.shape:, img.shape) # (512,512,3) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Gray = np.float32(gray) dst = cv2.cornerHarris(gray, 2, 3, 0.04) print(dst.shape:, dst.shape) # (512,512):每个像素点的C值都计算出来了 #焦点判断 img[dst>0.01*dst.max()] = [0,0,255] # 如果大于dst的最大值的0.01,就认为是角点 cv2.imshow(dst, img) cv2.waitKey(0) cv2.destroyAllWindows()
结果:
