计算机视觉(opencv)实战二十一——基于 SIFT 和 FLANN 的指纹图像匹配与认证


基于 SIFT 和 FLANN 的指纹图像匹配与认证

指纹识别是生物特征识别中的经典应用,其核心任务是从指纹图像中提取稳定的特征点,并将这些特征与模板指纹进行匹配,从而判断两幅指纹是否属于同一人。本文使用 SIFT 特征点检测 和 FLANN 匹配器 实现简单的指纹认证,并逐行解析代码。


一、整体思路

  1. 读取指纹图像:加载待验证指纹和模板指纹。

  2. 提取特征点:使用 SIFT 算法检测关键点并计算描述符。

  3. 特征点匹配:通过 FLANN 匹配器对两幅图像的描述符进行匹配。

  4. 筛选匹配结果:使用 Lowe's 比率测试剔除错误匹配。

  5. 统计匹配点数量:根据匹配数量判断认证是否通过。

  6. 可视化结果:在指纹图像上标注匹配到的关键点。


二、核心代码解析

复制代码
import cv2
import numpy as np

我们引入了 OpenCV 和 NumPy,分别用于图像处理和矩阵运算。


1. 图像显示函数

复制代码
def cv_show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)

简单的封装,用于显示图像并等待用户按键关闭。


2. 特征提取与匹配函数

复制代码
def verification(src, model):
    # 创建SIFT特征提取器
    sift = cv2.SIFT_create()
    # 检测关键点和计算描述符(特征向量) 源图像
    kp1, des1 = sift.detectAndCompute(src, None)  # 第二个参数:掩膜
    # for k in kp1:
    #     print(k.pt)
    # 检测关键点和计算描述符 模板图像
    kp2, des2 = sift.detectAndCompute(model, None)
    # 创建FLANN匹配器
    flann = cv2.FlannBasedMatcher()
    # 使用k近邻匹配(des1中的每个描述符与des2中的最近两个描述符进行匹配)
    matches = flann.knnMatch(des1, des2, k=2)
# distance: 匹配的特征点描述符的欧式距离,数值越小也就说明俩个特征点越相近。表示查询图像(待匹配的 "目标图")中特征点的索引。
# imgIdx表示匹配对应的图像索引。当进行多图之间的特征匹配(比如从多个模板图中找与目标图的匹配)时,用这个索引标记当前匹配来自哪一张图像(比如第 0 张、第 1 张模板图)。
# queryIdx: 测试图像的特征点描述符的下标(第几个特征点描述符),同时也是描述符对应特征点的下标。表示查询图像(待匹配的 "目标图")中特征点的索引。
# trainIdx: 样本图像的特征点描述符下标,同时也是描述符对应特征点的下标。表示训练图像(用于匹配的 "模板图")中特征点的索引。
    # 进行比较筛选
    ok = []
    for m, n in matches:
        # 根据Lowe's比率测试,选择最佳匹配
        if m.distance < 0.4 * n.distance:
            ok.append((m,n))

    # 统计通过筛选的匹配数量
    num = len(ok)
    if num >= 10:#500
        result = "认证通过"
    else:
        result = "认证失败"

    ok_list = np.array(ok)
    if len(ok_list.shape) == 2:
        f = ok_list[:,0]
        m = ok_list[:,1]
    else:
        f = []
        m = []

    f_p = [kp1[a.queryIdx].pt for a in f]
    m_p = [kp2[a.trainIdx].pt for a in f]

    return result, f_p, m_p
复制代码
# distance: 匹配的特征点描述符的欧式距离,数值越小也就说明俩个特征点越相近。表示查询图像(待匹配的 “目标图”)中特征点的索引。
# imgIdx表示匹配对应的图像索引。当进行多图之间的特征匹配(比如从多个模板图中找与目标图的匹配)时,用这个索引标记当前匹配来自哪一张图像(比如第 0 张、第 1 张模板图)。
# queryIdx: 测试图像的特征点描述符的下标(第几个特征点描述符),同时也是描述符对应特征点的下标。表示查询图像(待匹配的 “目标图”)中特征点的索引。
# trainIdx: 样本图像的特征点描述符下标,同时也是描述符对应特征点的下标。表示训练图像(用于匹配的 “模板图”)中特征点的索引。

这里使用 SIFT (Scale-Invariant Feature Transform) 算法提取关键点和描述符。

  • kp1 / kp2:关键点列表,每个关键点包含位置、尺度、方向等信息。

  • des1 / des2:描述符数组,通常是 128 维向量,用于表示关键点的局部特征。

3. FLANN 匹配器

FLANN (Fast Library for Approximate Nearest Neighbors) 是一种快速近似最近邻搜索库,非常适合处理大规模高维特征匹配。

这里使用 k=2 的 KNN 匹配,为每个描述符找出两个最近的匹配点,方便后续做比率测试。

4. Lowe's 比率测试

比率测试的思想是:如果最近邻距离远小于次近邻距离,说明匹配更可靠。

这里阈值设置为 0.4(可以根据实际情况调整,0.7 是常见的经验值)。

5. 匹配数量判断与坐标提取

当匹配点数量大于一定阈值(此处为 10),判定认证成功,否则失败。

接着提取匹配点的坐标,方便后续可视化:


复制代码
if __name__ == "__main__":
    finger1 = cv2.imread("finger1.BMP")
    cv_show('finger1', finger1)
    finger2 = cv2.imread("finger2.BMP")
    cv_show('finger2', finger2)
    model = cv2.imread("finger3.BMP")
    cv_show('model', model)
    result1,f1,m1 = verification(finger1, model)
    result2,f2,m2 = verification(finger2, model)

    for i in f1:
        finger1 = cv2.circle(finger1, (int(i[0]), int(i[1])), 3, (0, 0, 255), -1)
    for i in m1:
        model = cv2.circle(model, (int(i[0]), int(i[1])), 3, (0, 0, 255), -1)
    cv_show('finger1', finger1)
    cv_show('model', model)
    for i in f2:
        finger2 = cv2.circle(finger2, (int(i[0]), int(i[1])), 3, (0, 0, 255), -1)
    for i in m2:
        model = cv2.circle(model, (int(i[0]), int(i[1])), 3, (0, 0, 255), -1)
    cv_show('finger2', finger2)
    cv_show('model', model)


    print("finger1验证结果为:", result1)
    print("finger2验证结果为:", result2)

6. 主程序:加载图像与可视化

分别读取两幅待验证指纹和一幅模板指纹,并显示。

7. 验证与绘制关键点

将匹配到的关键点画在原图上(红色圆点),便于直观观察匹配效果。

8. 输出结果

输出指纹认证是否通过。


三、关键概念解析

  • SIFT 特征点:具有尺度不变性和旋转不变性,适合处理指纹这种局部纹理特征丰富的图像。

  • FLANN 匹配器:比暴力匹配更高效,适合大规模匹配任务。

  • Lowe's 比率测试:有效剔除伪匹配,提高准确率。

  • 匹配阈值:匹配点数阈值是影响认证结果的关键参数,需根据数据调整。


四、运行结果与分析

运行程序后,可以直观看到匹配到的关键点。如果匹配数量较多,则输出"认证通过",否则输出"认证失败"。这种方法适用于简单场景的指纹比对,但在实际应用中还需要:

  • 对图像预处理(去噪、增强对比度)

  • 使用更多鲁棒特征(ORB、深度学习特征)

  • 加入 RANSAC 剔除错误匹配

相关推荐
程序员于老七几秒前
漫话大模型:7 家中国公司被点名「蒸馏」,他们到底偷走了什么?
人工智能
YOLO数据集集合1 分钟前
风机叶片表面损伤检测数据集 | 风机叶片 表面损伤 污渍检测 无人机巡检 风电运维9119期
运维·人工智能·计算机视觉·目标跟踪·无人机·智慧城市·电力巡检
程序员于老七3 分钟前
漫话大模型:反 LLM 新物种:0.1 秒出结果、零幻觉的 Jev 是什么
人工智能
tellmewhoisi4 分钟前
机器学习:集成学习4(XGBoost前置知识泰勒展开式4)
人工智能·机器学习·集成学习
youdexiang21 分钟前
会议录音APP实时转文字有哪些关键技术
人工智能
hqyjzsb25 分钟前
法律 Prompt 干货:搭建合同审查提示词要包含哪些要素
开发语言·人工智能·python·职场和发展·数据分析·prompt·业界资讯
skywalk816326 分钟前
lightplugin项目已经复刻完成了很多插件,还有需要复刻的插件吗? 再复刻12个,另外解决复刻的插件的宽度和广度!
人工智能·调试
搞科研的小刘选手37 分钟前
【IOS 出版 | EI、Scopus检索 | 成都举办】第六届大数据、人工智能与风险管理国际学术会议(ICBAR 2026)
大数据·人工智能·学术会议·成都·会议推荐
胡家伟++39 分钟前
当 AI 自主思维链撞上果蝇全脑仿真(一)
人工智能
用户58333398166843 分钟前
电商RPA避坑实战:抖音、拼多多、天猫商品上架的风控、重试与限流设计
人工智能