详细介绍指纹识别匹配

下面介绍在一个保存着很多指纹图片的文件夹中如何识别到一个已知的指纹图片

import os#主要用于文件管理的第三方库,由于我们需要打开文件夹中的图片所以需要用到
import cv2#图像处理必备的第三方库

def getNum(src, model):#定义了一个函数,函数里面有两个可选参数
    img1 = cv2.imread(src)#读取src的图片,并赋值给变量img1
    img2 = cv2.imread(model)#同上
    sift = cv2.SIFT_create()#用于创建一个 SIFT 对象,该对象可以用来检测图像中的关键点并计算其描述符。
    kp1, des1 = sift.detectAndCompute(img1, None)#可以理解为使用了sift对象中的一个方法,这个方法主要的作用是获取imag1中的一些特征,kp1(关键点):这是一个包含检测到的关键点的列表。每个关键点都是一个 cv2.KeyPoint 对象,包含位置(x, y)、尺度、方向等信息。des1(描述符):这是一个 numpy 数组,包含每个关键点的描述符。描述符是对关键点局部图像区域的特征描述,通常用于图像匹配
    kp2, des2 = sift.detectAndCompute(img2, None)
    flann = cv2.FlannBasedMatcher()#创建一个 flann的匹配器对象,该对象可以用于在两个描述符集合之间找到最相似的描述符。非常适合大数据集的快速匹配。
    matches = flann.knnMatch(des1, des2, k=2)#利用flann对象里面的knn.Match方法来匹配des1和des2之间的相似特征。这里的k值通常设置为2,意味着对于des1中的每个描述符,该函数会找到在des2中与它距离最近的两个描述符。
    ok = []#初始化一个空列表ok
    for m, n in matches:#这行代码开始一个循环,迭代matches列表中的每个元素。matches是由flann.knnMatch函数返回的,其中每个元素是一个包含两个DMatch对象的数组。m和n分别是数组中的第一个和第二个DMatch对象,分别代表距离查询描述符最近的两个匹配。
        if m.distance < 0.8 * n.distance:#这行代码执行比率测试。m.distance是查询描述符与m对象所代表的匹配描述符之间的距离,n.distance是与次近的匹配描述符之间的距离。如果最近匹配的距离是次近匹配距离的0.8倍或更少,那么我们认为这是一个好的匹配。这个0.8是一个经验值,可以根据具体应用进行调整。比率测试的目的是排除那些可能由于噪声或错误而产生的不可靠匹配。
            ok.append(m)#如果比率测试通过(即条件为真),则将m对象添加到ok列表中。ok列表用于存储所有被认为是好的匹配。
    num = len(ok)#在循环结束后,计算ok列表的长度,即通过比率测试的匹配对的数量,并将这个数量赋值给变量num。
    return num#最后,函数返回num,即好的匹配对的数量。

def getID(src, database):#这行定义了一个名为getID的函数,它接受两个参数:src(源图像的路径)和database(包含图像数据库的目录路径)
    max_matches = 0#初始化一个变量max_matches,用于存储迄今为止找到的最大匹配数。初始值设为0
    name = ""#初始化一个变量name,用于存储匹配度最高的图像文件名。初始为空字符串。
    for file in os.listdir(database):#这行开始一个循环,遍历database目录中的所有文件。os.listdir(database)返回目录中的文件列表。
        model = os.path.join(database, file)#对于每个文件名file,使用os.path.join构造完整的文件路径。model变量存储了数据库中每个图像的完整路径。
        num = getNum(src, model)#调用getNum函数,来获取src和model之间的匹配数,并将结果存储在num变量中。
        print("文件名:", file, '距离', num)#打印出文件名来获取不同指纹于模板之间的特征匹配数
        if num > max_matches:
            max_matches = num
            name = file#如果当前的匹配数num大于之前记录的最大匹配数max_matches,则更新max_matches为当前的匹配数num。更新name为当前的文件名。

    if max_matches < 100:
        ID = 9999#当匹配的特征数小于100时ID=999
    else:
        ID = int(name.split('.')[0]) #将name字符串分割成两部分(以点.为分隔符),取第一部分并转换为整数,假设文件名以ID数字开始。
    return ID

def getName(ID):#设置一个获取名字的函数
    nameID = {0: '张三', 1: '李四', 2: '王五', 3: '赵六', 4: '朱七', 5: '钱八', 6: '曹九', 7: '王二麻子', 8: 'andy', 9: 'Anna', 9999: '没找到'}#名单设置为一个字典,可根据键来获取名字
    name = nameID.get(int(ID))
    return name

if __name__ == '__main__':#这行代码检查当前脚本是否作为主程序运行。__name__是一个特殊的变量,在Python中,如果脚本被直接运行,__name__将被设置为'__main__'。如果脚本是被另一个脚本导入的,__name__将被设置为脚本的名字。这个条件语句确保了只有在直接运行脚本时,下面的代码才会执行。
    src = './src.BMP'#匹配的模板路径,来自当前py文件的文件夹下名为src的BMP文件
    database = './database'#匹配的文件夹
    ID = getID(src, database)#执行getID函数获取编号
    name = getName(ID)
    print('识别结果', name)#最后,使用print函数打印出识别结果。字符串'识别结果'后面跟着变量name,这意味着打印的输出将包括文本'识别结果'和由getName函数返回的名称。

首先模板如下图所示

我们需要在如下的文件中匹配到上面这个模板,并最后识别出是谁的指纹

我们来看一下执行的效果

该代码实现了一个功能即识别指纹的名称。具体各行代码的作用已经写在注释里

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值