OpenCV(21)角点检测1 -- Harris(基础)和Shi-Tomas(优化,佳)
Posted _睿智_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV(21)角点检测1 -- Harris(基础)和Shi-Tomas(优化,佳)相关的知识,希望对你有一定的参考价值。
目录
一、基础理论
在拼图时,我们要寻找一些唯一的特征,这些特征要适于被跟踪,容易被比较。我们在一副图像中搜索这样的特征,找到它们,而且也能在其他图像中找到这些特征,然后再把它们拼接到一起。我们的这些能力都是天生的。
角点是图像很重要的特征,对图像图形的理解和分析有很重要的作用。角点在三维场景重建运动估计,目标跟踪、目标识别、图像配准与匹配等计算机视觉领域起着菲常重要的作用。在现实世界中,角点对应于物体的拐角,道路的十字路口、丁字路口等。(角点易区分)
图像特征:要有区分性,容易被比较,一般认为角点、斑点等是较好的图像特征。
特征检测︰找到图像中的特征。
特征描述:对特征及其周围的区域进行描述。
推荐Shi-Tomas算法。
二、Harris角点检测
1、基础理论
1、原理
Harris角点检测的思想是通过图像的局部的小窗口观察图像,角点的特征:窗口沿任意方向移动都会导致图像灰度的明显变化,如下图所示:
2、公式推导
(角点是最大值)
可知M矩阵决定了E(u,v)最大值,所以可以通过求M矩阵来求E(u,v)最大值,即角点。
3、理论结果判定
(和分别是椭圆的长、短半轴)(也算是x和y方向的延伸)
结果分三种情况:
1、两个特征值都很大:角点
2、一个特征值大: 边缘
3、两个特征值都很小: 平坦区域
以上便是理论上的角点判断,下面讲一下实际判断方式:
4、实际结果判定
Harris给出的角点计算方法并不需要计算具体的特征值,而是计算一个角点响应值R来判断角点。
R的计算公式为:R = det(M) − k(trace(M))^2
公式:R = λ1λ2 − k(λ1+λ2)^2
式中,detM为矩阵M的行列式;traceM为矩阵M的迹;为常数,取值范围为0.04~0.06。事实上,特征是隐含在detM和traceM中,因为:
(λ1 和 λ2 是 M 的特征值 )
最终判定:
R>0:角点(大数值)
R<0:边缘(大树值负数)
R>0:平坦区域(小数)
2、函数
dst=cv.cornerHarrisisrc, blockSize, ksize,k)
img:数据类型为float32的输入图像。
blockSize:角点检测中要考虑的邻域大小。
ksize:sobel求导使用的核大小。
k :角点检测方程中的自由参数,取值参数为[0.04,0.06]。
dst = cv.cornerHarris(gray, 2, 3, 0.01) # 邻域大小 核 k取值(k越大,角越少)
要求:1、灰度图 2、float32类型
3、代码
# Harris角点检测
def Harris():
# 1、转灰度图
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 2、转float32(Harris输入图像必须是float32)
gray = np.float32(gray)
# 3、角点检测
dst = cv.cornerHarris(gray, 2, 3, 0.01)
# 邻域大小 核 k取值(k越大,角越少)
# 4、角点显色(最佳值的阈值可能因图像而异)
img[dst > 0.01*dst.max()] = [0,0,255]
cv.imshow('Harris',img)
4、效果
(感觉结果差了点,角点不仔细看都看不清楚,至少下面经过优化的Shi-Tomas的算法能让人眼前一亮)
三、Shi-Tomas角点检测(Harris的改进)
1、基础理论
Shi-Tomas算法是对Harris角点检测算法的改进,一般会比Harris算法得到更好的角点。
Harris:算法的角点响应函数是将矩阵M的行列式值与M的迹相减,利用差值判断是否为角点。公式:R = λ1λ2 − k(λ1+λ2)^2
Shi-Tomas:若矩阵M的两个特征值中较小的一个大于阈值,则认为他是角点。(小值大于阈值)
公式:R = min(λ1, λ2)
只有当 λ1 和 λ2 大于最小值 λmin 时,才将其视为拐角(绿色区域)
2、函数
corners = cv2.goodFeaturesToTrack (image,maxcorners,qualityLevel, minDistance )
lmage:输入灰度图像。
maxCorners :获取角点数的数目。
qualityLevel:该参数指出最低可接受的角点质量水平,在0-1之间。
minDistance:角点之间最小的欧式距离,避免得到相邻特征点。
有些点无法正常显示,要注意角点最大数量是否足够,这个函数能设置角点的最大数量。
3、代码
# Shi-Tomas角点检测(Harris的优化)
def Shi_Tomas():
# 1、灰度化
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 2、角点检测(返回坐标)
corners = cv.goodFeaturesToTrack(gray, 300, 0.01, 10)
# 最多角点数 角点质量水平 角点之间最小距离
corners = np.int0(corners) # 浮点型化整形
# 3、遍历每个角点坐标并画点
for i in corners:
x, y = i.ravel() # 取出横纵坐标
cv.circle(img, (x, y), 3, (0, 0, 255), -1) # 画点
# 圆心 半径 颜色 厚度
# 4、显示
cv.imshow('Shi-Tomas', img)
4、效果
(效果显而易见,推荐Shi-Tomas算法)
总代码
# 角点检测(Harris和Shi-Tomas)
import numpy as np
import cv2 as cv
# Harris角点检测
def Harris():
# 1、灰度化
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 2、转float32(Harris输入图像必须是float32)
gray = np.float32(gray)
# 3、角点检测
dst = cv.cornerHarris(gray, 2, 3, 0.01)
# 邻域大小 核 k取值(k越大,角越少)
# 4、角点显色(最佳值的阈值可能因图像而异)
img[dst > 0.01*dst.max()] = [0,0,255]
cv.imshow('Harris',img)
# Shi-Tomas角点检测(Harris的优化)
def Shi_Tomas():
# 1、灰度化
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 2、角点检测(返回坐标)
corners = cv.goodFeaturesToTrack(gray, 300, 0.01, 10)
# 最多角点数 角点质量水平 角点之间最小距离
corners = np.int0(corners) # 浮点型化整形
# 3、遍历每个角点坐标并画点
for i in corners:
x, y = i.ravel() # 取出横纵坐标
cv.circle(img, (x, y), 3, (0, 0, 255), -1) # 画点
# 圆心 半径 颜色 厚度
# 4、显示
cv.imshow('Shi-Tomas', img)
if __name__ == '__main__':
img = cv.imread('Resource/test15.jpg')
cv.imshow("img", img)
Harris() # Harris角点检测
Shi_Tomas() # Shi-Tomas角点检测
cv.waitKey(0)
参考资料
https://www.bilibili.com/video/BV1Fo4y1d7JL?p=45&spm_id_from=pageDriver
http://woshicver.com/Sixth/5_2_%E5%93%88%E9%87%8C%E6%96%AF%E8%A7%92%E6%A3%80%E6%B5%8B/
以上是关于OpenCV(21)角点检测1 -- Harris(基础)和Shi-Tomas(优化,佳)的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV角点检测源代码分析(Harris和ShiTomasi角点)
OpenCV 例程300篇238. OpenCV 中的 Harris 角点检测