【实战案例:基于特征匹配的指纹识别系统开发】

角点检测:角点(Corner)是图像中在两个或多个方向上灰度值发生剧烈变化的点。这些点通常包含丰富的信息,适用于特征匹配、目标跟踪、三维重建等任务。

python 复制代码
#------------------角点检测------------------------
#角点指图像中局部区域与周围区域有较大灰度变化的点或像素。
#角点指图像中局部区域与周围区域有较大灰度变化的点或像素。
# cornerHarris(img,blocksize,ksize, k[, dst[, borderType]])-> dst
# img:输入图像。
# blockSize:角点检测中要考虑的领域大小。
# ksize:Sobel求导中使用的窗大小。
# k: Harris角点检测方程中的自由参数,取值参数为[0.04,0.06]。
# dst:返回numpy.ndarray对象,大小和src相同,值越大,对应像素点是角的概率越高

img = cv2.imread('phone.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
dst  = cv2.cornerHarris(gray,4,3,0.04)

#标记检测到的角点
img[dst >0.05 * dst.max()]=[0,0,255]
# 这里通过对角点响应进行闽值处理,标记出检测到的角点。
# 0.05 * dst.max() 是一个值,大于这个值的像素点会被标记为红色。
cv2.imshow('img',img)
cv2.waitKey(0)

特征提取:是指从原始数据中抽取关键信息,将其转化为具有判别性的特征向量的过程。

目的

降低数据维度,保留最相关的信息,提高模型效率与泛化能力。

python 复制代码
#'''''''''''------------特征提取------------------
#检测图像中的关键点
#cv2.SIFT_create() #cv2.xfeatures2d.SIFT_create()#创建一个sift特征的提取对象
#sift.detect(img)在图像中查找关键点

phone = cv2.imread('phone.png')
phone_gray = cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY)
sift = cv2.SIFT_create()#sift对象
kp = sift.detect(phone_gray)

# kp.pt:关键点的(x,y)
# 坐标。
# kp.size:关键点的大小(尺度)
# kp.angle:关键点的方间。
# kp.response:关键点的响应值。
# kp.octave:关键点所在的金字塔层级。
#查找关键点
#drawKeypoints(image,keypoints, outImage, color=None, flags=None)
# image:原始图片
# keypoints:从原图中获得的关键点,这也是画图时所用到的数
# outputimage:输出图像,可以是原始图片,也可以是None
# color:颜色设置,通过修改(b,g,r)的值,更改画笔的颜色,b=蓝色,g=绿色,r=红色。
# flags:绘图功能的标识设置      绘制富有信息的关键点。

phone_sift =cv2.drawKeypoints(phone,kp,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow('phone',phone_sift)
cv2.waitKey(0)

# 使用sift.compute()计算关键点描述符,方便后期的特征匹配
kp,des  =sift.compute(phone,kp)
print(np.array(kp).shape,des.shape)
# 输出关键点的形状和描述待的形状。
# np.array(kp).shape表不关键点的数量和属性
# des.shape 表示描述符的数量和属性。

运行结果:

基于 SIFT 特征匹配的图像验证程序,核心用途是判断两张指纹(或其他)图像是否为同一目标

核心流程:

python 复制代码
读取待验证图像(src1/src2)和模板图像(model)→ 
用SIFT提取所有图像的特征点+特征描述符 → 
用FLANN匹配器做K近邻匹配(每个特征点找最近的2个匹配)→ 
通过Lowe's比率测试(0.8阈值)筛选有效匹配 → 
统计有效匹配数,≥500则判定"认证通过",否则"认证失败"
代码段 功能
cv_show(name,img) 封装图像显示函数(但注释了cv2.waitKey(0),是关键问题)
verification(src,model) 核心验证函数:完成特征提取、匹配、筛选、结果判定
sift = cv2.SIFT_create() 创建 SIFT 特征提取器(提取具有尺度 / 旋转不变性的特征点)
kp1,des1 = sift.detectAndCompute(...) 检测图像关键点 + 计算 128 维特征描述符(匹配的核心依据)
flann = cv2.FlannBasedMatcher() 创建 FLANN 匹配器(高效匹配特征描述符,比暴力匹配快)
matches = flann.knnMatch(des1,des2,k=2) K 近邻匹配:为 src 的每个特征点找 model 中最像的 2 个特征点
if m.distance<0.8*n.distance Lowe's 比率测试:过滤误匹配(最佳匹配远优于次佳匹配才有效)
num >=500 自定义阈值:匹配数足够多则判定为同一图像(指纹认证通过)
主函数 读取图像、调用验证函数、输出认证结果

代码:

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中的最近两个描述进行匹配)

    matches = flann.knnMatch(des1,des2,k=2)

#distance :匹配的特征点描述符的欧氏距离,数值越小也就说明俩个特征点越相近
#queryIdx: 测试图像的特征描述的下标(第几个特征点描述符),同时也是描述符对应特征点的下标。
#也是描述符对应特征点的下标。
#进行比较筛选
    ok = []
    for m,n in matches:
        #根据Lowe's比率测试,选择最佳匹配
        if m.distance<0.8*n.distance:
            ok.append((m,n))

    #统计通过筛选的匹配数量
    num = len(ok)
    if num >=500:
        result="认证通过"
    else:
        result="认证失败"
    return result
if __name__=="__main__":
    src1 = cv2.imread("src1.bmp")
    cv_show('src1',src1)
    src2 = cv2.imread("src2.bmp")
    cv_show('src2',src2)
    model = cv2.imread("model.bmp")
    cv_show('model',model)
    result1=verification(src1,model)
    result2=verification(src2,model)
    print("src1验证结果为:",result1)
    print("src2验证结果为:",result2)
    cv2.waitKey(0)
#

运行结果:

实现一个自动化的指纹识别系统:

计算指纹匹配个数

python 复制代码
import os
import cv2

'''=====================计算两个指纹间匹配点的个数================='''
def getNum(src,model):
    # 1. 读取指纹图像(src:待识别指纹路径,model:模板指纹路径)
    img1=cv2.imread(src)
    img2=cv2.imread(model)
    
    # 2. 创建SIFT特征提取器(尺度不变特征变换,抗旋转/尺度变化)
    sift=cv2.SIFT_create()
    
    # 3. 检测关键点+计算特征描述符(128维向量,匹配的核心依据)
    kp1,des1 = sift.detectAndCompute(img1,None)
    kp2,des2 = sift.detectAndCompute(img2,None)
    
    # 4. 创建FLANN匹配器(高效近邻匹配,适合大规模特征集)
    flann = cv2.FlannBasedMatcher()
    
    # 5. K近邻匹配(k=2:为每个特征点找最近的2个匹配)
    matches = flann.knnMatch(des1,des2,k=2)
    
    # 6. Lowe's比率测试筛选有效匹配(过滤误匹配)
    ok=[]
    for m,n in matches:
        # 核心逻辑:最佳匹配距离 < 0.8*次佳匹配距离,判定为有效匹配
        if m.distance<0.8*n.distance:
            ok.append(m)
    
    # 7. 返回有效匹配点数量
    num =len(ok)
    return num

遍历指纹库获取最优匹配 ID

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:
            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

"""================主函数==========================="""
if __name__=="__main__":
    src ="src.BMP"
    database ="database"
    ID = getID(src,database)
    name = getName(ID)
    print("识别结果为:",name)

运行结果:

指纹验证案例中,指纹1与模板图片匹配成功了,分别在两图内标出匹配成功点的坐标

要求:匹配结果最近的distance小于次接近distance的0.4

提示:cv2.circle(src, (x,y), 3, (0, 0, 255), -1),绘制实心圆

代码如下:

python 复制代码
import cv2
import numpy as np

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

def verification_and_mark(src, model, threshold=0.4):
    # -------------------------- 1. 特征提取(你学的SIFT) --------------------------
    sift = cv2.SIFT_create()
    # 检测关键点 + 计算描述符(源图src1、模板图model)
    kp1, des1 = sift.detectAndCompute(src, None)
    kp2, des2 = sift.detectAndCompute(model, None)

    # -------------------------- 2. FLANN匹配(你学的K近邻) --------------------------
    # 补充FLANN参数,避免匹配报错
    FLANN_INDEX_KDTREE = 1
    index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
    search_params = dict(checks=50)
    flann = cv2.FlannBasedMatcher(index_params, search_params)

    # K=2近邻匹配:每个特征找最近的2个匹配
    matches = flann.knnMatch(des1, des2, k=2)

    # -------------------------- 3. 按作业要求筛选匹配(0.4阈值) --------------------------
    good_matches = []
    src_points = []   # 存储src1上的匹配点坐标
    model_points = [] # 存储model上的匹配点坐标

    for m, n in matches:
        # 作业要求:最近距离 < 次近距离 × 0.4
        if m.distance < threshold * n.distance:
            good_matches.append(m)
            # 提取匹配点的坐标(kp.pt返回(x,y)浮点数,转整数用于画圆)
            src_x, src_y = kp1[m.queryIdx].pt
            model_x, model_y = kp2[m.trainIdx].pt
            src_points.append((int(src_x), int(src_y)))
            model_points.append((int(model_x), int(model_y)))

    # -------------------------- 4. 标注匹配点(作业要求的cv2.circle) --------------------------
    # 复制原图,避免修改原图像
    src_marked = src.copy()
    model_marked = model.copy()

    # 在src1上画红色实心圆
    for (x, y) in src_points:
        cv2.circle(src_marked, (x, y), 3, (0, 0, 255), -1)  # 3是圆半径,-1实心

    # 在model上画红色实心圆
    for (x, y) in model_points:
        cv2.circle(model_marked, (x, y), 3, (0, 0, 255), -1)

    # -------------------------- 5. 结果输出 --------------------------
    print(f"符合0.4阈值的有效匹配点数量:{len(good_matches)}")
    print("src1匹配点坐标(前10个示例):", src_points[:10])
    print("model匹配点坐标(前10个示例):", model_points[:10])

    # 显示标注后的图(对应你提供的效果图)
    cv_show("Marked src1", src_marked)
    cv_show("Marked model", model_marked)

    # 返回匹配结果(认证通过/失败,可自定义阈值)
    return "认证通过" if len(good_matches) >= 20 else "认证失败"


# -------------------------- 主函数(直接运行) --------------------------
if __name__ == "__main__":
    # 读取你的指纹图(替换为你的实际路径)
    src1 = cv2.imread("src1.bmp")
    model = cv2.imread("model.bmp")

    # 执行验证+标注(阈值设为作业要求的0.4)
    result = verification_and_mark(src1, model, threshold=0.4)
    print("src1验证结果为:", result)

运行结果:

相关推荐
crackpot·2 小时前
图像处理01
图像处理·人工智能
rebekk2 小时前
pytorch custom op的简单介绍
人工智能·pytorch·python
ZGi.ai2 小时前
生产级 Agent 编排 从单一 LLM 调用到多智能体工作流的工程设计
大数据·数据库·人工智能
木斯佳2 小时前
前端八股文面经大全:阿里云AI应用开发一面(2026-03-20)·面经深度解析
前端·人工智能·阿里云·ai·智能体·流式打印
龙腾AI白云2 小时前
如何利用大语言模型的能力进行实体关系抽取
人工智能·语言模型·自然语言处理·tornado
8Qi82 小时前
Hello-Agents阅读笔记--智能体经典范式构建--ReAct
人工智能·笔记·llm·agent·智能体
von Neumann2 小时前
大模型从入门到应用——HuggingFace:Transformers-[AutoClass]
人工智能·深度学习·机器学习·ai·大模型·huggingface
心勤则明2 小时前
用 SpringAIAlibab 让高频问题实现毫秒级响应
java·人工智能·spring
AI科技星2 小时前
基于v≡c第一性原理的大统一力方程:严格推导、全维度验证与四大基本相互作用的统一
人工智能·线性代数·算法·机器学习·平面