Opencv之图像SIFT 特征检测与Harris角点检测

发布于:2025-03-01 ⋅ 阅读:(13) ⋅ 点赞:(0)

图像SIFT 特征检测与Harris角点检测

1 SIFT 特征检测


1.1 概念

SIFT(尺度不变特征变换)是一种用于图像处理中检测和描述图像中局部结构的算法。它是由David Lowe在1999年提出的,并在2004年进行了详细阐述。SIFT特征具有尺度不变性,这意味着即使图像的尺度发生变化,SIFT特征也能保持稳定

1.2 主要步骤

  1. 尺度空间极值检测

    • 构建尺度空间:通过使用高斯模糊对原始图像进行不同尺度的模糊处理,形成多尺度图像金字塔
    • 检测极值点:在尺度空间中,比较每个点与其周围邻域(包括同一尺度和相邻尺度)的像素值,找出局部极值点
  2. 关键点定位

    • 通过对极值点进行亚像素精度的插值,精确确定关键点的位置和尺度。
    • 剔除低对比度的关键点和不稳定的边缘响应点。
  3. 方向分配

    • 为每个关键点分配一个或多个方向,使SIFT特征具有旋转不变性。
    • 通过计算关键点邻域内的梯度方向直方图,找出主方向和辅方向。
  4. 特征描述

    • 在每个关键点周围取一个区域,将这个区域划分为若干个小块。
    • 对每个小块计算梯度方向直方图,形成特征向量。
    • 为了增强特征的鲁棒性,对特征向量进行归一化处理。

1.3 优缺点

SIFT特征的优点

  • 尺度不变性:能够适应图像的尺度变化。
  • 旋转不变性:能够适应图像的旋转变化。
  • 对光照、仿射变换和噪声具有一定的鲁棒性

SIFT特征的缺点

  • 计算复杂度较高,实时性较差。
  • 对于非线性变换和大幅度的视角变化,SIFT特征的性能可能会下降。

1.4 函数及参数

  • sift = cv2.SIFT_create(),创建 SIFT 特征检测器对象

  • kp = sift .detect(phone_0) ,检测关键点

    • phone_0为灰度图
  • phone_sift = cv2.drawKeypoints(phone,kp,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)绘制检测到的关键点

    • phone,绘制在的图像
    • kp,绘制的关键点
    • flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS 表示绘制带有关键点大小和方向的信息

2 Harris角点检测


2.1 概念

Harris 角点检测是一种经典的计算机视觉算法,用于检测图像中的角点。角点是图像中具有显著变化的特征点,通常位于物体的边缘或纹理丰富的区域。Harris 角点检测算法由 Chris Harris 和 Mike Stephens 在 1988 年提出,具有旋转不变性和对噪声的鲁棒性。

2.2 算法思想

Harris角点检测的核心思想是利用局部窗口在图像上进行移动,判断窗口内的灰度值是否发生较大的变化。如果窗口在所有方向上的移动都导致灰度值显著变化,那么这个窗口所在区域就存在角点

2.3 特点

旋转不变性:角点的检测不受图像旋转的影响。
对噪声鲁棒:通过高斯平滑,算法对噪声具有一定的鲁棒性。
对尺度敏感:Harris 角点检测对图像尺度变化敏感,不适合处理尺度变化较大的场景。

2.4 函数及参数

  • cv2.cornerHarris(gray, 4, 3, 0.04), Harris 角点检测图像中的角点
    • gray: 输入的灰度图像
    • 4: 角点检测的邻域大小
    • 3: Sobel 算子的孔径参数
    • 0.04: Harris 检测器的自由参数

3 角点、特征检测


3.1 焦点、特征检测代码及结果

代码展示:

import cv2
import numpy as np

img = cv2.imread('fang.png')
gray  = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

dst = cv2.cornerHarris(gray,4,3,0.04)
img[dst > 0.01*dst.max()] = [0,0,255]
cv2.imshow('img',img)
cv2.waitKey(0)
phone = cv2.imread('mm.jpg')
phone_0= cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY)
cv2.imshow('phone_0',phone_0)
cv2.waitKey(0)

phone_copy = phone.copy()
dst1 = cv2.cornerHarris(phone_0,4,3,0.04)
phone_copy[dst1 > 0.01*dst1.max()] = [0,0,255]
cv2.imshow('phone',phone_copy)
cv2.waitKey(0)

sift = cv2.SIFT_create()
kp = sift.detect(phone_0)
phone_sift = cv2.drawKeypoints(phone,kp,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
kp,des = sift.compute(phone,kp)
print(np.array(kp).shape,des.shape)
cv2.imshow('phone_sift',phone_sift)
cv2.waitKey(0)

运行结果:
在这里插入图片描述
在这里插入图片描述