![Harris 角点检测和Shi-Tomasi 角点检测](http://p2.ttnews.xyz/loading.gif)
这篇文章是关于一些流行的(Harris & Shi-Tomasi)角点检测算法和如何在Python和OpenCV实现它们。但是,在此之前,我们需要知道什么是图像特征:
图像的特征是提供丰富图像内容信息的兴趣点。它们基本上由两部分组成:
- 兴趣点:对旋转、平移、强度和尺度变化不变的图像中的点。有不同的兴趣点,如角,边,斑点等。
- 特征描述符:这些描述了围绕向量中的兴趣点的图像patch。它们可以简单到原始像素值,也可以复杂到像梯度直方图(HoG)等。
因此角点检测基本上就是检测图像中的(一种)兴趣点。
角点检测:为图像位置,其中位置的轻微偏移将导致水平(X)和垂直(Y)轴的强度发生大的变化。
Harris 角点检测
Harris Corner Detector算法简单如下:
第1步、当在X和Y方向(即梯度)上移动时,它确定哪些窗口(小图像块)产生非常大的强度变化。
第2步、找到每个这样的窗口,计算得分R.
第3步、对此分数应用阈值后,将选择并标记重要角点。
数学概述
第1步 :我们如何确定产生大变化的窗口?
让窗口(中心)位于位置(x,y)。设这个位置的像素强度为I(x,y)。如果此窗口稍微移动到具有位移(u,v)的新位置,则该位置处的像素的强度将为I(x + u,y + v)。因此[I(x + u,y + v)-I(x,y)]将是窗口移位强度的差异。对于一个角点,这种差异将非常高。因此,我们通过相对于X和Y轴来区分它来最大化该项。设w(x,y)为窗口上的像素权重(矩形或高斯)然后,E(u,v)定义为:
![Harris 角点检测和Shi-Tomasi 角点检测](http://p2.ttnews.xyz/loading.gif)
加权和乘以窗口中所有像素的强度差
现在,通过上面的公式计算E(u,v)将非常非常慢。因此,我们使用泰勒级数展开(仅第一阶)
第2步:现在我们知道如何找到具有大变化的窗口,我们如何选择具有合适角落的窗口?矩阵的特征值可用于实现此目的。因此,我们计算与每个这样的窗口相关联的分数。
用于分类为平坦区域/边缘/角点的分数
步骤3:根据R的值,窗口被分类为由平面,边缘或角点组成。R的较大值表示角,负值表示边。此外,为了获得最佳角点,我们可以使用非最大抑制。
(注意:Harris Detector不是尺度不变的)
代码概述
Harris Corner检测在OpenCV中实现。我们来看下面的Python代码:
'''
Function : cv2.cornerHarris(image,blocksize,ksize,k)
Parameters are as follows :
1. image : the source image in which we wish to find the corners (grayscale)
2. blocksize : size of the neighborhood in which we compare the gradient
3. ksize : aperture parameter for the Sobel() Operator (used for finding Ix and Iy)
4. k : Harris detector free parameter (used in the calculation of R)
'''
def harris_corners(image):
#Converting the image to grayscale
gray_img = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
#Conversion to float is a prerequisite for the algorithm
gray_img = np.float32(gray_img)
# 3 is the size of the neighborhood considered, aperture parameter = 3
# k = 0.04 used to calculate the window score (R)
corners_img = cv2.cornerHarris(gray_img,3,3,0.04)
#Marking the corners in Green
image[corners_img>0.001*corners_img.max()] = [0,255,0]
return image
Shi-Tomasi角点探测器
除了计算得分(R)的方式之外,Shi-Tomasi几乎与Harris 角点检测类似。这样可以获得更好的结果。此外,在这种方法中,我们可以找到前N个角,这在我们不想检测每个角的情况下可能是有用的。
数学概述
在Shi-Tomasi,R按以下方式计算:
如果R大于阈值,则将其归类为拐角。
代码概述
'''
Function: cv2.goodFeaturesToTrack(image,maxCorners, qualityLevel, minDistance[, corners[, mask[, blockSize[, useHarrisDetector[, k]]]]])
image – Input 8-bit or floating-point 32-bit, single-channel image.
maxCorners – You can specify the maximum no. of corners to be detected. (Strongest ones are returned if detected more than max.)
qualityLevel – Minimum accepted quality of image corners.
minDistance – Minimum possible Euclidean distance between the returned corners.
corners – Output vector of detected corners.
mask – Optional region of interest.
blockSize – Size of an average block for computing a derivative covariation matrix over each pixel neighborhood.
useHarrisDetector – Set this to True if you want to use Harris Detector with this function.
k – Free parameter of the Harris detector.
'''
def shi_tomasi(image):
#Converting to grayscale
gray_img = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
#Specifying maximum number of corners as 1000
# 0.01 is the minimum quality level below which the corners are rejected
# 10 is the minimum euclidean distance between two corners
corners_img = cv2.goodFeaturesToTrack(gray_img,1000,0.01,10)
corners_img = np.int0(corners_img)
for corners in corners_img:
x,y = corners.ravel()
#Circling the corners in green
cv2.circle(image,(x,y),3,[0,255,0],-1)
return image
该代码可用于在图像,图像文件夹或现场网络摄像头中使用Harris和Shi-Tomasi检测方法检测角点。您还可以使用其他一些参数来获得不同的输出。
让我们看一下这些代码的实际应用。我们可以看到,Shi-Tomasi比Harris更好地检测角点:
左上:Harris,右上:Shi-Tomasi,左下:原文
结论
综上所述,Harris和Shi-Tomasi的角检测方法是一些非常酷和容易的算法,可以使用intensity gradients的简单概念来检测这些角。shii - tomasi是一个稍微好一点的版本,只是改变了分数公式。我们检测了几个应用的角点:图像对齐、图像拼接(还记得你的手机摄像头的全景图吗?)、对象识别、3D重建、运动跟踪等等。
閱讀更多 不靠譜的貓 的文章