python编程-OpenCV(图像读写-图像处理-图像滤波-角点检测-边缘检测)角点检测

角点检测(Corner Detection)是计算机视觉和图像处理中重要的步骤,主要用于提取图像中的关键特征,以便进行后续的任务,比如图像匹配、物体识别、运动跟踪等。下面介绍几种常用的角点检测方法及其应用。

1. Harris角点检测

Harris角点检测是一种经典的角点检测算法,基于图像的局部特征,通过计算图像的自相关矩阵来判断一个点是否为角点。

  • 原理

    • 计算局部窗口内的图像梯度,并构造自相关矩阵。
    • 通过计算赫希因子(Harris Matrix),确定强度响应,响应值大于一定阈值的点被认为是角点。
  • 优点

    • 对于噪声具有一定的鲁棒性。
    • 可以检测到多种类型的角点。

OpenCV 中的 cv.cornerHarris() 函数用来实现 Harris 角点检测。它的参数是:

img - 输入图像,应为 float32 类型的灰度图。

blockSize - 角点检测所考虑的邻域大小。

ksize - Sobel 导数的内核大小。

k - Harris 检测器方程中的自由参数。

OpenCV 带有一个函数 cv.cornerSubPix() ,它进一步细化了角点检测,以达到亚像素级精度。

python 复制代码
import numpy as np
import cv2 as cv
filename = 'output.png'
img = cv.imread(filename)
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# find Harris corners
gray = np.float32(gray)
dst = cv.cornerHarris(gray,2,3,0.04)
dst = cv.dilate(dst,None)
ret, dst = cv.threshold(dst,0.01*dst.max(),255,0)
dst = np.uint8(dst)
# find centroids
ret, labels, stats, centroids = cv.connectedComponentsWithStats(dst)
# define the criteria to stop and refine the corners
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 100, 0.001)
corners = cv.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria)
# Now draw them
res = np.hstack((centroids,corners))
res = np.intp(res)
img[res[:,1],res[:,0]]=[0,0,255]
img[res[:,3],res[:,2]] = [0,255,0]
cv.imshow('sobely',img)
cv.waitKey(0)

2. Shi-Tomasi角点检测

Shi-Tomasi角点检测法是对Harris方法的改进,更注重测量响应函数的特征。

  • 原理

    • 通过计算两个特征值,选择具有较大特征值的点作为角点。
    • 角点的选择更为简洁和高效。
  • 优点

    • 对图像旋转和尺度变化具有更好的鲁棒性。
    • 适合实时应用,如视频监控。

OpenCV 有一个函数, cv.goodFeaturesToTrack() 。它通过 Shi-Tomasi 方法(或 Harris 角点检测,如果你指定它)在图像中找到 N 个最佳的角点。输入图像应该是灰度图像。然后指定要查找的角点数量。然后指定质量等级,该等级是 0-1 之间的值,所有低于这个质量等级的角点都将被忽略。最后设置检测到的两个角点之间的最小欧氏距离。

例如尝试找到 25 个最佳角点:

python 复制代码
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('f:/apple.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
corners = cv.goodFeaturesToTrack(gray,25,0.01,10)
corners = np.intp(corners)
for i in corners:
    x,y = i.ravel()
    cv.circle(img,(x,y),3,255,-1)
plt.imshow(img),plt.show()

3. SIFT(尺度不变特征变换)

SIFT是一种用于检测和描述局部特征的算法,具有对尺度、旋转和光照变化的高鲁棒性。

  • 原理

    • 检测图像中多个尺度的关键点。
    • 生成每个关键点的描述符,以便进行特征匹配。
  • 优点

    • 高鲁棒性,适用于图像匹配、拼接等应用。
    • 可以处理遮挡和光照变化。

SIFT算法主要可以分成以下几个步骤:

  1. 构建高斯金字塔(Gaussian Pyramid)

    • 对于给定的图像,首先通过对图像进行不同尺度的高斯模糊,构建一个高斯金字塔。这涉及到对原图像逐层进行模糊,每一层的尺度增大。通常,金字塔中的每一层是上一层的平滑图像。
  2. 构建差分高斯金字塔(Difference of Gaussian)

    • 通过相邻的高斯图像层之间进行减法来计算差分高斯(DoG),该过程可以近似计算图像的拉普拉斯金字塔(Laplacian Pyramid)。
    • 公式为:
  1. 关键点检测
  • 对于每个像素点,寻找极值点,即在当前尺度和相邻的尺度(上层和下层)中具有极大或极小值的点。具体步骤如下:
    • 遍历图像的每个像素,检查其是否在其邻域内(包括尺度上和空间上)是最大或最小点。
    • 一般使用3x3x3的邻域,即考虑9个临近像素的3个尺度。

4. 精确定位关键点

  • 对检测到的关键点进行细化,以提高其定位精度。常用的方法是通过泰勒级数展开。即优化关键点的位置,利用Hessian矩阵或者主导方向计算来细化关键点的位置和尺度。

5. 选择主方向

  • 为每个关键点分配一个或多个主方向,以使得描述符具有旋转不变性。
    • 计算关键点周围一定半径内的梯度值,并确定主方向。
    • 形成一个方向直方图,用于统计方向,并选择最大直方图峰值作为关键点的主方向。

6. 生成关键点描述符

  • 在每个关键点的周围区域中,计算其特征描述符。通常,这个区域被划分为多个子区块,并在每个子区块内计算梯度方向和幅值。
  • 将每个子块的梯度信息汇总,形成一个包含多维信息的特征向量。

7. 特征点匹配(可选)

  • 利用上述计算得到的描述符,针对不同图像中的特征点进行匹配。通常采取欧几里德距离或二元汉明距离来计算描述符之间的相似度。

具体步骤

  1. 构建高斯金字塔:对图像进行多次高斯模糊,生成一系列不同尺度的图像。

  2. 计算差分高斯:通过相邻两层的高斯图像做差,提取出潜在的特征点。

  3. 找到极值点:例如,对于某个像素,比较它与相邻8个像素以及上面和下面的对应像素,如果它是最大的或最小的,则记为一个关键点。

  4. 关键点精确定位:利用插值方法进行位置微调,去除那些边缘响应较强或低对比度的关键点。

  5. 计算方向:统计关键点周围像素的梯度直方图,确定主要方向。

  6. 生成描述符:以关键点的主方向为基准,计算关键点周围小块的描述符。

  7. 匹配过程:对于每个图像的特征点,可以使用最近邻法或比例测试进行匹配。

python 复制代码
import numpy as np
import cv2 as cv
img = cv.imread('f:/apple.jpg')
gray= cv.cvtColor(img,cv.COLOR_BGR2GRAY)
sift = cv.xfeatures2d.SIFT_create()
kp = sift.detect(gray,None)
img=cv.drawKeypoints(gray,kp,img)
img=cv.drawKeypoints(gray,kp,img,flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv.imshow('SIFT',img)
cv.waitKey(0)

4. SURF算法

SURF的基本理念是在SIFT的基础上,通过加快特征点检测和描述过程,取得更高的效率。SURF的主要步骤如下:

1.1 特征点检测
  • Hessian矩阵:SURF使用Hessian矩阵的行列式来检测特征点。通过计算每个像素点的Hessian矩阵,可以快速找到潜在的特征点。Hessian矩阵具有以下形式:
  • 盒子滤波:为了计算Hessian矩阵的行列式,SURF使用的是快速的Haar小波卷积。这种方法通过将图像分为不同大小的盒子,并使用加权和减少计算复杂度。

  • 梯度计算:SURF在特征点周围的邻域内计算图像的梯度值,并将其组织成一个描述符。描述符的生成过程涉及多个子块,各子块的特征会被汇总成一个固定长度的描述符。

  • 方向归一化:为了确保特征描述符具有方向不变性,SURF根据特征点的主方向进行方向归一化。

1.2 特征描述符生成
  • 梯度计算:SURF在特征点周围的邻域内计算图像的梯度值,并将其组织成一个描述符。描述符的生成过程涉及多个子块,各子块的特征会被汇总成一个固定长度的描述符。

  • 方向归一化:为了确保特征描述符具有方向不变性,SURF根据特征点的主方向进行方向归一化。

python 复制代码
import cv2 as cv
from matplotlib import pyplot as plt

# 读取图像
img = cv.imread('f:/apple.jpg', 0)

# Create SURF object. You can specify params here or later.
# Here I set Hessian Threshold to 400
surf = cv.xfeatures2d.SURF_create(400)
# Find keypoints and descriptors directly
kp, des = surf.detectAndCompute(img,None)

# Check present Hessian threshold
print( surf.getHessianThreshold() )

# We set it to some 50000. Remember, it is just for representing in picture.
# In actual cases, it is better to have a value 300-500
surf.setHessianThreshold(50000)
# Again compute keypoints and check its number.
kp, des = surf.detectAndCompute(img,None)
print( len(kp) )

img2 = cv.drawKeypoints(img,kp,None,(255,0,0),4)
plt.imshow(img2),plt.show()

5. ORB(Oriented FAST and Rotated BRIEF)

ORB结合了FAST特征检测和BRIEF特征描述,可以更快速地进行角点检测和描述。ORB 基本上是 FAST 特征点检测器和 Brief 描述子的融合,并进行了许多修改以增强性能。首先,它使用 FAST 查找特征点,然后应用 Harris 角点的测量方法来查找其中的前 N 个点。它还使用金字塔来生成多尺度特征。但有一个问题是,FAST 不计算方向。

  • 原理

    • 使用FAST算法检测特征点,计算点的方向和角度。
    • 采用BRIEF描述符来描述特征。
  • 优点

    • 快速高效,适合实时应用。
    • 对于图像的旋转具有稳健性。

cv.ORB()使用 feature2d 通用接口创建 ORB 对象。它有许多可选参数。

nFeatures,表示要保留的最大要素数量(默认为 500),

scoreType, 表示对特征点进行排序使用 Harris 得分或 FAST 得分(默认为 Harris 得分)等。

WTA_K, 决定生成一个 oriented BRIEF 描述子的所用的像素点数目。默认情况下它是 2,即一次选择两个点。在这种情况下进行匹配,使用 NORM_HAMMING 距离。如果 WTA_K 为 3 或 4,则需要 3 或 4 个点来产生 BRIEF 描述子,匹配距离由 NORM_HAMMING2 定义。

python 复制代码
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('f:/apple.jpg',0)
# Initiate ORB detector
orb = cv.ORB_create()
# find the keypoints with ORB
kp = orb.detect(img,None)
# compute the descriptors with ORB
kp, des = orb.compute(img, kp)
# draw only keypoints location,not size and orientation
img2 = cv.drawKeypoints(img, kp, None, color=(0,255,0), flags=0)
plt.imshow(img2), plt.show()
相关推荐
&zzz3 分钟前
PyTorch和 torchvision 和torch 和cu1版本不匹配
人工智能·pytorch·python
m0_748256564 分钟前
爬虫自动化(DrissionPage)
爬虫·python·自动化
江木1231 小时前
Python Numba多流和共享内存CUDA优化技术学习记录
开发语言·python·学习
多多*2 小时前
Sync底层字节码 monitorEnter和monitorExit 对象监视器
java·开发语言·windows·python·spring
小豆豆儿2 小时前
【PyCharm】快捷键使用
ide·python·pycharm
互联网杂货铺3 小时前
接口测试自动化实战(超详细的)
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·接口测试
处女座_三月3 小时前
使用QQ登录(头条项目-09)
android·python·django
程序员陆通3 小时前
使用 Python 开发一个 AI Agent 自媒体助手示例
人工智能·python·媒体
zhangfeng11333 小时前
python mysql库的三个库mysqlclient mysql-connector-python pymysql如何选择,他们之间的区别
数据库·python·mysql