第一篇: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,统计有效匹配点数量

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


相关推荐
林冠宏_指尖下的幽灵4 小时前
AI发展下的后编程时代思考
前端·人工智能·后端
盛世宏博智慧档案4 小时前
户外配电柜为什么要装POE供电以太网温湿度传感器?
服务器·网络·人工智能·监控·温湿度·配电柜
孙启超5 小时前
【AI开发之Rust】第 3 课:字符串与复合类型 —— 数据怎么放
开发语言·人工智能·后端·rust·llm·transformer
小智老师PMP5 小时前
2026PMP第八版新纲深度解读|从流程管控到价值交付,核心考点全迭代
人工智能·职场和发展·软件工程·制造·敏捷流程
秦先生在广东5 小时前
Worktrunk: 面向并行 AI Agent 工作流的 Git Worktree 管理 CLI
人工智能
韩曙亮5 小时前
【AI 大模型】国内各平台 AI 大模型 价格、性能 对比分析 ② ( 智谱 BigModel | 腾讯云 TokenHub | 千问 AI 平台 )
人工智能·ai·大模型·腾讯云·ai大模型·千问·智谱
YHL5 小时前
🧠 Agent 记忆进阶:总结压缩与向量检索 —— 从截断到 Milvus 长期记忆
前端·人工智能
llilian_165 小时前
时间统一系统 高精度时统设备选购避坑指南 授时系统
大数据·网络·人工智能·功能测试·单片机·嵌入式硬件·51单片机
仙魁XAN6 小时前
【WorkBuddy·基础入门】第 四 篇 :模式、技能、专家、连接器一次讲清
人工智能·workbuddy·workbuddy 基础入门·workbuddy 工具
呆萌很6 小时前
torch.nan_to_num 函数
人工智能