• OpenCV 14(角点特征Harris和Shi-Tomasi)


    一、角点

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

    • 蓝色框中的区域是一个平面很难被找到和跟踪。无论向哪个方向移动蓝色框,都是一样的
    • 对于黑色框中的区域,它是一个边缘。如果沿垂直方向移动,它会改变。但是如果沿水平方向移动就不会改变。
    • 红色框中的角点,无论你向那个方向移动,得到的结果都不同,这说明它是唯一的。

    所以,我们说角点是一个好的图像特征。

    二、Harris角点检测

    Harris角点检测的思想是通过图像的局部的小窗口观察图像,角点的特征是窗口沿任意方向移动都会导致图像灰度的明显变化,如下图所示:

    将上述思想转换为数学形式,即将局部窗口向各个方向移动(u,v)并计算所有灰度差异的总和,表达式如下:

    其中I(x,y)是局部窗口的图像灰度,I(x+u,y+v)是平移后的图像灰度,w(x,y)是窗口函数,该可以是矩形窗口,也可以是对每一个像素赋予不同权重的高斯窗口,如下所示:

    角点检测中使E(u,v)的值最大。利用一阶泰勒展开有:

    椭圆函数特征值与图像中的角点、直线(边缘)和平面之间的关系如下图所示。

    • 图像中的直线。一个特征值大,另一个特征值小,λ1>>λ2或 λ2>>λ1。椭圆函数值在某一方向上大,在其他方向上小。
    • 图像中的平面。两个特征值都小,且近似相等;椭圆函数数值在各个方向上都小。
    • 图像中的角点。两个特征值都大,且近似相等,椭圆函数在所有方向都增大

    Harris给出的角点计算方法并不需要计算具体的特征值,而是计算一个角点响应值R来判断角点。R的计算公式为:

    那我们怎么判断角点呢?如下图所示:

    •  当R为大数值的正数时是角点
    • 当R为大数值的负数时是边界
    • 当R为小数是认为是平坦区域

    dst=cv.cornerHarris(src, blockSize, ksize, k)
    
    • img:数据类型为 float32 的输入图像。

    • blockSize:角点检测中要考虑的邻域大小。

    • ksize:sobel求导使用的核大小

    • k :角点检测方程中的自由参数,取值参数为 [0.04,0.06].

    1. import cv2 as cv
    2. import numpy as np
    3. import matplotlib.pyplot as plt
    4. # 1 读取图像,并转换成灰度图像
    5. img = cv.imread('./image/chessboard.jpg')
    6. gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    7. # 2 角点检测
    8. # 2.1 输入图像必须是 float32
    9. gray = np.float32(gray)
    10. # 2.2 最后一个参数在 0.04 到 0.05 之间
    11. dst = cv.cornerHarris(gray,2,3,0.04)
    12. # 3 设置阈值,将角点绘制出来,阈值根据图像进行选择
    13. img[dst>0.001*dst.max()] = [0,0,255]
    14. # 4 图像显示
    15. plt.figure(figsize=(10,8),dpi=100)
    16. plt.imshow(img[:,:,::-1]),plt.title('Harris角点检测')
    17. plt.xticks([]), plt.yticks([])
    18. plt.show()

    Harris角点检测的优缺点:

    优点:

    • 旋转不变性,椭圆转过一定角度但是其形状保持不变(特征值保持不变)
    • 对于图像灰度的仿射变化具有部分的不变性,由于仅仅使用了图像的一介导数,对于图像灰度平移变化不变;对于图像灰度尺度变化不变

    缺点:

    • 对尺度很敏感,不具备几何尺度不变性
    • 提取的角点是像素级的

    三、Shi-Tomasi角点检测

    Shi-Tomasi算法是对Harris角点检测算法的改进,一般会比Harris算法得到更好的角点。

    • Harris 算法的角点响应函数是将矩阵 M 的行列式值与 M 的迹相减,利用差值判断是否为角点。

    • 后来Shi 和Tomasi 提出改进的方法是,若矩阵M的两个特征值中较小的一个大于阈值,则认为他是角点,即:

    从这幅图中,可以看出来只有当 λ1 和 λ 2 都大于最小值时,才被认为是角点。

    corners = cv2.goodFeaturesToTrack ( image, maxcorners, qualityLevel, minDistance )
    
    • Image: 输入灰度图像
    • maxCorners : 获取角点数的数目。
    • qualityLevel:该参数指出最低可接受的角点质量水平,在0-1之间。
    • minDistance:角点之间最小的欧式距离,避免得到相邻特征点。

      返回:

    • Corners: 搜索到的角点,在这里所有低于质量水平的角点被排除掉,然后把合格的角点按质量排序,然后将质量较好的角点附近(小于最小欧式距离)的角点删掉,最后找到maxCorners个角点返回。
    1. import numpy as np
    2. import cv2 as cv
    3. import matplotlib.pyplot as plt
    4. # 1 读取图像
    5. img = cv.imread('./image/tv.jpg')
    6. gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    7. # 2 角点检测
    8. corners = cv.goodFeaturesToTrack(gray,1000,0.01,10)
    9. # 3 绘制角点
    10. for i in corners:
    11. x,y = i.ravel()
    12. cv.circle(img,(x,y),2,(0,0,255),-1)
    13. # 4 图像展示
    14. plt.figure(figsize=(10,8),dpi=100)
    15. plt.imshow(img[:,:,::-1]),plt.title('shi-tomasi角点检测')
    16. plt.xticks([]), plt.yticks([])
    17. plt.show()

  • 相关阅读:
    【loadrunner】form表单模式提交例子
    92.(cesium之家)cesium楼栋分层
    UDP的可靠性传输2
    数据可视化:视觉感知与基本图表
    深入解析:如何基于GB32960标准,使用Java构建车联网数据接入网关
    SpringBoot-07-配置文件配置原理
    Unity脚本的基础语法(1)-游戏对象的常用操作
    白杨SEO:有技能专长的人想要做好知识付费的核心是什么?
    vue项目打包后使用reverse-sourcemap反编译到源码(详解版)
    stm32----ADC模数转换
  • 原文地址:https://blog.csdn.net/peng_258/article/details/133521234