一、原理
我们知道Harris角点检测的打分公式为: Harris角点检测
R = λ1
λ2 - k(
λ1 +
λ2)²
但是Shi-Tomasi使用的打分函数为:
R = min(λ1,
λ2)
如果打分超过阈值,我们就认为它是一个角点。我们可以把它绘制到
λ1~
λ2空间中,就会得到下图:
从这幅图中,我们可以看出来只有当
λ1和
λ2都大于最小值时,才被认为是角点(绿色区域)。
二、函数及代码
OpenCV提供了函数cv.goodFeaturesToTrack()。这个函数可以帮助我们使用Shi-Tomasi方法获取图像中的N个最好的角点。
goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance, corners=None, mask=None, blockSize=None, useHarrisDetector=None, k=None)
image:输入图像,一般是灰度图像。
maxCorners: 想要检测到的角点数目。
qualtyLevel: 角点的质量水平,0-1之间。
它代表了角点的最低质量,实际用于过滤角点的最小特征值是qualtyLevel与图像中最大特征值的乘积,所以 qualtyLevel的值不应超过1(常用的值为0.1或0.01)。低于这个值的所有角点都会被忽略。
minDistance: 两个角点之间的最短欧式距离。
mask: 是一幅像素值为布尔类型的像素,用于指定输入图像中蚕吐角点计算的像素点。
blockSize:计算导数的自相关矩阵时指定点的领域,默认为3,采用小窗口计算的结果比单点(也就是blockSize为1)计算的效 果要好。
useHarrisDetector: 默认值为0,若非0,则函数使用Harris的角点定义
K: 当
useHarrisDetector非0,则K为用于设置hessian自相关矩阵即对hessian行列式的相对权值的权值系数。
根据这些信息,函数就能在图像上找到角点。所有低于质量水平的角点都会被忽略。然后再把合格角点按角点质量进行降序排列。函数会采用角点质量最高的那个角点,然后将它附近(最小距离之内)的角点都删掉。按照这样的方式最后返回N个最佳角点。
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('img/blox.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
corners = cv.goodFeaturesToTrack(gray, 40, 0.01, 10)
'''
goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance, corners=None, mask=None, blockSize=None, useHarrisDetector=None, k=None)
imgae : 灰度图像
maxCorners: 你想要检测到的角点的数目
qualityLevel: 角点的质量水平,取值范围【0-1】,他代表了角点的最低质量,低于这个数的所有角点都会被忽略
minDistance: 两个角点之间的最短欧氏距离
'''
#int0 直接把小数后面抛弃取整,并不是四舍五入
corners = np.int0(corners)
print(len(corners))
for i in corners:
x, y = i.ravel()
cv.circle(img, (x, y), 3, 255, -1)
cv.namedWindow('img',cv.WINDOW_AUTOSIZE)
cv.imshow('img',img)
cv.waitKey(0)
cv.destroyAllWindows()
可以看出,比Harris角点检测的效果好了很多