opencv学习:FLANN匹配器算法实现指纹验证与指纹识别
概念
FLANN(Fast Library for Approximate Nearest Neighbors)是一个开源的C++库,用于在高维空间中进行近似最近邻搜索。它被广泛用于计算机视觉和机器学习领域,特别是在处理具有大量特征点的图像匹配问题时。FLANN旨在提供一个快速且灵活的近似最近邻搜索解决方案。
最近邻搜索:给定一个查询点,最近邻搜索的目标是找到一个数据点,使得与查询点之间的距离最小。在特征匹配中,这通常用于找到与查询图像中特征点最相似的特征点。
近似最近邻搜索:与精确最近邻搜索不同,近似最近邻搜索不保证找到距离最小的点,但可以在更短的时间内找到一个距离相对较小的点。这对于处理大规模数据集或实时应用非常有用。
特征匹配方法
在 OpenCV 中,match
,radiusMatch
,和 knnMatch
是三种不同的特征匹配方法,它们都属于 DescriptorMatcher
类。下面是每种方法的简要说明和使用场景:
-
match:
match
方法为每个查询描述符找到训练描述符集中的单个最佳匹配。- 它返回一个
DMatch
对象的列表,其中每个对象表示一个匹配对。 - 通常用于当你知道每个查询描述符在训练集中只有一个最佳匹配时。
match(self, queryDescriptors, trainDescriptors, mask=None)
-
knnMatch:
knnMatch
方法为每个查询描述符找到训练描述符集中的 k 个最佳匹配。- 它返回一个列表的列表,其中每个内部列表包含 k 个
DMatch
对象,按距离递增排序。 - 通常用于找到多个潜在匹配,然后可以通过 Lowe's ratio test 来选择最佳匹配。
- 参数
k
通常设置为 2,这样每个查询描述符会有两个最近邻。knnMatch(self, queryDescriptors, trainDescriptors, k, mask=None, compactResult=None)
-
radiusMatch:
radiusMatch
方法为每个查询描述符找到所有在指定半径内的训练描述符。- 它返回一个列表的列表,其中每个内部列表包含所有在指定半径内的匹配对。
- 这种方法不是基于最近邻的,而是基于距离阈值的,可以找到所有与查询描述符距离在一定范围内的训练描述符。
- 适用于当你需要找到所有可能的匹配,而不仅仅是最近的那些。
radiusMatch(self, queryDescriptors, trainDescriptors, maxDistance, mask=None, compactResult=None)
指纹验证
运行结果
代码流程
函数用于显示图像
def cv_show(name,img):
cv2.imshow(name,img)
cv2.waitKey(0)
验证两幅图像是否相似
1.创建了一个 SIFT 特征检测器,对源图像进行 SIFT 特征检测和描述
# 创建了一个SIFT特征检测器。
sift=cv2.SIFT_create()
kp1,des1=sift.detectAndCompute(src,None)
# 对源图像进行SIFT特征检测和描述,得到关键点kp1和描述符des1。
kp2,des2=sift.detectAndCompute(model,None)
2.创建了一个基于 FLANN 的匹配器,使用 FLANN 匹配器对描述符进行 K 最近邻匹配
# 创建了一个基于FLANN的匹配器。
flann=cv2.FlannBasedMatcher()
# 使用FLANN匹配器对描述符进行K最近邻匹配。
matches=flann.knnMatch(des1,des2,2)
3.筛选出好的匹配,如果好的匹配数量 num
超过 500,则认为验证成功,否则验证失败。
for i,j in matches:
# 如果当前匹配的距离小于其最近邻距离的80%,则认为是一个好的匹配。
if i.distance<0.8*j.distance:
m.append(i)
num=len(m)
if num>500:
result='验证成功'
else:
result=('验证失败')
return result
完整代码
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)
# 对源图像进行SIFT特征检测和描述,得到关键点kp1和描述符des1。
kp2,des2=sift.detectAndCompute(model,None)
# 创建了一个基于FLANN的匹配器。
flann=cv2.FlannBasedMatcher()
# 使用FLANN匹配器对描述符进行K最近邻匹配。
matches=flann.knnMatch(des1,des2,2)
m=[]
for i,j in matches:
# 如果当前匹配的距离小于其最近邻距离的80%,则认为是一个好的匹配。
if i.distance<0.8*j.distance:
m.append(i)
num=len(m)
if num>500:
result='验证成功'
else:
result=('验证失败')
return result
if __name__ == '__main__':
a1=cv2.imread('zhiwen1.bmp')
a2=cv2.imread('zhiwen2.bmp')
model=cv2.imread('zhiwenmodel.bmp')
result1=verification(a1,model)
result2=verification(a2,model)
print(result1)
print(result2)
指纹识别
运行结果
完整代码
import cv2
import os
# 定义函数getNum,用于计算两幅图像之间的匹配点数量
def getNum(src, model):
img1 = cv2.imread(src) # 读取源图像
img2 = cv2.imread(model) # 读取模型图像
sift = cv2.SIFT_create() # 创建SIFT特征检测器
kp1, des1 = sift.detectAndCompute(img1, None) # 检测源图像的关键点和描述符
kp2, des2 = sift.detectAndCompute(img2, None) # 检测模型图像的关键点和描述符
flann = cv2.FlannBasedMatcher() # 创建FLANN匹配器
matches = flann.knnMatch(des1, des2, 2) # 使用FLANN匹配器进行K最近邻匹配
m = [] # 初始化匹配点列表
# 遍历匹配结果,使用Lowe's ratio test筛选好的匹配
for i, j in matches:
if i.distance < 0.8 * j.distance:
m.append(i)
num = len(m) # 计算好的匹配点数量
return num # 返回匹配点数量
# 定义函数getID,用于在数据库中找到与源图像最相似的模型图像
def getID(src, database):
max = 0 # 初始化最大匹配点数量
for file in os.listdir(database): # 遍历数据库中的每个模型图像
model = os.path.join(database, file) # 获取模型图像的完整路径
num = getNum(src, model) # 使用getNum函数计算匹配点数量
print('file', file, '距离', num) # 打印模型图像文件名和匹配点数量
# 如果当前模型图像的匹配点数量大于已知的最大值,则更新最大值和对应的文件名
if num > max:
max = num
name = file
ID = name[0] # 将匹配点数量最多的模型图像的文件名的第一位作为ID
if max < 100: # 如果最大匹配点数量小于100,则将ID设置为99999
ID = 99999
return ID # 返回ID
# 定义函数getName,用于将ID转换为对应的名称
def getName(ID):
nameID = {0: '一', 1: '二', 2: '三', 3: '四', 4: '五', 5: '六', 6: '七', 7: '八', 8: '九', 9: '十'} # 定义ID到名称的映射
name = nameID.get(int(ID)) # 获取ID对应的名称
return name # 返回名称
# 主程序入口
if __name__ == '__main__':
src = 'src.bmp' # 源图像路径
database = 'database' # 数据库目录路径
ID = getID(src, database) # 调用getID函数获取ID
name = getName(ID) # 调用getName函数获取名称
print('识别结果', name) # 打印识别结果
原文地址:https://blog.csdn.net/mohanyelong/article/details/142778193
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!