opencv-基于 SIFT 特征和 FLANN 匹配器的图像特征点匹配与可视化

指纹验证案例中,指纹1与模板图片匹配成功了,分别在两图内标出匹配成功点的坐标

要求:匹配结果最近的distance小于次接近distance的0.4

提示:cv2.circle(src, (x,y), 3, (0, 0, 255), -1),绘制实心圆

分块详解

第1块:导入和辅助函数

import cv2

def cv_show(name, img):

cv2.imshow(name, img)

cv2.waitKey(0)

  • 作用 :导入 OpenCV 库,定义显示图像的函数 cv_show,它创建一个窗口显示图像,并等待按键后关闭窗口(waitKey(0) 表示无限等待)。

第2块:读取并显示原始图像

src1 = cv2.imread('1.bmp')

model = cv2.imread('3.bmp')

cv_show('src1', src1)

cv_show('model', model)

  • 作用 :从文件读取两张待匹配的图像(src1 为待匹配图,model 为模板图),并显示它们以确认读取成功。


第3块:SIFT 特征提取

sift = cv2.SIFT_create()

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

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

  • 作用 :创建 SIFT 对象,检测每张图像的关键点(kp)并计算对应的描述子(des)。描述子是 128 维向量,用于后续匹配。SIFT 就像一个"细节提取机",它会自动在大图和小图里找出最突出的角角落落、纹理变化大的点 (比如扇子的尖角、图案的边缘)。这些点叫"关键点"(kp),而 des 就是每个点的"身份证号码"(一串数字)。

  • 重要函数cv2.SIFT_create()detectAndCompute(image, mask)

    • cv2.SIFT_create():返回 SIFT 对象,可选参数有 nfeatures(特征点数量)、nOctaveLayers 等。

    • detectAndCompute(image, mask)image 是输入图像(灰度或彩色),mask 是可选掩膜,指定感兴趣区域。返回值是 (keypoints, descriptors)keypointsKeyPoint 对象列表,descriptors 是形状为 (N, 128) 的 numpy 数组。


第4块:FLANN 匹配器创建与 kNN 匹配

flann = cv2.FlannBasedMatcher()

matches = flann.knnMatch(des1, des2, k=2)

  • 作用 :基于 FLANN(快速最近邻搜索库)创建匹配器,对 des1 中的每个描述子在 des2 中找出最近的 2 个 匹配(k=2),返回 matches,它是一个列表,每个元素是包含 2 个 DMatch 对象的元组。其实就是找两个最像的描述子

  • 重要函数cv2.FlannBasedMatcher([index_params[, search_params]])

    • 若不传参,使用默认参数,但对于 SIFT 描述子(浮点型),建议指定索引参数为 KDTree,例如:

      index_params = dict(algorithm=1, trees=5)

      search_params = dict(checks=50)

      flann = cv2.FlannBasedMatcher(index_params, search_params)

    • knnMatch(queryDescriptors, trainDescriptors, k)query 为第一幅图的描述子,train 为第二幅图的描述子,k 为返回的最近邻个数。返回值 matchesList[List[DMatch]]


第5块:Lowe's 比率测试筛选优质匹配

good = \[\]

alist = \[\]

for m, n in matches:

if m.distance < 0.4 * n.distance:

alist.append((m.queryIdx, m.trainIdx))

good.append((m, n))

  • 作用 :对每个 (m, n) 对,m 是最近邻,n 是次近邻。如果 m.distance 远小于 n.distance(阈值 0.4),则认为 m 是可靠的匹配。这里 0.4 设置得越小,留下的匹配点越少,但越精准。筛选后:

    • alist 存储匹配点对在各自关键点列表中的索引,用于后续绘制圆点

    • good 存储原始匹配对 (m, n),但注意这里 good 的元素是元组,用于后续 drawMatchesKnn 时会出错(应为列表的列表)。

  • 重要:Lowe 比率测试是 SIFT 匹配中的经典筛选方法,阈值通常取 0.7~0.8。


第6块:在两张原图上绘制筛选出的关键点(红色圆点)

for i, j in alist:

x, y = kp1i.pt

m, n = kp2j.pt

cv2.circle(src1, (int(x), int(y)), 3, (0, 0, 255), -1)

cv2.circle(model, (int(m), int(n)), 3, (0, 0, 255), -1)

cv_show('Marked src1', src1)

cv_show('Marked model', model)

  • 作用 :遍历筛选出的匹配索引,提取关键点坐标,用红色实心圆标记在图像上。注意此处直接修改了 src1model 原图。

  • alist :只记了匹配上的点的"编号",.pt: 选取对应点的坐标


第7块:绘制匹配连线(显示匹配关系)

matched_image = cv2.drawMatchesKnn(

src1, kp1, model, kp2, good, None,

flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS

)

cv_show('matched', matched_image)

  • 作用 :生成一张拼接图像,左边是 src1,右边是 model,并在两者之间用线条连接匹配点对。

  • 重要函数cv2.drawMatchesKnn(img1, keypoints1, img2, keypoints2, matches1to2, outImg, ...)

    • 参数

      • img1:第一张图像。

      • keypoints1:第一张图像的关键点。

      • img2:第二张图像。

      • keypoints2:第二张图像的关键点。

      • matches1to2必须是一个列表的列表 ,每个子列表包含一个或多个 DMatch 对象(通常用于 kNN 的 k>1 情形)。若只绘制单一匹配,应传入 [[m1], [m2], ...] 的形式。

      • outImg:输出图像,可传入 None 让函数自动创建。

      • flags:绘制标志,常用有:

        • cv2.DRAW_MATCHES_FLAGS_DEFAULT(默认)

        • cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS(绘制关键点圆和方向)

        • cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS(不绘制未匹配到的点)

    • 返回值:绘制后的彩色图像。


重要代码单独总结

代码片段 作用 关键参数说明
sift = cv2.SIFT_create() 创建 SIFT 对象 可选参数:nfeatures(保留特征点数量)、contrastThreshold(对比度阈值)等。
sift.detectAndCompute(img, mask) 检测关键点并计算描述子 img:输入图像,mask:感兴趣区域掩膜;返回 kpKeyPoint 列表)和 desN×128 数组)。
cv2.FlannBasedMatcher(index_params, search_params) 创建 FLANN 匹配器 index_params:索引参数,SIFT 常用 dict(algorithm=1, trees=5)search_params:搜索参数,常用 dict(checks=50)
flann.knnMatch(des1, des2, k=2) k 近邻匹配 des1des2 为描述子矩阵,k=2 返回两个最近邻。返回 List[List[DMatch]]
cv2.drawMatchesKnn(...) 绘制匹配连线 关键参数已在上文详述,注意 matches 必须是列表的列表。

相关推荐
richard_first42 分钟前
第8章 Feed Forward Network(FFN 网络)
网络·人工智能·深度学习·机器学习·transformer
Wang's Blog43 分钟前
Vibe Coding一人即团队系列2: AI驱动的全链路产品开发实践
人工智能
飞哥数智坊43 分钟前
豆包工作上线:功能超多,但我更关注这3个地方
人工智能
Csvn43 分钟前
第 4 章 提示工程
人工智能·aigc
小白的成长路程43 分钟前
AI搜索里,品牌被悄悄降级了
人工智能·geo
这就是佬们吗1 小时前
AI 的记忆进化史:从金鱼记忆到学会做梦
人工智能·python·embedding
智塑未来1 小时前
金融AI应用解决方案选型先看哪三项
人工智能·金融
Csvn1 小时前
第 3 章 上下文工程
人工智能·aigc
智恒百亿1 小时前
AI服务器涨价15%背后:5090八卡智算服务器的选型与成本分析
大数据·服务器·人工智能·github