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

"花海"

  • 一、特征检测
    • 1.Harris角点检测
    • 2. shi-tomasi角点检测
    • 3. SIFT关键点检测
    • 4. 关键点和描述子
  • 二、几种角点特性

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

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

一、特征检测

特征检测包括边缘检测,角检测,区域检测和脊检测。【opencv图像处理】-- 8. 特征点检测:Harris,shi-tomasi,SIFT角点检测,关键点和描述子_第1张图片

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

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()

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()

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()

二、几种角点特性

  • Harris角点具有旋转不变的特性,但是缩放之后,原来的角点就可能不是角点了
  • SIFT,具有尺度不变性,可在图像中检测出关键点

你可能感兴趣的:(#,图像处理,opencv,图像处理,计算机视觉,人工智能,python)