al+大数据每日学习笔记27

2026年8月26日

SIFT+FLANN 指纹特征匹配知识点总结

项目用途:指纹识别,利用SIFT 提取局部特征 + FLANN 快速匹配 + Lowe 比率筛选完成指纹比对、指纹库检索、匹配点可视化。

一、核心知识点

1. SIFT 特征(尺度不变特征变换)

作用:提取图像关键点(特征点)+ 生成描述子 (des),对缩放、旋转有一定鲁棒性,适合指纹这类细节特征匹配。

sift.detectAndCompute(img,mask)

返回:kp关键点列表,des描述符(特征向量数组)

kpi.pt 获取第 i 个关键点坐标**(x,y)**

OpenCV 调用:sift = cv2.SIFT_create()

2. FLANN 匹配器

FLANN:快速近似最近邻搜索,比暴力匹配 BFMatcher 速度快,适合描述符数量大的场景(指纹特征点很多)。

flann = cv2.FlannBasedMatcher()

flann.knnMatch(des1, des2, k=2): k 近邻匹配,每个特征点返回 2 个最匹配结果,用于 Lowe 筛选。

3. Lowe's ratio test(比率测试,核心过滤算法)

作用:剔除错误匹配,滤除歧义匹配点

复制代码
if m.distance < ratio * n.distance:
    保留匹配

m :第一近匹配;n :第二近匹配

distance: 描述符之间欧式距离,距离越小特征越相似

ratio 常用阈值:0.4 ~ 0.8;阈值越小筛选越严格,保留匹配点越少。

4. OpenCV 关键点与匹配可视化

cv2.circle() :在图像上绘制关键点圆圈标记

cv2.drawMatchesKnn() :拼接两张图,画出匹配点之间连线

flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS :不绘制无匹配的关键点

**cv2.imshow() / cv2.waitKey(0):**图片显示。

5. 指纹库检索业务逻辑

遍历指纹库文件夹,逐个与待识别图片计算有效匹配点数

记录最大匹配点数量,得到最相似指纹文件名

设置匹配点阈值(例 200/500):低于阈值判定库中无该指纹;

文件名字符串切片拿到编号,映射字典得到人名。

二、代表性关键代码片段

片段 1:SIFT 提取特征 + FLANN k 近邻匹配 + Lowe 筛选

复制代码
import cv2

# 1.创建SIFT
sift = cv2.SIFT_create()
# 2.提取关键点、描述符
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# 3.FLANN匹配器
flann = cv2.FlannBasedMatcher()
matches = flann.knnMatch(des1, des2, k=2)

# 4.Lowe比率测试筛选优秀匹配点
good_matches = []
ratio = 0.8
for m, n in matches:
    if m.distance < ratio * n.distance:
        good_matches.append(m)

# 获取有效匹配数量
match_count = len(good_matches)
print("有效匹配点数量:", match_count)

片段 2:标记关键点 + 绘制匹配连线

复制代码
# 在原图绘制匹配到的关键点
for match in good_matches:
    # queryIdx:第一张图关键点索引;trainIdx:第二张图关键点索引
    x1, y1 = kp1[match.queryIdx].pt
    x2, y2 = kp2[match.trainIdx].pt
    cv2.circle(img1, (int(x1), int(y1)), 3, (0, 0, 255), -1)
    cv2.circle(img2, (int(x2), int(y2)), 3, (0, 0, 255), -1)

# 绘制匹配连线图
match_img = cv2.drawMatchesKnn(img1, kp1, img2, kp2, [[m] for m in good_matches], None,
                               flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS)
cv2.imshow("匹配结果", match_img)
cv2.waitKey(0)

片段 3:指纹库遍历检索(核心业务)

复制代码
import os

def search_fingerprint(src_path, db_path):
    max_num = 0
    best_file = ""
    for filename in os.listdir(db_path):
        full_path = os.path.join(db_path, filename)
        # getNum:计算两张图片有效匹配点数,即上面片段1逻辑
        cnt = getNum(src_path, full_path)
        print(f"{filename} 匹配点:{cnt}")
        if cnt > max_num:
            max_num = cnt
            best_file = filename
    # 阈值判断,匹配不足判定未找到
    if max_num < 200:
        return 9999, "未找到指纹"
    else:
        fid = best_file[0]
        return fid, max_num

片段 4:简单认证逻辑

复制代码
def verify_fingerprint(src_img, template_img, thresh=500):
    sift = cv2.SIFT_create()
    kp1, des1 = sift.detectAndCompute(src_img, None)
    kp2, des2 = sift.detectAndCompute(template_img, None)
    flann = cv2.FlannBasedMatcher()
    matches = flann.knnMatch(des1, des2, k=2)
    good = [m for m,n in matches if m.distance < 0.8*n.distance]
    if len(good) >= thresh:
        return "认证通过"
    else:
        return "认证失败"

三、整体流程总结

读取指纹图片 → SIFT检测关键点+计算描述子 → FLANN k=2近邻匹配 → Lowe比率过滤错误匹配 → 统计有效匹配点数量 → 和阈值比较: ①单张比对:直接输出认证通过/失败 ②指纹库识别:遍历全部模板,取匹配点最多的模板,映射得到人员姓名 ③可视化:画关键点、画匹配连线

相关推荐
2601_949950632 小时前
练题簿在线练题全流程:从资料导入到模拟考试与错题复盘
学习·考研·小程序·刷题·小程序推荐
2601_965384262 小时前
口腔黏膜清洁的工程化路径:从表面形貌表征到清洁策略匹配
经验分享·笔记
泡泡鱼(敲代码中)2 小时前
Python 容器类型学习笔记:列表、元组、字典、集合
开发语言·笔记·python·pycharm
别动我齐刘海2 小时前
ROS2 Jazzy + C++ 实战路线——基础学习2
c++·人工智能·vscode·python·学习·机器学习·机器人
Hotchip_MEMS4 小时前
传统咪头与MEMS硅麦:雾化器气流传感方案对比
人工智能·笔记·物联网·电脑·制造
志尊宝4 小时前
Vue3 零基础每日笔记(040):Vite 创建 Vue3 + TS 项目——企业标配从这一篇开始
笔记·vue·html·前端开发·软件开发
水云桐程序员5 小时前
量子力学概论,量子力学概念总结
笔记·科技·学习·量子计算
darin_ฅ( ̳• ◡ • ̳)ฅ15 小时前
【 Obsidian】2026版-Obsidian安装Automatic Table of Contents 插件一键生成文章目录
笔记
2401_850122045 小时前
航空、轨交、汽车线束防护有什么不同?三大行业的共性、差异与选型逻辑
经验分享·笔记·科技
志尊宝5 小时前
Vue3 零基础每日笔记(037):动手封装 useMouse 与 useWindowSize——事件监听的标准模板
前端·javascript·vue.js·笔记·html5