• 【opencv图像处理】-- 8. 特征点检测:Harris,shi-tomasi,SIFT角点检测,关键点和描述子


    希望有能力的朋友还是拿C++做。

    本节讨论特征检测,主要是Harris,shi-tomasi,sift三种方法和对比,以及原理简介,还有关键点和描述子的概念介绍。

    一、特征检测

    特征检测包括边缘检测,角检测,区域检测和脊检测。在这里插入图片描述

    • 应用场景:图像搜索(如以图搜图),拼图游戏,图像拼接
    • 寻找特征:
      • 唯一的
      • 可追踪的
      • 能比较的
    • 角点:
      • 灰度梯度的最大值对应的像素
      • 两条线的交点
      • 极值点(一阶导数最大,二阶导数为0)

    1.Harris角点检测

    角点检测数学原理地址

    • 直观理解就是用一个矩形框,去在图像中移动,当图像(x,y)(x,y),在点(x,y)(x,y)处平移(Δx,Δy)(Δx,Δy)后的自相似性(就是两个图像做差)
    • 细节处理是对矩形框的权重
    • 在平坦区域,任意移动衡量系统变换都不大
    • 在边缘区域,垂直边缘移动,衡量系统变换剧烈
    • 在角点处,往哪个方向移动,衡量系统都变化剧烈
    • cornerHarris(src, blockSize, ksize, k[, dst[, borderType]])
      • blockSize:检测窗口大小
      • ksize:卷积核
      • k:权重系数,是个经验值,一般取0.04~0.06之间,一般默认0.04
      • 它的返回值是一个无通道数据的,尺寸与原图相同的ndarray数组,数据为TRUE证明是角点
    import cv2
    import numpy as np
    
    img = cv2.imread('homework.jpg')
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    dst = cv2.cornerHarris(gray, blockSize=2, ksize=3, k=0.04)
    
    #返回的东西叫做角点响应,每一个像素点都能计算出一个角点响应
    #print(dst.shape)
    #显示角点
    #我们认为角点响应大于0.01倍的dst.max()就可以认为是角点了
    #print(dst>(0.01 * dst.max()))
    #print(img.shape)
    img[(dst>(0.05 * dst.max()))] = [0,0,255]
    cv2.imshow('img', img)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2. shi-tomasi角点检测

    • 改进了harris算法,harris角点检测计算的稳定性与k有关,而K是一个经验值,不太好设定最佳K值
    • shi-tomasi发现,角点稳定性与矩阵M的较小特征值有关,对算法做了调整,就不用调整K值了

    • goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance[, corners[, mask[, blockSize[, useHarrisDetector[, k]]]]])
      • maxCorners:角点的最大值
      • qualityLevel:角点质量
      • minDistance:角之间最小欧氏距离,忽略小于此距离的点
      • mask:感兴趣的区域
      • blockSize:检测窗口的大小
      • useHarrisDetector:是否使用Harris算法
      • k:默认是0.04
    import cv2
    import numpy as np
    
    maxCorners = 100
    q1 = 0.01
    minDistance = 10
    
    img = cv2.imread('homework.jpg')
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    
    corners = cv2.goodFeaturesToTrack(gray, maxCorners, q1, minDistance)
    corners = np.int0(corners)
    
    #Shi-Tomasi绘制角点
    for i in corners:
        x,y = i.ravel() #二维变一维
        cv2.circle(img, (x,y), 3, (255,255,0), -1)
        
    cv2.imshow('img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3. SIFT关键点检测

    希望在图片不同尺寸(图像金字塔),不同分辨率(高斯滤波)下,都能找到角点。
    sift关键点检测原理说明

    • 高斯差分金字塔(DOG),金字塔间不同层级之间图像做差
    • DOG空间极值检测:为寻找尺度空间极值点,每个像素点要和(图像域)同一尺度空间、(相邻域)相邻尺度空间的所有点进行比较。
    • 关键点的精确定位:对比出来的DOG空间的极值点都是离散的点,精确定位的一种方法是,对尺度空间的DOG函数进行拟合,计算其极值点,从而实现关键点的精确定位。
    • 使用SIFT:
      • 创建SIFT对象 sift=cv2.xfeatures2d.SIFT_create()
      • 进行检测 kp = sift, detect(img, …)
      • 绘制关键点 drawKeypoints(gray, kp, img)
    import cv2
    import numpy as np
    
    img = cv2.imread('homework.jpg')
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    
    #创建sift对象
    #注意:xfretures2d是opencv的扩展包中的内容,需要安装opencv扩展包:opencv-contrib-python
    sift = cv2.xfeatures2d.SIFT_create()
    
    #进行检测
    kp = sift.detect(gray)
    print(kp)
    #绘制关键点
    cv2.drawKeypoints(gray, kp, img)
    
    cv2.imshow('img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4. 关键点和描述子

    • 关键点:返回的keypoints, 只包含位置大小方向
    • 关键点描述子:记录了关键点周围对其又共享像素点的一组向量值,其不受仿射变换,光照变换等的影响,作用是进行特征匹配,在后面进行特征匹配会用上
    import cv2
    import numpy as np
    
    img = cv2.imread('homework.jpg')
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    
    #创建sift对象
    sift = cv2.xfeatures2d.SIFT_create()
    
    #进行检测
    kp = sift.detect(gray)
    
    #检测关键点,并计算描述子
    kp,des = sift.compute(img, kp)
    
    #或者一步到位,一起检测,none是掩膜
    #kp, des = sift.detectAndCompute(img, None)
    
    #print(kp, des)
    # #绘制关键点
    cv2.drawKeypoints(gray, kp, img)
    
    cv2.imshow('img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    二、几种角点特性

    • Harris角点具有旋转不变的特性,但是缩放之后,原来的角点就可能不是角点了
    • SIFT,具有尺度不变性,可在图像中检测出关键点
  • 相关阅读:
    vue加载图片,地图,请求api跨域问题
    如何高效且优雅地使用Redis
    Qt信号槽与多线程的关系
    医院陪诊小程序源码 陪诊陪护小程序源码
    01_Linux字符设备驱动开发
    txt大文件拆分(批量版)
    HTTPS
    [论文笔记] Scaling Laws for Neural Language Models
    SpringBoot SpringBoot 基础篇(第一篇) 第2章 SpringBoot 全局配置 2.2 yaml 文件
    涨点神器!全局注意力+位置注意力,打造更强深度学习模型
  • 原文地址:https://blog.csdn.net/Eric_Sober/article/details/126055004