前言:特征点检测广泛应用到目标匹配、目标跟踪、三维重建等应用中,在进行目标建模时会对图像进行目标特征的提取,常用的有颜色、角点、特征点、轮廓、纹理等特征。现在开始讲解常用的特征点检测,其中Harris角点检测是特征点检测的基础,提出了应用邻近像素点灰度差值概念,从而进行判断是否为角点、边缘、平滑区域。Harris角点检测原理是利用移动的窗口在图像中计算灰度变化值,其中关键流程包括转化为灰度图像、计算差分图像、高斯平滑、计算局部极值、确认角点。
一、算法思想
角点原理来源于人对角点的感性判断,即图像在各个方向灰度有明显变化。算法的核心是利用局部窗口在图像上进行移动通过灰度的变化来判断局部图像是属于边界、角点还是“平面”。如下图:绿色框代表我们的移动窗口,第一种情况:窗口内图像的灰度没有发生变化,那么窗口内就不存在角点;第二种情况:窗口在某一个方向移动时,窗口内图像的灰度发生了较大的变化,而在另一些方向上没有发生变化,那么,窗口内的图像可能就是一条直线的线段,第三种情况:随着窗口的移动变化窗口内图像的灰度变化迅速,我们就认为存在角点。
二、数学模型
根据算法思想,构建数学模型,计算移动窗口的的灰度差值。对于图像,在点处平移后的自相似性:
是以点(x,y)为中心的窗口,既可以是常数,也可以是高斯加权函数。
为了减小计算量,利用泰勒级数进行简化公式:
表示的偏导数。
近似可得(公式忘加权重项):
其中M:
化简可得:
二次项函数本质上是一个椭圆,椭圆方程为:
对于矩阵可以进行对称矩阵的变化,假设利用两个特征值进行替代,其几何含义类似下图中的表达。在几何模型中通过判断两个特征值的大小,来判定像素的属性。
边界:一个特征值大,另一个特征值小,或,认为自相关函数在某一方向上大,在其他方向上小。
平面:两个特征值都小,且近似相等;自相关函数数值在各个方向上都小。
角点:两个特征值都大,且近似相等,自相关函数在所有方向上都增大。
在实际应用中为了能够应用更好的编程,定义了角点响应函数R,通过判定R大小来判断像素是否为角点。R取决于M的特征值,对于角点|R|很大,平坦的区域|R|很小,边缘的R为负值。R取决于M的特征值,对于角点|R|很大,平坦区域|R|很小,边缘的R为负值。
opencv-python代码:
#cv.cornerHarris()
#img:数据类型为float32的图像
#blockSize:角点检测中指定区域的大小
#ksize:Sobel求导中使用的窗口大小
#k:取值参数为[0.04,0.06]
import cv2
import numpy as np
img=cv2.imread(img.jpg)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
dst=cv2.cornerHarris(gray,2,3,0.04)
img[dst>0.01*dst.max()]=[0,0,225]
cv2.imshow('dst',img)
cv2.waitKey(0)
cv2.destroyAllWindow()