先导文章: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)的原理与代码实现相关推荐

  1. python opencv图像匹配_关于python:OpenCV功能匹配多个图像

    如何使用FLANN优化许多图片的SIFT功能匹配? 我有一个从Python OpenCV文档中获取的工作示例.然而,这是将一个图像与另一个图像进行比较而且速度很慢.我需要它来搜索一系列图像(几千个)中 ...

  2. Python+OpenCV 调用手机摄像头并实现人脸识别

    文章内容: 1.windows 环境下安装 OpenCV 机器视觉环境搭建: 2.基于通过 Python+OpenCV调用手机摄像头并实现人脸检测识别. 目录 1 实验环境 2 实验准备 2.1 下载 ...

  3. 【Python | opencv+PIL】常见操作(创建、添加帧、绘图、读取等)的效率对比及其优化

    一.背景 本人准备用python做图像和视频编辑的操作,却发现opencv和PIL的效率并不是很理想,并且同样的需求有多种不同的写法并有着不同的效率.见全网并无较完整的效率对比文档,遂决定自己丰衣足食 ...

  4. Python OpenCV识别行人入口进出人数统计

     程序示例精选 Python OpenCV识别行人入口进出人数统计 如需安装运行环境或远程调试,见文章底部微信名片,由专业技术人员远程协助! 前言 这篇博客针对<Python OpenCV识别行 ...

  5. python+OpenCV笔记(三十五):特征匹配——基于FLANN的匹配、基于FLANN进行单应性匹配

    目录 一.基于FLANN的匹配 FLANN匹配流程: 代码编写 二.基于FLANN进行单应性匹配 什么是单应性? FLANN进行单应性匹配流程 代码编写 FLANN库全称是Fast Library f ...

  6. Brute Force算法介绍及C++实现

    字符串的模式匹配操作可以通过Brute Force算法来实现.字符串匹配操作即是查看S串(目标串或主串)中是否含有T串(模式串或子串),如果在主串中查找到了子串,则模式匹配成功,返回模式串中的第一个字 ...

  7. python+opencv图像拼接-python opencv 图像拼接的实现方法

    初级的图像拼接为将两幅图像简单的粘贴在一起,仅仅是图像几何空间的转移与合成,与图像内容无关.高级图像拼接也叫作基于特征匹配的图像拼接,拼接时消去两幅图像相同的部分,实现拼接合成全景图. 具有相同尺寸的 ...

  8. DVWA学习(三)Brute Force(暴力破解)

    BF算法,即暴风(Brute Force)算法,是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符:若不相 ...

  9. python——opencv入门(一)

    1. OpenCV的结构 和Python一样,当前的OpenCV也有两个大版本,OpenCV2和OpenCV3.相比OpenCV2,OpenCV3提供了更强的功能和更多方便的特性.不过考虑到和深度学习 ...

最新文章

  1. $(document).ready(function() {})不执行的问题
  2. 第二轮冲刺-Runner站立会议03
  3. 数据结构 快速排序(详解)
  4. 448. Find All Numbers Disappeared in an Array 寻找有界数组[1,n]中的缺失数
  5. php 串口通信例程,HAL库串口通信例程
  6. python读取配置文件 分段_python配置文件读取
  7. Python更改pip镜像源
  8. Java 中时间处理SimpleDateFormat 中HH和hh的区别
  9. python 使用 ipx协议_肝了三天,万字长文教你玩转 tcpdump,从此抓包不用愁
  10. 2 imwrite中文路径_如何为FreePBX/Asterisk配置中文语音支持
  11. 菜鸟之路---1,熊猫烧香病毒的简单分析
  12. python实战项目
  13. QQ获取群链接、二维码
  14. 质量评估指标:PSNR(Peak signal-to-noise ratio 峰值信噪比)
  15. 台式计算机硬盘的安装位置,台式电脑分别如何安装SSD(固态硬盘)详细图文教程...
  16. matlab仿真心型函数,matlab绘制心形函数
  17. 40079 钉钉_钉钉获取免登陆授权码CODE,返回:不存在的临时授权码40078
  18. TextView中加横线
  19. js实现购物车加减和价格运算
  20. IE hasLayout详解

热门文章

  1. 用python把文本转换为数字
  2. 解决“不能读取 AppletViewer 的属性文件”的问题
  3. User-Agent结构介绍及主流浏览器User-Agent大全
  4. C++虚函数、纯虚函数、虚析构、纯虚析构、动态绑定和抽象类详解。
  5. 域名批量查询 到期未续费域名查询
  6. 分表、分库、分片和分区
  7. GUID partition table (GPT) 磁盘分区表详解
  8. Spring 注解-包扫描
  9. Nginx配置图片服务器(Nginx极简配置说明)
  10. 收藏:NVMe协议基础原理介绍