什么是角点?
简单来说就是局部窗口沿各方向移动,均发生明显变化的点;图像局部曲率突变的点;下面就是不同的角点
比较有名角点检测的就是:Harris角点检测、CSS角点检测
一、Harris角点检测
1、从图像局部小窗口观察图像特征;
2、窗口向任意方向的移动都导致图像灰度的明显变化;(角点定义)
窗口移动的三种情况判断:
(1)平坦区域:这种情况下任意方向移动无灰度值变化
(2)边缘:沿着边缘方向移动,无灰度值变化
(3)角点:沿着任意方向移动,发生明显灰度值变化
总的来说,角点在任意方向移动都会有明显变化;如果在图像区域移动过程中灰度没有变化,说明没有角点;还有就是如果在某一个方向移动,一个发生很大变化另一侧没有变化,那么说明这个区域是位于该对象的边缘区域;表达式如下:
对于图像I(x,y),在点(x,y)处平移(u,v)后的自相似性。其中w(x,y)是加权函数,它可以是常数,也可以是高斯加权函数。
1表示在窗口里,0表示外面 Gaussian高斯加权
为了寻找带角点的窗口,我们搜索像素灰度变化较大的窗口。于是我们期望最大化下面的式子;
然后使用泰勒公式展开:
展开式为:
转换为矩阵表达式可以写为:
表示为:
每个窗口中计算得到一个值。这个值决定了这个窗口中是否包含了角点:
其中:
- det(M) =
- trace(M) =
一个窗口,它的分数 大于一个特定值,这个窗口就可以被认为是”角点”
λ1和λ2是M的特征值。这些特征值决定了一个区域是角,边缘还是平面。
- 当|R|很小时,即λ1和λ2很小时,该区域时平面。
- 当 R < 0时,即λ1远远大于λ2或者λ2远远大于λ1时,该区域时直线。
-
当 R很大时,即λ1和λ2都很大且近似相等,该区域时角点。他们的关系可以表示为下图。
数学表达式如下:
算法:
对角点响应函数R进行阈值处理:R > threshold 然后提取 R 的局部最大值
Harris角点的性质:
- 该算法算子对亮度和对比度的变化不敏感。
- 算子具有旋转不变性。
- 算子不具有尺度不变性。
Python中Harris角点检测函数
cv2.cornerHarris(src, blockSize, ksize, k[, dst[,borderType]]) -> dst
其中,src - 输入为单通道8位或者浮点数图片,dst - 存储哈里斯角点检测响应的图像矩阵,矩阵大小跟src输入的一样,数据类型为浮点数, blockSize - 邻域大小,ksize - 孔径参数,k - 公式中的无限制参数,borderTyoe - 边界处理类型。
代码如下:
import cv2
import numpy as np
img = cv2.imread('test.jpg')
print('img.shape:',img.shape)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
dst = cv2.cornerHarris(gray,2,3,0.06)
print('dst.shape:',dst.shape)
img[dst>0.01*dst.max()] = [0,0,255]
cv2.imshow('dst',img)
cv2.waitKey()
cv2.destroyAllWindows()
仔细观看图中红点!
参考:https://www.jianshu.com/p/4049c00afaf4
https://wenku.baidu.com/view/f876c35d6c175f0e7dd13742.html?sxts=1569205882391