计算机视觉opencv之指纹识别补充&图片拼接&思考

一、指纹识别

1.上篇博客中讲到指纹识别以及对匹配上的点标出,这次我们实现让匹配对应的点连接起来,从连接的线上反应匹配的程度

这里和上篇博客中代码一样,只不过在函数中稍改动了,添加了src_matches=[]这个变量,以及后面对其的使用

python 复制代码
import cv2
def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
def verification(src,model,show_matchs=False):
    sift=cv2.SIFT_create()
    kp1,des1=sift.detectAndCompute(src,None)
    kp2,des2=sift.detectAndCompute(model,None)
    flann=cv2.FlannBasedMatcher()
    matches=flann.knnMatch(des1,des2,k=2)
    ok=[]
    good_matches=[]
    src_matches=[]
    model_matches=[]
    for m,n in matches:
        if m.distance<0.4*n.distance:
            ok.append((m,n))
            good_matches.append(m)
            src_matches.append(kp1[m.queryIdx].pt)
            model_matches.append(kp2[m.trainIdx].pt)
    num=len(ok)
    if num >=50:
        result='认证通过'
    else:
        result='认证失败'
    if show_matchs and len(src_matches)>0:
        src_with_matches=src.copy()
        model_with_matches=model.copy()
        for (x,y) in src_matches[:100]:
            cv2.circle(src_with_matches,(int(x),int(y)),3,(0,0,255),-1)
        for (x,y) in model_matches[:100]:
            cv2.circle(model_with_matches,(int(x),int(y)),3,(0,0,255),-1)
        cv2.imshow('src_matches',src_with_matches)
        cv2.imshow('model_matches',model_with_matches)
        cv2.waitKey(0)
        match_img=cv2.drawMatches(src,kp1,model,kp2,good_matches[:100],None,flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
        cv2.imshow('pipei',match_img)
        cv2.waitKey(0)#1
    return  result,num,src_matches,model_matches

if __name__=='__main__':
    src1=cv2.imread('zhiwen1.bmp')
    src2=cv2.imread('zhiwen2.bmp')
    model = cv2.imread('zhiwen_model.bmp')
    cv2.imshow('src1',src1)
    cv2.imshow('src2',src2)
    cv2.imshow('model',model)
    cv2.waitKey(0)
    reselt1,num1,src1_matches,model1_matches=verification(src1,model,show_matchs=True)
    reselt2,num2,src2_matches,model2_matches=verification(src2,model,show_matchs=True)
    print('src1的结果为:',reselt1,'匹配点数:{}'.format(num1))
    print('src2的结果为:',reselt2,'匹配点数:{}'.format(num2))

2.指纹识别并输出对应人名

这段和之前指纹识别的是一样的

python 复制代码
import os
import cv2

# 计算两个指纹间匹配点的个数
def getNum(src, model):
    img1 = cv2.imread(src)
    img2 = cv2.imread(model)
    sift = cv2.SIFT_create()  # orb_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)
    num = len(ok)
    return num

如果要对应上人的姓名这里我们新增两个函数,一是在这这个函数里面进行指纹匹配,获取匹配成功这个指纹图片的编号,二是创建字典每个编号对应一个人

python 复制代码
# 获取指纹编号
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 < 200:  # src图片不一定是库里面人的指纹
        ID = 9999
    return ID
python 复制代码
# 根据指纹编号,获取对应姓名
def getName(ID):
    nameID = {0: '张三', 1: '李四', 2: '王五', 3: '赵六', 4: '朱老七', 5: '钱八', 6: '曹九', 7: '王二麻子', 8: 'andy', 9: 'Anna', 9999: '没找到'}
    name = nameID.get(int(ID))
    return name

指纹识别,和哪个编号的指纹对应上就调用函数对应的个人名字。

python 复制代码
# 主函数
if __name__ == "__main__":
    src = "src.bmp"
    database = "database"
    ID = getID(src, database)
    name = getName(ID)
    print("识别结果为:", name)

二、图片拼接

目的让这两张图无缝衔接成一张图片

做准备:

python 复制代码
import cv2
import numpy as np
import sys

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

def detectAndDescribe(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 将彩色图片转换成灰度图
    sift = cv2.SIFT_create()  # 建立SIFT生成器
    # 检测SIFT特征点,并计算描述符,第二个参数为掩膜
    (kps, des) = sift.detectAndCompute(gray, None)
    # 将结果转换成NumPy数组
    kps_float = np.float32([kpc.pt for kpc in kps])
    # kpc 包含两个值,分别是关键点在图像中的 x 和 y 坐标。这些坐标通常是浮点数,可以精确地描述关键点在图像中的位置。
    return (kps, kps_float, des)  # 返回特征点集,及对应的描述特征
python 复制代码
'''读取拼接图片'''
imageA = cv2.imread("zuo.jpg")
cv_show('imageA', imageA)
imageB = cv2.imread("you.jpg")
cv_show('imageB', imageB)
python 复制代码
'''计算图片特征点及描述符'''
(kpsA, kps_floatA, desA) = detectAndDescribe(imageA)
(kpsB, kps_floatB, desB) = detectAndDescribe(imageB)
python 复制代码
'''建立匹配器BFMatcher,在匹配大图训练集合时使用FlannBasedMatcher速度更快。'''
matcher = cv2.BFMatcher()
rawMatches = matcher.knnMatch(desB, desA, k=2)
good = []
matches = []
for m in rawMatches:
    # 当最近距离跟次近距离的比值小于0.65时,保留此匹配对
    if len(m) == 2 and m[0].distance < 0.65 * m[1].distance:
        good.append(m)
        # 存储两个点在featuresA、featuresB中的索引值
        matches.append((m[0].queryIdx, m[0].trainIdx))
print(len(good))
print(matches)
vis = cv2.drawMatchesKnn(imageB, kpsB, imageA, kpsA, good, outImg=None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv_show("Keypoint Matches", vis)

计算透视变换矩阵

findHomography(srcPoints, dstPoints, method=None, ransacReprojThreshold=None, mask=None, maxIters=None, confidence=None)

  • 计算视角变换矩阵,透视变换函数,与cv2.getPerspectiveTransform()的区别在于可多个数据点变换
  • 参数srcPoints:图片A的匹配点坐标
  • 参数dstPoints:图片B的匹配点坐标
  • 参数method:计算变换矩阵的方法。
  • ransacReprojThreshold: 最大允许重投影错误阈值。该参数只有在method参数为RANSAC与RHO的时启用,默认为3

findHomography的四种方法:

  • H = cv2.findHomography(ptsA, ptsB, 0),0 - 使用所有匹配点计算变换矩阵,最小二乘。
  • H = cv2.findHomography(ptsA, ptsB, cv2.RANSAC, 5.0),RANSAC - 随机采样少量点计算模型,测试其他点是否符合。
  • H = cv2.findHomography(ptsA, ptsB, cv2.LMEDS), LMEDS - 最小化误差的中位数,而不是平均值
  • H = cv2.findHomography(ptsA, ptsB, cv2.RHO), RHO - RANSAC的改进版,使用更智能的采样策略

findHomography返回值解释:

  • 返回值:中值为变换矩阵,mask是掩模标志,指示哪些点对应内点,哪些是外点。
  • 内点:指那些与估计的模型非常接近的数据点,通常是正确匹配或真实数据。
  • 外点:指那些与估计的模型不接近的数据点,通常是错误匹配或噪声数据。
python 复制代码
'''透视变换'''
if len(matches) > 4:  # 当筛选后的匹配对大于4时,计算视角变换矩阵。
    # 获取匹配对的点坐标
    ptsB = np.float32([kps_floatB[i] for (i, _) in matches])  # matches是通过阈值筛选之后的特征点对象
    ptsA = np.float32([kps_floatA[i] for (_, i) in matches])  # kps_floatA是图片A中的全部特征点坐标
    H, mask = cv2.findHomography(ptsB, ptsA, cv2.RANSAC, 10)
else:
    print('图片未找到4个以上的匹配点')
    sys.exit()

result = cv2.warpPerspective(imageB, H, (imageB.shape[1] + imageA.shape[1], imageB.shape[0]))
cv_show('resultB', result)
# 将图片A传入resultB后显示
result[0:imageA.shape[0], 0:imageA.shape[1]] = imageA
cv_show('result', result)
cv2.imwrite('pingjie.jpg', result)

展示zuo和you,并对匹配上的特征进行连线,这点和指纹识别是一样。

展示you图经过透视之后的变化以及最后拼接成功的结果。我们能看出还是有拼接痕迹的,就比如纸箱处。

三、思考

上面我们图像拼接是对b图进行透视转化,把透视的b图拼接在a图的右侧,思考我们能不能对图a进行透视,把a图拼接在b图的左侧。得到下面这种结果的拼接。

相关推荐
油泼辣子多加2 小时前
【信创】华为昇腾大模型训练
人工智能·机器学习·数据挖掘
marteker2 小时前
熊猫快餐以手工制作的动画短片庆祝农历新年
人工智能
彬鸿科技2 小时前
彬鸿科技bhSDR Studio/Matlab总览讲解
人工智能·matlab·软件无线电·sdr
敢敢のwings2 小时前
NVIDIA Alpamayo 完整使用教程与介绍
人工智能
zhangfeng11332 小时前
VS Code,trae-cn qcoder cursor krio 装了 Markdown 插件却打不开预览
人工智能·python
一个王二不小2 小时前
A-Stock Trading:基于 AI 多 Agent 协同辩论的 A 股量化分析系统【不构成任何投资建议】
人工智能·trading agent
会周易的程序员2 小时前
# cv coach从视频到模型:一站式计算机视觉数据预处理工具全解析
人工智能·计算机视觉·音视频
火云洞红孩儿2 小时前
使用Python开发游戏角色识别!(游戏辅助工具开发入门)
人工智能·python·游戏
audyxiao0012 小时前
会议热点扫描|机器学习顶级会议ICML 2025的研究热点与最新趋势分析
人工智能·机器学习·icml·会议热点