opencv指纹匹配

一、指纹匹配概述

指纹匹配是指通过比较两个指纹图像的特征,判断它们是否来自同一手指的过程。在实际应用中,如门禁系统、考勤系统、刑侦鉴定等领域,指纹匹配技术发挥着重要作用。OpenCV 作为强大的计算机视觉库,为指纹匹配提供了丰富的工具和方法,一般可借助特征提取、特征匹配等步骤实现指纹匹配。

二、指纹匹配的基本原理

指纹匹配的核心目标是判断两个指纹图像是否来自同一手指。其基本原理是通过提取指纹图像的特征,然后比较这些特征之间的相似度。指纹的特征主要包括细节点(如断点、分叉点等)和纹理信息。在匹配过程中,首先需要对指纹图像进行预处理,以提高特征提取的准确性;然后提取指纹的特征点和描述符;最后通过比较描述符之间的距离来判断指纹是否匹配。

三、代码实现

1.导入库与定义显示函数

python 复制代码
import cv2


def cv_show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)

导入库:import cv2 导入了 OpenCV 库,它是一个强大的计算机视觉库,提供了众多图像处理和计算机视觉相关的功能。

定义显示函数:cv_show 函数用于显示图像,它接受两个参数,name 是显示窗口的名称,img 是要显示的图像。cv2.imshow 用于在指定名称的窗口中显示图像,cv2.waitKey(0) 表示无限等待用户按下任意键,这样可以让图像窗口一直显示,直到用户有操作。

2.定义 verification 函数(特征提取部分)

python 复制代码
def verification(src, model):
    # 创建SIFT特征提取器
    sift = cv2.SIFT_create()

    # 检测关键点和计算描述符(特征向量)的原图像
    kp1, des1 = sift.detectAndCompute(src, None)  # 第二个参数是掩膜
    # 检测关键点和计算描述符  模板图像
    kp2, des2 = sift.detectAndCompute(model, None)

创建 SIFT 特征提取器:cv2.SIFT_create() 创建了一个 SIFT(尺度不变特征变换)特征提取器对象。SIFT 算法可以在图像中检测出关键点,并计算这些关键点的描述符,这些描述符对图像的尺度、旋转和光照变化具有较好的不变性。

检测关键点和计算描述符:sift.detectAndCompute 函数用于在图像中检测关键点并计算其描述符。src 是原图像,model 是模板图像,None 表示不使用掩膜。函数返回两个值,kp 是检测到的关键点列表,des 是对应的描述符矩阵。

3.定义 verification 函数(特征匹配与筛选部分)

python 复制代码
    # 创建Flann匹配器
    flann = cv2.FlannBasedMatcher()

    # 使用K近邻匹配(des1中的每个描述符周围距离它最近的des2的点,K值就是设置点的个数
    matches = flann.knnMatch(des1, des2, k=2)

    # 进行比较筛选
    ok = []
    for m, n in matches:
        if m.distance < 0.8 * n.distance:
            ok.append(m)

创建 Flann 匹配器:cv2.FlannBasedMatcher() 创建了一个基于快速最近邻搜索库(FLANN)的匹配器对象。FLANN 可以快速地在高维空间中找到最近邻点,适用于大规模特征匹配。

K 近邻匹配:flann.knnMatch 函数用于进行 K 近邻匹配,k=2 表示为 des1 中的每个描述符找到 des2 中距离最近的两个描述符。返回的 matches 是一个列表,每个元素是一个包含两个 DMatch 对象的列表,分别表示最近邻和次近邻。

筛选匹配结果:通过比较最近邻和次近邻的距离,如果最近邻的距离小于次近邻距离的 0.8 倍,则认为这个匹配是可靠的,将其添加到 ok 列表中。

4.定义 verification 函数(提取匹配点坐标与判断结果部分)

python 复制代码
    num = len(ok)
    query_idx = []
    train_idx = []
    for match in ok[:num]:
        query_idx.append(match.queryIdx)
        train_idx.append(match.trainIdx)
    pt1_1 = []
    pt1_2 = []
    pt2_1 = []
    pt2_2 = []
    for m in query_idx:
        pt1_1.append(int(kp1[m].pt[0]))
        pt1_2.append(int(kp1[m].pt[1]))
    for n in train_idx:
        pt2_1.append(int(kp2[n].pt[0]))
        pt2_2.append(int(kp2[n].pt[1]))
    if num >= 500:
        result = '认证通过'
    else:
        result = '认证失败'
    return result, pt1_1, pt1_2, pt2_1, pt2_2

提取匹配点索引:query_idx 和 train_idx 分别存储了原图像和模板图像中匹配点的索引。

提取匹配点坐标:根据匹配点的索引,从关键点列表中提取出匹配点的坐标,并分别存储在 pt1_1、pt1_2、pt2_1 和 pt2_2 中。

判断认证结果:如果可靠匹配点的数量 num 大于等于 500,则认为认证通过,否则认证失败。

返回结果:函数返回认证结果和匹配点的坐标。

5.主程序(读取图像与验证部分)

python 复制代码
if __name__ == '__main__':
    src1 = cv2.imread('zw1.bmp')
    cv_show('zw1', src1)
    src2 = cv2.imread('zw2.bmp')
    cv_show('zw2', src2)
    model = cv2.imread('zwmatch.bmp')
    cv_show('model', model)
    mm = verification(src1, model)
    result1 = verification(src1, model)[0]
    result2 = verification(src2, model)[0]
    pt1_1 = mm[1]
    pt1_2 = mm[2]
    pt2_1 = mm[3]
    pt2_2 = mm[4]

读取图像:使用 cv2.imread 函数读取三张图像,分别是 zw1.bmp、zw2.bmp 和 zwmatch.bmp,并使用 cv_show 函数显示这些图像。

进行验证:调用 verification 函数对 src1 和 src2 分别与 model 进行验证,得到认证结果 result1 和 result2,并提取出 src1 与 model 匹配点的坐标。

6.主程序(绘制匹配点与连线部分)

python 复制代码
    for x1, y1 in zip(pt1_1, pt1_2):
        cv2.circle(src1, (x1, y1), 3, (0, 0, 255), -1)
    for m1, n1 in zip(pt2_1, pt2_2):
        cv2.circle(model, (m1, n1), 3, (0, 0, 255), -1)

    # 绘制连线
    h1, w1 = src1.shape[:2]
    h2, w2 = model.shape[:2]
    vis = cv2.hconcat([src1, model])
    for i in range(len(pt1_1)):
        pt1 = (pt1_1[i], pt1_2[i])
        pt2 = (pt2_1[i] + w1, pt2_2[i])
        cv2.line(vis, pt1, pt2, (0, 255, 0), 1)

    cv_show('src1_w', src1)
    cv_show('model_w', model)
    cv_show('matched', vis)

    print('src1验证结果为:', result1)
    print('src2验证结果为:', result2)

绘制匹配点:使用 cv2.circle 函数在 src1 和 model 图像上绘制匹配点,颜色为红色。

绘制连线:将 src1 和 model 图像水平拼接成 vis 图像,然后使用 cv2.line 函数在 vis 图像上绘制匹配点之间的连线,颜色为绿色。

显示结果:使用 cv_show 函数显示绘制了匹配点和连线的图像,并打印出 src1 和 src2 的验证结果。

完整代码:

python 复制代码
import cv2


def cv_show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)


def verification(src, model):
    # 创建SIFT特征提取器
    sift = cv2.SIFT_create()

    # 检测关键点和计算描述符(特征向量)的原图像
    kp1, des1 = sift.detectAndCompute(src, None)  # 第二个参数是掩膜
    # 检测关键点和计算描述符  模板图像
    kp2, des2 = sift.detectAndCompute(model, None)

    # 创建Flann匹配器
    flann = cv2.FlannBasedMatcher()

    # 使用K近邻匹配(des1中的每个描述符周围距离它最近的des2的点,K值就是设置点的个数
    matches = flann.knnMatch(des1, des2, k=2)

    # match的参数:
    # distance:使用欧式距离计算距离
    # queryIdx:
    # trainIdx:

    # 进行比较筛选
    ok = []
    for m, n in matches:
        if m.distance < 0.8 * n.distance:
            ok.append(m)

    num = len(ok)
    query_idx = []
    train_idx = []
    for match in ok[:num]:
        query_idx.append(match.queryIdx)
        train_idx.append(match.trainIdx)
    pt1_1 = []
    pt1_2 = []
    pt2_1 = []
    pt2_2 = []
    for m in query_idx:
        pt1_1.append(int(kp1[m].pt[0]))
        pt1_2.append(int(kp1[m].pt[1]))
    for n in train_idx:
        pt2_1.append(int(kp2[n].pt[0]))
        pt2_2.append(int(kp2[n].pt[1]))
    if num >= 500:
        result = '认证通过'
    else:
        result = '认证失败'
    return result, pt1_1, pt1_2, pt2_1, pt2_2


if __name__ == '__main__':
    src1 = cv2.imread('zw1.bmp')
    cv_show('zw1', src1)
    src2 = cv2.imread('zw2.bmp')
    cv_show('zw2', src2)
    model = cv2.imread('zwmatch.bmp')
    cv_show('model', model)
    mm = verification(src1, model)
    result1 = verification(src1, model)[0]
    result2 = verification(src2, model)[0]
    pt1_1 = mm[1]
    pt1_2 = mm[2]
    pt2_1 = mm[3]
    pt2_2 = mm[4]
    for x1, y1 in zip(pt1_1, pt1_2):
        cv2.circle(src1, (x1, y1), 3, (0, 0, 255), -1)
    for m1, n1 in zip(pt2_1, pt2_2):
        cv2.circle(model, (m1, n1), 3, (0, 0, 255), -1)

    # 绘制连线
    h1, w1 = src1.shape[:2]
    h2, w2 = model.shape[:2]
    vis = cv2.hconcat([src1, model])
    for i in range(len(pt1_1)):
        pt1 = (pt1_1[i], pt1_2[i])
        pt2 = (pt2_1[i] + w1, pt2_2[i])
        cv2.line(vis, pt1, pt2, (0, 255, 0), 1)

    cv_show('src1_w', src1)
    cv_show('model_w', model)
    cv_show('matched', vis)

    print('src1验证结果为:', result1)
    print('src2验证结果为:', result2)

运行结果:

相关推荐
磊叔的技术博客几秒前
A2A 与 MCP:智能体协作的新纪元与AI工程化的思考
人工智能·开源·mcp
小爷毛毛_卓寿杰5 分钟前
【Dify(v1.2) 核心源码深入解析】Agent 模块
人工智能·后端·python
北京青翼科技36 分钟前
【PCIE736-0】基于 PCIE X16 总线架构的 4 路 QSFP28 100G 光纤通道处理平台
图像处理·人工智能·fpga开发·信号处理
IT古董1 小时前
【漫话机器学习系列】206.稀疏性(Sparsity)
人工智能
AI小码1 小时前
期待的 A2A 和 MCP 的对比,谷歌与Anthropic联手打造的AI协作新时代,你准备好了吗?
人工智能·mcp
视觉AI1 小时前
PyTorch 模型转换为 TensorRT 引擎的通用方法
人工智能·pytorch·python
风筝超冷1 小时前
面试篇 - 位置编码
人工智能·深度学习
pen-ai1 小时前
【NLP】 21. Transformer整体流程概述 Encoder 与 Decoder架构对比
人工智能·自然语言处理·transformer
蹦蹦跳跳真可爱5891 小时前
Python----机器学习(基于PyTorch的垃圾邮件逻辑回归)
人工智能·pytorch·python·机器学习·逻辑回归
人工干智能1 小时前
科普:如何通过ROC曲线,确定二分类的“理论阈值”
大数据·人工智能·分类