目录

一.指纹识别案例

1.计算两个指纹之间的匹配点个数

1.特征提取:

2.匹配原则

3.匹配成功依据:

2.获取指纹编号

3.根据指纹编号获取对应姓名

4.调用各方法

二.在验证图和模板图上画出对应的关键点


一.指纹识别案例

目标:捕捉待识别指纹与指纹库(database)中所有指纹图片的相似度,找出匹配度最高的指纹。

待识别指纹src.BMP:

关键实现流程与技术要点:

  • 文件遍历: 使用 os.listdir() 遍历指纹库文件夹内的所有指纹图片文件(如 .bmp 格式)。
  • 路径构建: 利用 os.path.join() 将文件夹路径与单个文件名组合,生成可被程序读取的完整图像路径。
  • SIFT特征提取与匹配: 类似于指纹验证,使用 cv2.SIFT_create() 提取待识别指纹和每一张库图的特征点,并利用 FLANN 进行特征匹配。
  • 匹配阈值判断: 设置了匹配成功点的数量阈值。当两个图像之间匹配到的“共同点”总数大于或等于当前记录的最大值时,才会更新最大值和对应的指纹文件名。
  • 最终结果判定: 通过匹配成功的点数达到预设的最小阈值才能判定识别结果有效;若所有指纹的匹配点数均低于该阈值,则返回一个特殊ID(如“9999”)表示未找到匹配指纹。

1.计算两个指纹之间的匹配点个数

1.特征提取:

直接使用sift的方法detectAndCompute()分别返回验证图src和模板图model的关键点keypoint和关键点的描述符descripter,此过程可同时完成“Detect”与“Compute”。

2.匹配原则

匹配以k=2的方式进行,即对待匹配的描述符,寻找其在另一组描述符中最近邻和次近邻。

3.匹配成功依据:

只有当一个匹配的距离(d1)远远小于其对应的次近邻距离(d2)时,才认为该匹配是有效的。项目中设定的判据是d1 < d2 * 0.8。

最后返回匹配成功的关键点数量

'''------计算两个指纹之间的匹配点个数--------'''
def getNum(src, model):
    img1=cv2.imread(src)
    img2=cv2.imread(model)
    sift=cv2.SIFT_create()
    kp1,des1=sift.detectAndCompute(img1,None)
    kp2,des2=sift.detectAndCompute(img2,None)
    flann=cv2.FlannBasedMatcher()
    matches=flann.knnMatch(des1,des2,k=2)
    ok=[]
    for m,n in matches:
        if m.distance<0.8*n.distance:
            ok.append((m,n))
    num=len(ok)
    return num

2.获取指纹编号

'''------获取指纹编号--------'''
def getID(src, database):
    max=0
    for file in os.listdir(database):
        model=os.path.join(database,file)
        num=getNum(src,model)
        print("文件名:",file,"匹配点个数:",num)
        if num>max:
            max=num
            name=file
    ID=name[0]
    if max<100:#src不一定是库里面人的指纹
        ID=9999
    return int(ID)

利用os.listdir()遍历database中的所有指纹照片,再os.path.join()得到路径

调用上一步自定义的getNum()方法得到该图片与database中的图片匹配的关键点个数,并将与每个指纹照片的匹配点个数打印出来

通过if条件保存最大的匹配点个数和指纹文件名

最后返回文件名的索引[0]并转化为int型,方便后续字典取值

3.根据指纹编号获取对应姓名

def getName(ID):
    nameID={
        0:'张三',1:'李四',2:'王五',3:'赵六',4:'朱老七',5:'钱八',
        6:'曹久',7:'王林',8:'andy',9:'john',9999:'没找到'
    }
    return nameID.get(ID)

实际就是定义一个字典根据传进来的ID值来获取对应的姓名

4.调用各方法

if __name__=='__main__':
    src='src.BMP.bmp'
    database='database'
    ID=getID(src,database)
    name=getName(ID)
    print('识别结果为:',name)

二.在验证图和模板图上画出对应的关键点

我们只需要在计算匹配成功的关键点时做出改进即可

kp1_indexs和kp2_index2分别保存匹配成功的关键点索引

queryIdx可以返回匹配成功后验证图上对应的关键点索引

trainIdx可以返回匹配成功后模板图上对应的关键点索引

最后对这些索引遍历,利用索引来取出对应的关键点,pt属性可以返回该关键点对应的x,y坐标

cv.circle()在图上画出对应的远点,需传入圆心(x,y)即上面得到的关键点坐标和边界

def verification(src,model):
    sift=cv2.SIFT_create()
    kp1,des1=sift.detectAndCompute(src,None)
    kp2, des2 = sift.detectAndCompute(model, None)
    #创建FLANN匹配器
    flann=cv2.FlannBasedMatcher()
    matches=flann.knnMatch(des1,des2,k=2)

    ok=[]
    kp1_indexs = []
    kp2_indexs = []
    for m,n in matches:
        if m.distance<0.4*n.distance:
            ok.append((m,n))
            kp1_indexs.append(m.queryIdx)
            kp2_indexs.append(m.trainIdx)
    for index_des1 in kp1_indexs:
        (x,y)=kp1[index_des1].pt
        cv2.circle(src, (int(x),int(y)),3,(0,0,255),-1)
    for index_des2 in kp2_indexs:
        (x,y)=kp2[index_des2].pt
        cv2.circle(model, (int(x),int(y)),3,(0,0,255),-1)

完整代码:

import cv2
def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
def verification(src,model):
    sift=cv2.SIFT_create()
    kp1,des1=sift.detectAndCompute(src,None)
    kp2, des2 = sift.detectAndCompute(model, None)
    #创建FLANN匹配器
    flann=cv2.FlannBasedMatcher()
    matches=flann.knnMatch(des1,des2,k=2)

    ok=[]
    kp1_indexs = []
    kp2_indexs = []
    for m,n in matches:
        if m.distance<0.4*n.distance:
            ok.append((m,n))
            kp1_indexs.append(m.queryIdx)
            kp2_indexs.append(m.trainIdx)
    for index_des1 in kp1_indexs:
        (x,y)=kp1[index_des1].pt
        cv2.circle(src, (int(x),int(y)),3,(0,0,255),-1)
    for index_des2 in kp2_indexs:
        (x,y)=kp2[index_des2].pt
        cv2.circle(model, (int(x),int(y)),3,(0,0,255),-1)
if __name__=='__main__':
    src1=cv2.imread('src1.bmp')
    src2=cv2.imread('src2.bmp')
    model=cv2.imread('model.bmp')
    cv_show('src1',src1)
    cv_show('model',model)
    result1=verification(src1,model)

    cv_show('src1', src1)
    cv_show('model', model)

补充说明:

cv2.drawMatchesKnn(src1,kp1,model,kp2,ok,None,flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)函数可以画出验证图与模板图关键点的对应关系

matched_image=cv2.drawMatchesKnn(src1,kp1,model,kp2,ok,None,flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
cv_show('matched_image',matched_image)

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐