《opencv学习》Shi-Tomasi 角点检测

Shi-Tomasi 角点检测 和 Harris 角点检测的很多步骤都是一样的。
Harris 角点检测最后会得到一个相似度函数C,这个函数是一个对称矩阵M,可以将对称矩阵分解得到一个P的逆乘以特征值矩阵乘以P的形式(P是特征向量矩阵,正交的)。
对于一个角点来说, 随着位置的稍微移动,基本上相似度函数都会变化非常大。

如果固定函数E的值,那么后面的式子就是一个椭圆方程。而且M也是个定值,那么就是位置变化量(u, v)才是变化量,也就是说,在某个方向上,移动多少距离,C值就会变多少。移动相同位置,变化的越快的,说明像素差异变化越大,如果移动了很长的一点距离都没有怎么变化(C 值变化不大)那么说明像素值变化相差异不大,而我们希望得到水平和数值俩方向都变化很大的才是角点。

而这种变化程度,椭圆的变化程度,可以用特征值来表示。椭圆上某个方向越短,变化越剧烈,对应的这个特征值越大。椭圆上某个方向越长,变化越缓慢,对应的这个特征值越小。

在Harris算法中,通过下面的式子来判断是不是角点
《opencv学习》Shi-Tomasi 角点检测_第1张图片
《opencv学习》Shi-Tomasi 角点检测_第2张图片

而在Shi-Tomasi算法中,这点处理不一样,
是通过设置一个阈值λmin来判断是不是角点
如果λ1和λ2都小于λmin,则是平面点
如果只有一个小于,则是直线。
如果λ1和λ2都大于λmin,则是角点。
《opencv学习》Shi-Tomasi 角点检测_第3张图片
《opencv学习》Shi-Tomasi 角点检测_第4张图片
对比代码展示如下:

import cv2
import numpy as np

# 1.cv2.cornerHarris(img, blocksize, kszie, k)  # 找出图像中的角点
# 参数说明:
# img:是数据类型为float32的输入图像,表示输入的灰度图,
# blocksize:我们检测过程中需要一个窗口,这个就是窗口的大小,W(x,y)
# kszie:运用Sobel算子求解每个像素的梯度。有Ix和Iy方向的。
# k:是角点响应值运算中的α数值,一般推荐是[0.06, 0.06]
img = cv2.imread('images/build.jpeg')
img1 = img.copy()
gray_img = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray_img = np.float32(gray_img)
dst = cv2.cornerHarris(gray_img, blockSize=2, ksize=3, k=0.04)
img1[dst > 0.01 * dst.max()] = (0, 0, 255)


# goodFeaturesToTrack(image,
#                     maxCorners,
#                     qualityLevel,
#                     minDistance,
#                     corners,
#                     mask,
#                     blockSize,
#                     useHarrisDetector)
# 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角点检测时使用。
img2 = cv2.imread('images/build.jpeg')
gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
corners = cv2.goodFeaturesToTrack(gray, maxCorners=100, qualityLevel=0.01, minDistance=10)
corners = np.int0(corners)
for i in corners:
    x, y = i.ravel()
    cv2.circle(img2, (x, y), 2, (0, 0, 255), -1)

ret = np.hstack((img, img1, img2))
cv2.imshow("Harris and Shi-Tomasi", ret)
cv2.waitKey(0)  # 等待时间,单位是毫秒,0代表任意键终止
cv2.destroyAllWindows()

效果如下:

想要提高检测速度的话,可以考虑基于模板的方法:FAST角点检测算法。该算法原理比较简单,但实时性很强。可以学习我的前一篇:
https://blog.csdn.net/qq_29367075/article/details/123781298?spm=1001.2014.3001.5502

学习自:
自己的博客:https://blog.csdn.net/qq_29367075/article/details/123012724?spm=1001.2014.3001.5502

https://zhuanlan.zhihu.com/p/83064609

你可能感兴趣的:(OpenCV,图像处理,opencv,计算机视觉,Shi-Tomasi,角点检测)