Python OpenCV 图像匹配(Brute-Force与FLANN)的原理与代码实现
先导文章:SIFT特征提取
Python OpenCV SIFT特征提取的原理与代码实现_乔卿的博客-CSDN博客如果对图像扩大规模,如缩放,如下图所示,那么原本的角点在变换后的某些窗口中可能就不是角点,因此,HarrisDetectors不具有尺度不变性。例如,在上图中,低σ的高斯核可以为小角点提供高值,而高σ的高斯核则适合于大角点。因此,我们可以在尺度空间中找到局部极大值。...https://qiaoxs.blog.csdn.net/article/details/125849051?spm=1001.2014.3001.5502
图像匹配
获得两张图像的关键点之后,下一步就是找到它们之间的对应关系,找到那些相匹配的点,从而基于这些点,实现图像拼接。在OpenCV中,我们可以用于Feature Matching的方法有两种:Brute-Force Matcher 和 FLANN Matcher。
Brute-Force Matcher
这一方法即暴力搜索法,它选择第一个集合中一个特征的描述符,计算与第二个集合中的所有其他特征描述符之间的距离,返回最接近的一个。
cv.BFMathcer()
对于BF Matcher,我们首先使用cv.BFMatcher()创建BFMatcher对象,该方法需要两个可选参数:
- normType:指定距离测量方法,默认为cv.NORM_L2,适合SIFT、SURF。cv.NORM_HAMMING则是更适合ORB(WTA_K == 3 or 4)、BRIEF、BRISK等二进制串描述符。下面列举一些距离方法,参考链接为:OpenCV: Operations on arrays
- cv.NORM_INF
- cv.NORM_L1
- cv.NORM_L2
- cv.NORM_L2SQR
- cv.NORM_HAMMING
- cv.NORM_HAMMING2
- crossCheck:这是一个布尔型的参数,默认为False。当crossCheck为True时,该方法仅返回那些互为最佳匹配的描述符下标(i,j)。
BFMatcher.match()
创建BFMatcher对象之后,使用BFMatcher.match()方法获得最佳匹配。更进一步地,可以使用BFMatcher.knnMatch()方法返回 k 个最佳匹配,其中 k 由用户指定。
该方法返回的结果是DMatch对象的列表。一个DMatch对象具有如下属性:
- DMatch.distance - 描述符之间的距离。越低越好。
- DMatch.trainIdx - 训练描述符描述符的索引。
- DMatch.queryIdx - 查询描述符中描述符的索引。
- DMatch.imgIdx - 训练图像的索引。
cv.drawMatches()
该方法被用于绘制关键点的匹配情况。我们看到的许多匹配结果都是使用这一方法绘制的——一左一右两张图像,匹配的关键点之间用线条链接。
函数原型:
cv.drawMatches( img1, keypoints1, img2, keypoints2, matches1to2, outImg[, matchColor[, singlePointColor[, matchesMask[, flags]]]]) -> outImgcv.drawMatches( img1, keypoints1, img2, keypoints2, matches1to2, outImg, matchesThickness[, matchColor[, singlePointColor[, matchesMask[, flags]]]] ) -> outImgcv.drawMatchesKnn( img1, keypoints1, img2, keypoints2, matches1to2, outImg[, matchColor[, singlePointColor[, matchesMask[, flags]]]]) -> outImg
参数:
- img1:第一张原始图像。
- keypoints1:第一张原始图像的关键点。
- img2:第二张原始图像。
- keypoints2:第二张原始图像的关键点。
- matches1to2:从第一个图像到第二个图像的匹配,这意味着keypoints1[i]在keypoints2[Matches[i]中有一个对应的点。
- outImg:绘制结果图像。
- matchColor:匹配连线与关键点点的颜色,当matchColor==Scalar::all(-1) 时,代表取随机颜色。
- singlePointColor:没有匹配项的关键点的颜色,当singlePointColor==Scalar::all(-1) 时,代表取随机颜色。
- matchesMask:确定绘制哪些匹配项的掩码。如果掩码为空,则绘制所有匹配项。
- flags:绘图功能的一些标志。具体有:
- cv.DRAW_MATCHES_FLAGS_DEFAULT
- cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
- cv.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG
- cv.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
使用SIFT描述符的具体实现
# Brute-Force Matchingdef bf_match(img_path1, img_path2):# 读取两张图像img1 = cv2.imread(img_path1, cv2.IMREAD_GRAYSCALE)img2 = cv2.imread(img_path2, cv2.IMREAD_GRAYSCALE)# 计算两张图像的SIFT描述符kp1, des1, _ = sift_algorithm(img_path1)kp2, des2, _ = sift_algorithm(img_path2)# 创建BFMatcher实例bf = cv2.BFMatcher()# 获得最佳匹配# matches = bf.match(des1, des2)matches = bf.knnMatch(des1, des2, k=2)# 使用比率检测,筛选出好的匹配good = []for m, n in matches:if m.distance < 0.75 * n.distance:good.append([m])# 绘制匹配结果# matches = sorted(matches, key = lambda x:x.distance)# match_result = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)match_result = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)# 显示绘制结果plt.imshow(match_result)plt.show()return match_resultbf_match(images_list[0], images_list[1])
匹配结果
FLANN based Matcher
FLANN,即近似最近邻的快速库(Fast Library for Approximate Nearest Neighbors)。
它包含一系列算法,这些算法针对大型数据集中的快速最近邻搜索(KD树)和高维特征进行了优化。对于大型数据集,它比BFMatcher工作得更快。
cv2.FlannBasedMatcher()
对于基于 FLANN 的匹配器,我们使用cv2.FlannBasedMatcher()创建FLANN匹配器对象,该方法需要传递两个字典来指定要使用的算法及其相关参数等。
- 第一个是 IndexParams,它指定最近邻搜索中的KD树算法。
- 对于SIFT,SURF,该信息可以是:
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
- 对于ORB,该信息可以是:
FLANN_INDEX_LSH = 6
index_params= dict(algorithm = FLANN_INDEX_LSH,
table_number = 6,
key_size = 12,
multi_probe_level = 1)
- 第二个是 SearchParams,它指定递归遍历索引中的树的次数。值越高,精度越高,但也需要更多时间。
search_params = dict(checks=100)
使用SIFT描述符的具体实现
# FLANN Matchingdef flann_match(img_path1, img_path2):# 读取两张图像img1 = cv2.imread(img_path1, cv2.IMREAD_GRAYSCALE) # queryImageimg2 = cv2.imread(img_path2, cv2.IMREAD_GRAYSCALE) # trainImage# 计算两张图像的SIFT描述符kp1, des1, _ = sift_algorithm(img_path1)kp2, des2, _ = sift_algorithm(img_path2)# 设置FLANN所需要的两个字典FLANN_INDEX_KDTREE = 1index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)search_params = dict(checks=50)# 创建FlannBasedMatcher对象flann = cv2.FlannBasedMatcher(index_params, search_params)# 获得匹配matches = flann.knnMatch(des1, des2, k=2)# 为了只绘制好的匹配,这里使用掩码matches_mask = [[0,0] for i in range(len(matches))]# 使用比率检测,筛选出好的匹配for i, (m, n) in enumerate(matches):if m.distance < 0.7 * n.distance:matches_mask[i] = [1, 0]# 绘制匹配结果,这里使用一个字典传递参数draw_params = dict(matchColor=(0, 255, 0),singlePointColor=(255, 0, 0),matchesMask=matches_mask,flags=cv2.DrawMatchesFlags_DEFAULT)match_result = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None, **draw_params)# 显示绘制结果plt.imshow(match_result)plt.show()return match_resultflann_match(images_list[0], images_list[1])
匹配结果
Python OpenCV 图像匹配(Brute-Force与FLANN)的原理与代码实现相关推荐
- python opencv图像匹配_关于python:OpenCV功能匹配多个图像
如何使用FLANN优化许多图片的SIFT功能匹配? 我有一个从Python OpenCV文档中获取的工作示例.然而,这是将一个图像与另一个图像进行比较而且速度很慢.我需要它来搜索一系列图像(几千个)中 ...
- Python+OpenCV 调用手机摄像头并实现人脸识别
文章内容: 1.windows 环境下安装 OpenCV 机器视觉环境搭建: 2.基于通过 Python+OpenCV调用手机摄像头并实现人脸检测识别. 目录 1 实验环境 2 实验准备 2.1 下载 ...
- 【Python | opencv+PIL】常见操作(创建、添加帧、绘图、读取等)的效率对比及其优化
一.背景 本人准备用python做图像和视频编辑的操作,却发现opencv和PIL的效率并不是很理想,并且同样的需求有多种不同的写法并有着不同的效率.见全网并无较完整的效率对比文档,遂决定自己丰衣足食 ...
- Python OpenCV识别行人入口进出人数统计
程序示例精选 Python OpenCV识别行人入口进出人数统计 如需安装运行环境或远程调试,见文章底部微信名片,由专业技术人员远程协助! 前言 这篇博客针对<Python OpenCV识别行 ...
- python+OpenCV笔记(三十五):特征匹配——基于FLANN的匹配、基于FLANN进行单应性匹配
目录 一.基于FLANN的匹配 FLANN匹配流程: 代码编写 二.基于FLANN进行单应性匹配 什么是单应性? FLANN进行单应性匹配流程 代码编写 FLANN库全称是Fast Library f ...
- Brute Force算法介绍及C++实现
字符串的模式匹配操作可以通过Brute Force算法来实现.字符串匹配操作即是查看S串(目标串或主串)中是否含有T串(模式串或子串),如果在主串中查找到了子串,则模式匹配成功,返回模式串中的第一个字 ...
- python+opencv图像拼接-python opencv 图像拼接的实现方法
初级的图像拼接为将两幅图像简单的粘贴在一起,仅仅是图像几何空间的转移与合成,与图像内容无关.高级图像拼接也叫作基于特征匹配的图像拼接,拼接时消去两幅图像相同的部分,实现拼接合成全景图. 具有相同尺寸的 ...
- DVWA学习(三)Brute Force(暴力破解)
BF算法,即暴风(Brute Force)算法,是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符:若不相 ...
- python——opencv入门(一)
1. OpenCV的结构 和Python一样,当前的OpenCV也有两个大版本,OpenCV2和OpenCV3.相比OpenCV2,OpenCV3提供了更强的功能和更多方便的特性.不过考虑到和深度学习 ...
最新文章
- $(document).ready(function() {})不执行的问题
- 第二轮冲刺-Runner站立会议03
- 数据结构 快速排序(详解)
- 448. Find All Numbers Disappeared in an Array 寻找有界数组[1,n]中的缺失数
- php 串口通信例程,HAL库串口通信例程
- python读取配置文件 分段_python配置文件读取
- Python更改pip镜像源
- Java 中时间处理SimpleDateFormat 中HH和hh的区别
- python 使用 ipx协议_肝了三天,万字长文教你玩转 tcpdump,从此抓包不用愁
- 2 imwrite中文路径_如何为FreePBX/Asterisk配置中文语音支持
- 菜鸟之路---1,熊猫烧香病毒的简单分析
- python实战项目
- QQ获取群链接、二维码
- 质量评估指标:PSNR(Peak signal-to-noise ratio 峰值信噪比)
- 台式计算机硬盘的安装位置,台式电脑分别如何安装SSD(固态硬盘)详细图文教程...
- matlab仿真心型函数,matlab绘制心形函数
- 40079 钉钉_钉钉获取免登陆授权码CODE,返回:不存在的临时授权码40078
- TextView中加横线
- js实现购物车加减和价格运算
- IE hasLayout详解