OpenCV-Python系列之Shi—tomasi拐角检测器
在上一个教程中,我们看到了Harris Corner Detector。1994年下半年,J。Shi和C. Tomasi在他们的论文《有益于跟踪的特征》中做了一个小修改,与Harris Harris Detector相比,显示了更好的结果。哈里斯角落探测器由下式给出:
取而代之的是,史托马西提出:
如果大于阈值,则将其视为拐角。如果像在Harris Corner Detector中那样在空间中绘制它,则会得到如下图像:
从图中可以看出,只有当两个值都大于最小值时,才将其视为拐角,也就是绿色区域。
OpenCV中的Shi-Tomasi 角点检测
OpenCV 提供了 Shi-Tomasi 的函数: cv2.goodFeaturesToTrack(),来获取图像中前 N 个最好的角点。函数原型如下:
goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance[, corners[, mask[, blockSize[, useHarrisDetector[, k]]]]])
其中的参数如下:
image:输入灰度图像,float32类型
maxCorners:返回角点的最大数目,值为0表表示没有设置最大值限制,返回所有检测到的角点。
qualityLevel:质量系数(小于1.0的正数,一般在0.01-0.1之间),表示可接受角点的最低质量水平。该系数乘以最好的角点分数(也就是上面较小的那个特征值),作为可接受的最小分数;例如,如果最好的角点分数值为1500且质量系数为0.01,那么所有质量分数小于15的角都将被忽略。
minDistance:角之间最小欧式距离,忽略小于此距离的点。
corners:输出角点坐标
mask:可选的感兴趣区域,指定想要检测角点的区域。
blockSize:默认为3,角点检测的邻域大小(窗口尺寸)
useHarrisDetector:用于指定角点检测的方法,如果是true则使用Harris角点检测,false则使用Shi Tomasi算法。默认为False。
k:默认为0.04,Harris角点检测时使用。
设定好这些参数,函数就能在图像上找到角点。所有低于质量水平的角点都会被忽略,然后再把合格角点按角点质量进行降序排列。
然后保留质量最高的一个角点,将它附近(最小距离之内)的角点都删掉(类似于非极大值抑制),按这样的方式最后得到 N 个最佳角点。
我们使用图像进行试验:
现在我们来看代码:
# coding=utf-8 import cv2 import numpy as np def shi_tomasi(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 第一个参数是输入图像 # 第二个参数是检测的角点数目 # 第三个参数是角点质量 # 第四个参数是角点间的最短距离 corners = cv2.goodFeaturesToTrack(gray, 300, 0.01, 10) # 将浮点型数据转成 int 型,否则无法绘制 corners = np.int0(corners) for i in corners: # 将每一项拆开,在重新拼成一个元组 x, y = i.ravel() # 在图上绘制角点,为了更好显示,设置半径为 2 cv2.circle(img, (x, y), 2, (0, 0, 255), 2) cv2.imshow("shi-tomasi", img) cv2.waitKey(0) img = cv2.imread("test_1.jpg") shi_tomasi(img)
来看结果:
我们可以看到角点被检测出来,不过这幅图像干扰项太多,不方便检验,大家可以自己进行试验,Shi—Tomasi 角点检测更多的被用于进行目标追踪,不过在图像识别领域,仍然有比它更为强大的目标追踪算法。
结合上个教程,我们总结,Harris 和 Shi-Tomasi 都是基于梯度计算的角点检测方法,Shi-Tomasi 的效果要好一些。基于梯度的检测方法有一些缺点: 计算复杂度高,图像中的噪声可以阻碍梯度计算,我们将在之后的教程中详述更好效果的检测算法。