第一篇:OpenCV特征检测与SIFT特征匹配

一、什么是图像特征

在计算机视觉中,图片并不只是由颜色和像素组成。程序还需要从图片中找到一些具有代表性的内容,例如:

1,角点;

2,边缘;

3,纹理;

4,方向变化明显的位置;

5,具有独特形状的局部区域。

6,这些内容可以称为图像特征。

例如,一张建筑物图片中,窗户的角落、屋顶的交点、文字的边缘,都可能成为特征点。不同图片如果包含相同物体,即使图片大小、角度或位置不同,也可能拥有一些相同的特征。

因此,特征检测可以用于:

图片匹配;目标识别;图像拼接;物体定位;指纹识别;人脸识别。


二、Harris角点检测

角点是图像中灰度变化明显的点。简单来说,如果一个小区域向各个方向移动,像素变化都很明显,那么这个位置就可能是角点。

例如矩形的四个拐角,通常具有比较明显的灰度变化。

OpenCV 中可以使用 Harris 算法检测角点:

复制代码
import cv2

image = cv2.imread(
    "coca.png"
)

gray = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2GRAY
)

dst = cv2.cornerHarris(
    gray,
    4,
    3,
    0.04
)

cornerHarris( )的参数包括:

gray:输入的灰度图像;

blockSize:计算角点时所考虑的邻域大小;

ksize:Sobel 算子的窗口大小;

k:Harris 算法中的参数。

检测结果 dst 是一个矩阵,其中每个位置都有一个角点响应值。响应值越大,表示这个位置越可能是角点。

可以设置阈值,将角点标记为红色:

复制代码
image[
    dst > 0.01 * dst.max()
] = [0, 0, 255]

最后显示图片:

复制代码
cv2.imshow(
    "corners",
    image
)

cv2.waitKey(0)
cv2.destroyAllWindows()

需要注意,OpenCV 使用 BGR 颜色顺序,因此:

复制代码
[0, 0, 255]

表示红色,而不是 RGB 中的蓝色。

Harris 角点检测适合寻找角落和交点,但它的特征表达能力比较有限。如果图片发生旋转、缩放或较大变化,单纯使用 Harris 角点可能不够稳定。


三、SIFT特征检测

SIFT 是一种比较经典的局部特征算法。它不仅可以找到关键点,还可以为每个关键点生成一个描述符。

关键点可以理解为:

图片中比较有代表性的位置

描述符则可以理解为:

描述这个关键点周围图像特征的一组数字

后面进行图片匹配时,程序并不是直接比较整张图片,而是比较这些关键点和描述符。

创建 SIFT 对象:

复制代码
sift = cv2.SIFT_create()

读取图片并转为灰度图:

复制代码
image = cv2.imread(
    "coca.png"
)

gray = cv2.cvtColor(
    image,
    cv2.COLOR_BGR2GRAY
)

检测关键点:

复制代码
keypoints = sift.detect(gray)

绘制关键点:

复制代码
result = cv2.drawKeypoints(
    image,
    keypoints,
    None,
    flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
)

cv2.imshow(
    "sift",
    result
)

cv2.waitKey(0)
cv2.destroyAllWindows()

在显示结果中,可以看到图片上出现许多圆圈或标记,这些位置就是 SIFT 检测到的关键点。

每个关键点都有一些属性:

pt:关键点坐标;

size:关键点所在区域的大小;

angle:关键点方向;

response:关键点响应值;

octave:关键点所在的尺度层级。

SIFT 能够在不同大小、不同方向的图片中寻找相似特征,因此比普通角点检测更加稳定。


四、计算特征描述符

只有关键点还不够,还需要计算描述符:

复制代码
kp, des = sift.compute(gray,keypoints)

也可以直接使用:

复制代码
keypoints, descriptors = sift.detectAndCompute(gray,None)

detectAndCompute() 会一次完成关键点检测和描述符计算。

查看结果:

复制代码
print(
    len(keypoints)
)

print(
    descriptors.shape
)

descriptors 通常是一个二维数组:

复制代码
关键点数量 × 描述符维度

SIFT 描述符一般是 128 维。也就是说,每个关键点都会对应一组数字,用来描述它附近的纹理和方向信息。


五、两张图片之间的特征匹配

有了两张图片的关键点和描述符后,就可以比较它们是否存在相同内容。

假设有两张指纹图片:

复制代码
img1 = cv2.imread("src.BMP")
img2 = cv2.imread("model.BMP")

分别提取特征:

复制代码
sift = cv2.SIFT_create()

kp1, des1 = sift.detectAndCompute(
    img1,
    None
)

kp2, des2 = sift.detectAndCompute(
    img2,
    None
)

然后创建 FLANN 匹配器:

复制代码
flann = cv2.FlannBasedMatcher()

使用 K 近邻匹配:

复制代码
matches = flann.knnMatch(
    des1,
    des2,
    k=2
)

这里的 k=2 表示:对于第一张图片中的每一个描述符,在第二张图片中寻找最相近的两个描述符。


六、Lowe比例测试

仅仅找到距离最近的特征点还不够,因为有些特征可能会产生误匹配。

代码中使用了 Lowe 比率测试:

复制代码
good_matches = []

for m, n in matches:
    if m.distance < 0.8 * n.distance:
        good_matches.append(m)

其中:

m 是距离最近的匹配;

n 是距离第二近的匹配;

m.distancen.distance 表示特征描述符之间的距离。

判断条件:

复制代码
m.distance < 0.8 * n.distance

意思是:最近的匹配必须明显优于第二近的匹配,才能认为它比较可靠。

如果两个距离非常接近,说明程序无法确定哪个才是真正的匹配,这种结果就会被舍弃。

最后统计有效匹配数量:

复制代码
num = len(good_matches)
print("有效匹配点:", num)

匹配点越多,通常表示两张图片越相似。


七、特征匹配的实际意义

SIFT具有旋转不变性和尺度不变性

在普通图片中,程序可以通过 SIFT 找到物体表面的特征。例如,一张建筑图片经过旋转或缩放后,仍然可能与原图匹配。

在指纹识别中,指纹纹理中有很多特殊的分叉点、端点和纹路结构。SIFT 可以从指纹图片中提取这些局部特征,再通过描述符匹配判断两张指纹是否属于同一个人。

整个过程不需要逐个比较所有像素,而是比较更有代表性的特征点,因此效率和稳定性都更好。


八、编程时需要注意的问题

1. 图片读取失败

复制代码
image = cv2.imread("coca.png")

if image is None:
    print("图片读取失败")

如果图片路径错误,imread() 会返回 None,后续调用灰度转换时会报错。

2. 描述符可能为空

如果图片太简单,或者图片读取失败,SIFT 可能检测不到关键点:

复制代码
if des1 is None or des2 is None:
    print("没有检测到足够的特征")

进行匹配前最好先判断。

3. 匹配数量不是唯一标准

匹配点数量越多,不一定代表结果绝对正确。还需要考虑:

1,匹配点是否分布合理;

2,是否集中在一个小区域;

3,图片是否存在重复纹理;

4,是否受到噪声影响。

在更复杂的项目中,还可以结合单应性矩阵和 RANSAC 去除错误匹配。


总结

本篇学习了 OpenCV 中的特征检测和特征匹配。

Harris 算法可以检测图像中的角点,适合寻找局部灰度变化明显的位置。SIFT 不仅可以检测关键点,还可以计算特征描述符,使图像在发生缩放、旋转后仍然能够进行匹配。

两张图片的匹配流程可以概括为:

1,读取图片

2,检测关键点

3,计算描述符

4,使用FLANN寻找近邻

5,通过比例测试筛选

6,统计有效匹配点数量

这些知识为后面的指纹验证和指纹识别打下了基础。


相关推荐
大熊背1 小时前
ISP图像处理中大数乘法溢出处理(一)
人工智能·python·算法·溢出处理
精彩AI说1 小时前
ChatGPT回答内容总是漏重点怎么办?需求拆分、检查清单与二次补充方法
人工智能·chatgpt
Alphapeople1 小时前
3D算法推荐项目
人工智能
hhzz1 小时前
智慧校园13类视频异常检测:数据集与预训练模型全攻略
人工智能·pytorch·python·深度学习·目标检测·机器学习
广西生活网1 小时前
水晶光电发布 2026 半年报:归母净利润 5.24 亿元同比增长 4.73%
人工智能·能源
浩腾数字多媒体1 小时前
如何判断专业电子留言厂家适配条件?
大数据·人工智能·python
阿里云大数据AI技术2 小时前
从 Common Crawl 到可训练语料:用 EMR Serverless Daft 构建清洗、模型标注与向量化管线
人工智能·spark
jay神2 小时前
27届计算机专业深度学习选题推荐
人工智能·深度学习·yolo·机器学习·计算机视觉
stuartevil2 小时前
AI漫剧日更制作怎么做才不累
人工智能