您好,欢迎来到年旅网。
搜索
您的当前位置:首页OpenCV-Python:Harris角点检测与Shi-Tomasi角点检测

OpenCV-Python:Harris角点检测与Shi-Tomasi角点检测

来源:年旅网
OpenCV-Python:Harris⾓点检测与Shi-Tomasi⾓点检测

⼀、Harris⾓点检测

原理:

⾓点特性:向任何⽅向移动变换都很⼤。

Chris_Harris 和 Mike_Stephens 早在 1988 年的⽂章《A CombinedCorner and Edge Detector》中就已经提出了焦点检测的⽅法,被称为Harris ⾓点检测。将窗⼝向各个⽅向移动(u,v)然后计算所有差异的总合:表达式如下:

⾓点检测中要使E(u,v)的值最⼤。这就是说必须使⽅程的第⼆项的取值最⼤。对上⾯的等式进⾏泰勒级数展开,然后再通过⼏步数学换算(参考其他标准教材),我们得到下⾯的等式:

其中

这⾥ Ix 和 Iy 是图像在 x 和 y ⽅向的导数(可以使⽤cv2.Sobel()计算得到)根据⼀个⽤来判定窗⼝内是否包含⾓点的等式进⾏打分

其中

λ1 和 λ 2 是矩阵M的特征值所以根据这些特征中我们可以判断⼀个区域是否是⼀个⾓点、边界或是平⾯当λ1 和 λ 2都⼩时,|R| 也⼩,这个区域就是⼀个平坦区域当 λ 1 ≫ λ 2 或者 λ 1 ≪ λ 2时,R⼩于0,这个区域是边缘

当 λ 1 和 λ 2 都很⼤,并且 λ 1 ~λ 2 中的时,R 也很⼤,(λ 1 和 λ 2 中最⼩值都⼤于阈值),说明这个区域是⾓点⽤下图来表⽰我们的结论:

所以Harris ⾓点检测的结果是⼀个由⾓点分数构成的灰度图像。选取适当的阈值对结果进⾏⼆值化,我们就检测到了图像中的⾓点。

OpenCV中的⾓点检测

使⽤ cv2.cornerHarris(),参数如下:

  img:数据类型为float32的输⼊图像(灰度图)  blockSize:⾓点检测中要考虑的领域⼤⼩  ksize:Sobel求导中使⽤的窗⼝⼤⼩

  k:Harris⾓点检测⽅程中的⾃由参数,取值参数为[0.04,0.06]

import cv2

import numpy as npimg = cv2.imread('blox.jpg')

# 1. Harris⾓点检测基于灰度图

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 2. Harris⾓点检测

dst = cv2.cornerHarris(gray, 2, 3, 0.04)# 腐蚀⼀下,便于标记dst = cv2.dilate(dst, None)

# ⾓点标记为红⾊

img[dst > 0.01 * dst.max()] = [0, 0, 255]cv2.imwrite('blox-RedPoint.png', img)cv2.imshow('dst', img)cv2.waitKey(0)

⼆、Shi-Tomasi⾓点检测 & 适合于跟踪的图像特征

Shi-Tomasi ⾓点检测是在Harris⾓点检测上进⾏了修改。我们知道Harris⾓点检测的打分公式为:

但 Shi-Tomasi 使⽤的打分函数为:

如果打分查过阈值,我们就认为它是⼀个⾓点,我们可以把它绘制到 λ 1 ~λ 2 空间中,就会得到下图:

从这幅图中,我们可以看出只有当λ 1 和 λ 2 都⼤于最⼩值时,才被认为是⾓点(绿⾊区域)

OpenCV使⽤cv2.goodFeatureToTrack()。这个函数可以帮我们使⽤Shi-Tomasi⽅法获取图像中的N个最好的⾓点。  image : 输⼊灰度图

  maxCorners:想要检测的⾓点数⽬

  qualityLevel:设置⾓点的最低质量,0 到 1之间。低于这个数的所有⾓点都会被忽略  minDistance:两个⾓点之间的最短欧式距离

根据这些信息,函数就能在图像上找到⾓点。所有低于质量⽔平的⾓点都会被忽略。然后再把合格⾓点按⾓点质量进⾏降序排列。函数会采⽤⾓点质量最⾼的那个⾓点(排序后的第⼀个),然后将它附近(最⼩距离之内)的⾓点都删掉。按着这样的⽅式最后返回 N 个最佳⾓点。

import numpy as npimport cv2

from matplotlib import pyplot as pltimg = cv2.imread('blox.jpg')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Shi-Tomasi⾓点检测

corners = cv2.goodFeaturesToTrack(gray, 20, 0.01, 10)corners = np.int0(corners) # 20 个⾓点坐标for i in corners:

# 压缩⾄⼀维:[[62, ]] -> [62, ] x, y = i.ravel()

cv2.circle(img, (x, y), 4, (0, 0, 255), -1)

cv2.imwrite('Shi-Tomasi-corner.jpg', img)cv2.imshow('dst', img)cv2.waitKey(0)

这个函数很适合在⽬标跟踪中使⽤

三、Harris和Shi-Tomasi的⽐较

import numpy as npimport cv2

from matplotlib import pyplot as plt

img = cv2.imread('blox.jpg')

imgShi, imgHarris = np.copy(img), np.copy(img)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 1. Shi-Tomasi⾓点检测

# 优点:速度相⽐Harris有所提升,可以直接得到⾓点坐标corners = cv2.goodFeaturesToTrack(gray, 20, 0.01, 10)corners = np.int0(corners)for i in corners:

# 压缩⾄⼀维:[[62, ]] -> [62, ] x, y = i.ravel()

cv2.circle(imgShi, (x, y), 4, (0, 0, 255), -1)

# 2. Harris⾓点检测

dst = cv2.cornerHarris(gray, 2, 3, 0.04)# 腐蚀⼀下,便于标记dst = cv2.dilate(dst, None)# ⾓点标记为红⾊

imgHarris[dst > 0.01 * dst.max()] = [0, 0, 255]

cv2.imwrite('compare.png', np.hstack((imgHarris, imgShi)))cv2.imshow('compare', np.hstack((imgHarris, imgShi)))cv2.waitKey(0)

左图为Harris⾓点检测结果,右图为Shi-Tomasi结果。可以看出,Shi-Tomasi⾓点检测的质量更⾼,数量也相对较少。⼀般情况下,Shi-Tomasi相⽐Harris速度有所提升,并且可以直接得到⾓点坐标。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务