北京产品网站设计哪家专业,5网站建设,wordpress定时发布,重庆点优定制网站建设sift特征检测和FLANN 匹配器进行指纹匹配 目录 sift特征检测和FLANN 匹配器进行指纹匹配1 sift特征检测1.1 概念1.2 优缺点 2 FLANN 匹配器2.1 概念2.2 工作原理与匹配方式2.3 FLANN 匹配器的使用步骤2.4 优缺点 3 函数3.1 特征检测匹配3.2 匹配符合条件点并绘制 3 代码测试3.1…sift特征检测和FLANN 匹配器进行指纹匹配 目录 sift特征检测和FLANN 匹配器进行指纹匹配1 sift特征检测1.1 概念1.2 优缺点 2 FLANN 匹配器2.1 概念2.2 工作原理与匹配方式2.3 FLANN 匹配器的使用步骤2.4 优缺点 3 函数3.1 特征检测匹配3.2 匹配符合条件点并绘制 3 代码测试3.1 单个指纹模板匹配3.2 多个指纹匹配 1 sift特征检测
1.1 概念
SIFT尺度不变特征变换是一种用于图像处理中检测和描述图像中局部结构的算法。它是由David Lowe在1999年提出的并在2004年进行了详细阐述。SIFT特征具有尺度不变性这意味着即使图像的尺度发生变化SIFT特征也能保持稳定。
1.2 优缺点
SIFT特征的优点
尺度不变性能够适应图像的尺度变化。旋转不变性能够适应图像的旋转变化。对光照、仿射变换和噪声具有一定的鲁棒性。
SIFT特征的缺点
计算复杂度较高实时性较差。对于非线性变换和大幅度的视角变化SIFT特征的性能可能会下降。
2 FLANN 匹配器 2.1 概念
FLANN 匹配器Fast Library for Approximate Nearest Neighbors快速近似最近邻搜索库是 OpenCV 中用于高效匹配特征描述符的工具。它通过近似算法加速最近邻搜索特别适合处理高维数据如 SIFT 或 SURF 描述符。
2.2 工作原理与匹配方式
最近邻搜索 给定一个特征描述符集合FLANN 的目标是找到与查询描述符最接近的匹配点。精确的最近邻搜索如暴力匹配在高维数据中计算量很大FLANN 通过近似算法加速搜索。 近似算法 FLANN 使用了一种基于树结构的算法如 KD-Tree 或 Hierarchical K-Means Tree来组织数据从而快速缩小搜索范围。通过牺牲一定的精度换取更快的搜索速度。 匹配方式 FLANN 支持两种匹配方式单匹配为每个查询描述符找到一个最近邻。KNN 匹配为每个查询描述符找到 K 个最近邻。
2.3 FLANN 匹配器的使用步骤 创建 FLANN 匹配器 使用 cv2.FlannBasedMatcher 创建 FLANN 匹配器对象。 准备特征描述符 使用特征检测算法如 SIFT、SURF 或 ORB提取图像的特征描述符。 进行匹配 使用 knnMatch 方法进行 KNN 匹配返回每个查询描述符的 K 个最近邻。 筛选匹配点 根据距离比例或其他条件筛选出可靠的匹配点。
2.4 优缺点
优点
高效比暴力匹配Brute-Force Matcher更快特别适合处理高维数据。灵活支持多种算法和参数配置可以根据需求调整精度和速度。
缺点
近似匹配结果是近似的可能存在一定的误差。参数调优需要根据具体任务调整参数否则可能影响匹配效果。
3 函数 3.1 特征检测匹配
特征关键点检测 sift cv2.SIFT_create()创建 SIFT 特征检测器kp1, des1 sift.detectAndCompute(src, None)检测并计算 src 图像的关键点kp1 和描述符des1 匹配器匹配 flann cv2.FlannBasedMatcher()创建FLANN 匹配器matches flann.knnMatch(des1, des2, 2) 使用 KNN 算法进行特征des1, des2匹配k2 表示每个描述符返回两个最佳匹配
3.2 匹配符合条件点并绘制
ok [] # 存储符合条件的匹配点
ok_n [] # 存储对应的次佳匹配点# 遍历所有匹配点
for m, n in matches:
# 如果最佳匹配点的距离小于次佳匹配点距离的 0.65 倍则认为是一个好的匹配if m.distance 0.65 * n.distance:ok.append(m) # 将好的匹配点加入 ok 列表ok_n.append(n) # 将对应的次佳匹配点加入 ok_n 列表# 计算好的匹配点的数量
num len(ok)# 如果好的匹配点数量大于等于 400则认为验证通过
if num 400:result 认证通过 # 设置验证结果为通过# 遍历所有匹配点for m, n in matches:# 再次筛选好的匹配点if m.distance 0.65 * n.distance:ok.append(m)x1 int(kp1[m.queryIdx].pt[0])y1 int(kp1[m.queryIdx].pt[1])x2 int(kp2[n.queryIdx].pt[0])y2 int(kp2[n.queryIdx].pt[1])src cv2.circle(src, (x1, y1), 3, (0, 0, 255), -1)model cv2.circle(model, (x2, y2), 3, (0, 0, 255), -1)
3 代码测试 3.1 单个指纹模板匹配
图片1
图片2
模板
代码展示
import cv2
def cv_chow(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 cv2.FlannBasedMatcher()matches flann.knnMatch(des1, des2, 2)ok []ok_n []for m, n in matches:if m.distance 0.65 * n.distance:ok.append(m)ok_n.append(n)## m,n,在kp的ptnum len(ok)if num400:result 认证通过for m, n in matches:if m.distance 0.65 * n.distance:ok.append(m)x1 int(kp1[m.queryIdx].pt[0])y1 int(kp1[m.queryIdx].pt[1])x2 int(kp2[n.queryIdx].pt[0])y2 int(kp2[n.queryIdx].pt[1])src cv2.circle(src, (x1, y1), 3, (0, 0, 255), -1)model cv2.circle(model, (x2, y2), 3, (0, 0, 255), -1)cv_chow(src, src)cv_chow(model, model)else:result 认证失败return resultif __name____main__:src1 cv2.imread(zhiwen1.bmp)cv_chow(src1,src1)src2 cv2.imread(zhiwen2.bmp)cv_chow(src2, src2)model cv2.imread(zhiwenp.bmp)cv_chow(model_, model)result1 verification(src1,model)result2 verification(src2, model)print(fsrc1验证结果{result1})print(fsrc2验证结果{result2})运行结果
3.2 多个指纹匹配
指纹文件库
代码展示
import osdef 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, 2)ok []for m, n in matches:if m.distance 0.8 * n.distance:ok.append(m)num len(ok)return numdef getID(src,database):max 0for file in os.listdir(database):print(file)model os.path.join(database,file)num getNum(src,model)print(f文件名{file}匹配点个数{num})if nummax:max numname fileID name[0]if max100:ID 9999return IDdef getname(ID):nameID {0:张三,1:李四,2:王五,3:赵六,4:朱老七,5:钱八,6:曹九,7:王二麻子,8:andy,9:Anna,9999:没找到}name nameID.get(int(ID))return nameif __name____main__:src scrpp.bmpdatabase database//databaseID getID(src,database)name getname(ID)print(f识别结果{name})运行结果