OpenCV(21)角点检测1 -- Harris(基础)和Shi-Tomas(优化,佳)

Posted _睿智_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV(21)角点检测1 -- Harris(基础)和Shi-Tomas(优化,佳)相关的知识,希望对你有一定的参考价值。

目录

一、基础理论

二、Harris角点检测

1、基础理论

1、原理

2、公式推导

3、理论结果判定 

4、实际结果判定

2、函数

 3、代码

 4、效果

三、Shi-Tomas角点检测(Harris的改进)

1、基础理论

 2、函数

3、代码

4、效果

总代码

参考资料


一、基础理论

        在拼图时,我们要寻找一些唯一的特征,这些特征要适于被跟踪容易被比较。我们在一副图像中搜索这样的特征找到它们,而且也能在其他图像中找到这些特征,然后再把它们拼接到一起。我们的这些能力都是天生的。

        角点是图像很重要的特征,对图像图形的理解和分析有很重要的作用。角点在三维场景重建运动估计,目标跟踪、目标识别、图像配准与匹配等计算机视觉领域起着菲常重要的作用。在现实世界中,角点对应于物体的拐角,道路的十字路口、丁字路口等。(角点易区分

图像特征:要有区分性,容易被比较,一般认为角点斑点等是较好的图像特征。

特征检测︰找到图像中的特征

特征描述:对特征及其周围的区域进行描述。

推荐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。事实上,特征是隐含在detMtraceM中,因为:

(λ1 λ2 是 特征值 )

 最终判定:

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角点检测

OpenCV角点检测源代码分析(Harris和ShiTomasi角点)

OpenCV 例程300篇238. OpenCV 中的 Harris 角点检测

OpenCV 例程300篇238. OpenCV 中的 Harris 角点检测

opencv-角点检测之Harris角点检测

Opencv Harris角点检测