Python OpenCV特征检测之特征匹配方式详解

目录
  • 前言 
  • 一、暴力匹配器
  • 二、FLANN匹配器

前言 

获得图像的关键点后,可通过计算得到关键点的描述符。关键点描述符可用于图像的特征匹配。通常,在计算图A是否包含图B的特征区域时,将图A称做训练图像,将图B称为查询图像。图A的关键点描述符称为训练描述符,图B的关键点描述符称为查询描述符。

一、暴力匹配器

暴力匹配器使用描述符进行特征比较。在比较时,暴力匹配器首先在查询描述符中取一个关键点的描述符,将其与训练描述符中的所有关键点描述符进行比较,每次比较后会给出一个距离值,距离最小的值对应最佳匹配结果。所有描述符比较完后,匹配器返回匹配结果列表。

OpenCV的cv2.BFMatcher_create()函数用于创建暴力匹配器,其基本格式如下:

bf = cv2.BFMatcher_create([normType[, crossCheck]])

bf为返回的暴力匹配器对象

normType为距离测量类型, 默认为cv2.NORM_L2, 通常, SIFT描述符使用cv2.NORM_L1或cv2.NORM_L2, ORB描述符使用cv2.NORM_HAMMING

crossCheck默认为False, 匹配器为每个查询描述符找到k个距离最近的匹配描述符, 为True时, 只返回满足交叉验证条件的匹配结果

暴力匹配器对象的match()方法返回每个关键点的最佳匹配结果,其基本格式如下:

ms = bf.match(des1, des2)

ms为返回的结果, 它是一个DMatch对象列表, 每个DMatch对象表示关键点的一个匹配结果, 其dintance属性表示距离, 距离值越小匹配度越高

des1为查询描述符

des2为训练描述符

获得匹配结果后,可调用cv2.drawMatches()函数或cv2.drawMatchesKnn()函数绘制匹配结果图像,其基本格式如下:

outImg = cv2.drawMatches(img1, keypoints1, img2, keypoints2, matches1to2[, matchColor[, singlePointColor[, matchesMask[, flags]]]])

outImg为返回的绘制结果图像, 图像中查询图像与训练图像中匹配的关键点个两点之间的连线为彩色

img1为查询图像

keypoints1为img1的关键点

img2为训练图像

keypoints2为img2的关键点

matches1to2为img1与img2的匹配结果

matchColor为关键点和链接线的颜色, 默认使用随机颜色

singlePointColor为单个关键点的颜色, 默认使用随机颜色

matchesMask为掩膜, 用于决定绘制哪些匹配结果, 默认为空, 表示绘制所有匹配结果

flags为标志, 可设置为下列参数值:

cv2.DrawMatchesFlags_DEFAUL:默认方式, 绘制两个源图像、匹配项和单个关键点, 没有围绕关键点的圆以及关键点的大小和方向

cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS:不会绘制单个关键点

cv2.DrawMatchesFlags_DRAW_RICH_KEYPOINTS:在关键点周围绘制具有关键点大小和方向的圆圈

# 暴力匹配器、ORB描述符和match()方法
import cv2

img1 = cv2.imread("xhu1.jpg", cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread("xhu2.jpg", cv2.IMREAD_GRAYSCALE)

orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

bf = cv2.BFMatcher_create(cv2.NORM_HAMMING, crossCheck = False)
ms = bf.match(des1, des2)
ms = sorted(ms, key = lambda x:x.distance)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, ms[:20], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)

cv2.imshow("Xhu1", img1)
cv2.imshow("Xhu2", img2)
cv2.imshow("Matches", img3)

cv2.waitKey(0)
cv2.destroyAllWindows()

# 暴力匹配器、SIFT描述符和match()方法
import cv2

img1 = cv2.imread("xhu1.jpg", cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread("xhu2.jpg", cv2.IMREAD_GRAYSCALE)

sift=cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

bf = cv2.BFMatcher_create(cv2.NORM_L1, crossCheck = False)
ms = bf.match(des1, des2)
ms = sorted(ms, key = lambda x:x.distance)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, ms[:20], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)

# ms = np.expand_dims(ms,1)
# img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, ms[:20], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)

cv2.imshow("Xhu1", img1)
cv2.imshow("Xhu2", img2)
cv2.imshow("Matches", img3)

cv2.waitKey(0)
cv2.destroyAllWindows()

暴力匹配器对象的knnMatch()方法可返回指定数量的最佳匹配结果,其基本格式如下:

ms = knnMatch(des1, des2, k=n)

ms为返回的匹配结果, 每个列表元素是一个子列表, 它包含了由参数k指定个数的DMatch对象

des1为查询描述符

des2为训练描述符

k为返回的最佳匹配个数

# 暴力匹配器、ORB描述符和knnMatch()方法
import cv2

img1 = cv2.imread("xhu1.jpg", cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread("xhu2.jpg", cv2.IMREAD_GRAYSCALE)

orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

bf = cv2.BFMatcher_create(cv2.NORM_HAMMING, crossCheck = False)
ms = bf.knnMatch(des1, des2, k=2)

# 应用比例测试选择要使用的匹配结果
good = []
for m, n in ms:
    if m.distance < 0.75 * n.distance:
		good.append(m)

img3 = cv2.drawMatches(img1, kp1, img2, kp2, good[:20], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
# good = np.expand_dims(good,1)
#img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good[:20], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)

cv2.imshow("Xhu1", img1)
cv2.imshow("Xhu2", img2)
cv2.imshow("Matches", img3)

cv2.waitKey(0)
cv2.destroyAllWindows()

二、FLANN匹配器

FLANN(Fast Library for Approximate Nearest Neignbors)为近似最近邻的快速库,FLANN特征匹配算法比其它的最近邻算法更快。

在创建FLANN匹配器时,需要传递两参数:index_params和search_params。

index_params用来指定索引树的算法类型和数量。SIFT算法可以使用下面的代码来设置。

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)

search_params用于指定索引树的遍历次数,遍历次数越多,匹配结果越精细,通常设置为50即可,如下所示:

search_params = dict(check = 50)
# FLANN匹配器、ORB描述符
import cv2

img1 = cv2.imread("xhu1.jpg", cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread("xhu2.jpg", cv2.IMREAD_GRAYSCALE)

orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

# 定义FLANN参数
FLANN_INDEX_LSH = 6
index_params = dict(algorithm = FLANN_INDEX_LSH,
                    table_number = 6,
                    key_size = 12,
                    multi_probe_level = 1)
search_params = dict(check = 50)

flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.match(des1, des2)
draw_params = dict(matchColor = (0,255,0),
                   singlePointColor = (255,0,0),
                   matchesMask = None,
                   flags = cv2.DrawMatchesFlags_DEFAULT)

img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:20], None, **draw_params)

cv2.imshow("Xhu1", img1)
cv2.imshow("Xhu2", img2)
cv2.imshow("Matches", img3)

cv2.waitKey(0)
cv2.destroyAllWindows()

# FLANN匹配器、SIFT描述符
import cv2

img1 = cv2.imread("xhu1.jpg", cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread("xhu2.jpg", cv2.IMREAD_GRAYSCALE)

sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# 定义FLANN参数
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm = FLANN_INDEX_KDTREE,
                    trees = 5)
search_params = dict(check = 50)

flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.match(des1, des2)
draw_params = dict(matchColor = (0,255,0),
                   singlePointColor = (255,0,0),
                   matchesMask = None,
                   flags = cv2.DrawMatchesFlags_DEFAULT)

img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:20], None, **draw_params)

cv2.imshow("Xhu1", img1)
cv2.imshow("Xhu2", img2)
cv2.imshow("Matches", img3)

cv2.waitKey(0)
cv2.destroyAllWindows()

到此这篇关于Python OpenCV特征检测之特征匹配方式详解的文章就介绍到这了,更多相关Python OpenCV特征匹配内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python使用Opencv实现图像特征检测与匹配的方法

    特征检测是计算机对一张图像中最为明显的特征进行识别检测并将其勾画出来.大多数特征检测都会涉及图像的角点.边和斑点的识别.或者是物体的对称轴. 角点检测 是由Opencv的cornerHarris函数实现,其他函数参数说明如下: cv2.cornerHarris(src=gray, blockSize=9, ksize=23, k=0.04) # cornerHarris参数: # src - 数据类型为 float32 的输入图像. # blockSize - 角点检测中要考虑的领域大小. #

  • OpenCV实现特征检测和特征匹配方法汇总

    目录 1.SURF 2.SIFT 3.ORB 4.FAST 5.Harris角点 一幅图像中总存在着其独特的像素点,这些点我们可以认为就是这幅图像的特征,成为特征点.计算机视觉领域中的很重要的图像特征匹配就是一特征点为基础而进行的,所以,如何定义和找出一幅图像中的特征点就非常重要.这篇文章我总结了视觉领域最常用的几种特征点以及特征匹配的方法. 在计算机视觉领域,兴趣点(也称关键点或特征点)的概念已经得到了广泛的应用, 包括目标识别. 图像配准. 视觉跟踪. 三维重建等. 这个概念的原理是, 从图

  • 浅析ORB、SURF、SIFT特征点提取方法以及ICP匹配方法

    目录 main.cpp CMakeLists.txt 执行效果 ICP CMakeLists.txt 执行效果 在进行编译视觉SLAM时,书中提到了ORB.SURF.SIFT提取方法,以及特征提取方法暴力匹配(Brute-Force Matcher)和快速近邻匹配(FLANN).以及7.9讲述的3D-3D:迭代最近点(Iterative Closest Point,ICP)方法,ICP 的求解方式有两种:利用线性代数求解(主要是SVD),以及利用非线性优化方式求解. 完整代码代码如下: 链接:h

  • opencv3/C++ FLANN特征匹配方式

    使用函数detectAndCompute()检测关键点并计算描述符 函数detectAndCompute()参数说明: void detectAndCompute( InputArray image, //图像 InputArray mask, //掩模 CV_OUT std::vector<KeyPoint>& keypoints,//输出关键点的集合 OutputArray descriptors,//计算描述符(descriptors[i]是为keypoints[i]的计算描述符

  • python利用opencv实现SIFT特征提取与匹配

    本文实例为大家分享了利用opencv实现SIFT特征提取与匹配的具体代码,供大家参考,具体内容如下 1.SIFT 1.1.sift的定义 SIFT,即尺度不变特征变换(Scale-invariant feature transform,SIFT),是用于图像处理领域的一种描述.这种描述具有尺度不变性,可在图像中检测出关键点,是一种局部特征描述子. 1.2.sift算法介绍 SIFT由David Lowe在1999年提出,在2004年加以完善 .SIFT在数字图像的特征描述方面当之无愧可称之为最红

  • Python OpenCV特征检测之特征匹配方式详解

    目录 前言  一.暴力匹配器 二.FLANN匹配器 前言  获得图像的关键点后,可通过计算得到关键点的描述符.关键点描述符可用于图像的特征匹配.通常,在计算图A是否包含图B的特征区域时,将图A称做训练图像,将图B称为查询图像.图A的关键点描述符称为训练描述符,图B的关键点描述符称为查询描述符. 一.暴力匹配器 暴力匹配器使用描述符进行特征比较.在比较时,暴力匹配器首先在查询描述符中取一个关键点的描述符,将其与训练描述符中的所有关键点描述符进行比较,每次比较后会给出一个距离值,距离最小的值对应最佳

  • Python OpenCV实现识别信用卡号教程详解

    目录 通过与 OpenCV 模板匹配的 OCR 信用卡 OCR 结果 总结 今天的博文分为三个部分. 在第一部分中,我们将讨论 OCR-A 字体,这是一种专为辅助光学字符识别算法而创建的字体. 然后我们将设计一种计算机视觉和图像处理算法,它可以: 本地化信用卡上的四组四位数字. 提取这四个分组中的每一个,然后单独分割 16 个数字中的每一个. 使用模板匹配和 OCR-A 字体识别 16 个信用卡数字中的每一个. 最后,我们将看一些将信用卡 OCR 算法应用于实际图像的示例. 通过与 OpenCV

  • Python OpenCV对图像进行模糊处理详解流程

    其实我们平时在深度学习中所说的卷积操作,在 opencv 中也可以进行,或者说是类似操作.那么它是什么操作呢?它就是图像的模糊(滤波)处理. 均值滤波 使用 opencv 中的cv2.blur(src, ksize)函数.其参数说明是: src: 原图像 ksize: 模糊核大小 原理:它只取内核区域下所有像素的平均值并替换中心元素.3x3 标准化的盒式过滤器如下所示: 特征:核中区域贡献率相同. 作用:对于椒盐噪声的滤除效果比较好. # -*-coding:utf-8-*- ""&q

  • Python OpenCV图像处理之图像滤波特效详解

    目录 1分类 2邻域滤波 2.1线性滤波 2.2非线性滤波 3频域滤波 3.1低通滤波 3.2高通滤波 1 分类 图像滤波按图像域可分为两种类型: 邻域滤波(Spatial Domain Filter),其本质是数字窗口上的数学运算.一般用于图像平滑.图像锐化.特征提取(如纹理测量.边缘检测)等,邻域滤波使用邻域算子——利用给定像素周围像素值以决定此像素最终输出的一种算子 频域滤波(Frequency Domain Filter),其本质是对像素频率的修改.一般用于降噪.重采样.图像压缩等. 按

  • 浅谈Python Opencv中gamma变换的使用详解

    伽马变换就是用来图像增强,其提升了暗部细节,简单来说就是通过非线性变换,让图像从暴光强度的线性响应变得更接近人眼感受的响应,即将漂白(相机曝光)或过暗(曝光不足)的图片,进行矫正. 伽马变换的基本形式如下: 大于1时,对图像的灰度分布直方图具有拉伸作用(使灰度向高灰度值延展),而小于1时,对图像的灰度分布直方图具有收缩作用(是使灰度向低灰度值方向靠拢). #分道计算每个通道的直方图 img0 = cv2.imread('12.jpg') hist_b = cv2.calcHist([img0],

  • 对Python使用mfcc的两种方式详解

    1.Librosa import librosa filepath = "/Users/birenjianmo/Desktop/learn/librosa/mp3/in.wav" y,sr = librosa.load(filepath) mfcc = librosa.feature.mfcc( y,sr,n_mfcc=13 ) 返回结构为(13,None)的np.Array,None表示任意数量 2.python_speech_features from python_speech_

  • Python+OpenCV实现阈值分割的方法详解

    目录 一.全局阈值 1.效果图 2.源码 二.滑动改变阈值(滑动条) 1.效果图 2.源码 三.自适应阈值分割 1.效果图 2.源码 3.GaussianBlur()函数去噪 四.参数解释 一.全局阈值 原图: 整幅图采用一个阈值,与图片的每一个像素灰度进行比较,重新赋值: 1.效果图 2.源码 import cv2 import matplotlib.pyplot as plt #设定阈值 thresh=130 #载入原图,并转化为灰度图像 img_original=cv2.imread(r'

  • Python实现单例模式的四种方式详解

    简介:单例模式可以保证一个类仅有一个实例,并提供一个访问它的全局访问点.适用性于当类只能有一个实例而且客户可以从一个众所周知的访问点访问它,例如访问数据库.MQ等. 实现方式: 1.通过导入模块实现 2.通过装饰器实现 3.通过使用类实现 4.通过__new__ 方法实现 单例模块方式被导入的源码:singleton.py # -*- coding: utf-8 -*- # time: 2022/5/17 10:31 # file: singleton.py # author: tom # 公众

  • Python OpenCV实现图片预处理的方法详解

    目录 一.图片预处理 1.1 边界填充(padding) 1.2 融合图片(mixup) 1.3 图像阈值 二.滤波器 2.1 均值滤波器 2.2 方框滤波器 2.3 高斯滤波器 2.4 中值滤波 2.5 所有滤波器按照上述顺序输出 一.图片预处理 1.1 边界填充(padding) 方法 : cv2.copyMakeBorder BORDER_REPLICATE:复制法,也就是复制最边缘像素. BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abc

  • 用 Python 连接 MySQL 的几种方式详解

    尽管很多 NoSQL 数据库近几年大放异彩,但是像 MySQL 这样的关系型数据库依然是互联网的主流数据库之一,每个学 Python 的都有必要学好一门数据库,不管你是做数据分析,还是网络爬虫,Web 开发.亦或是机器学习,你都离不开要和数据库打交道,而 MySQL 又是最流行的一种数据库,这篇文章介绍 Python 操作 MySQL 的几种方式,你可以在实际开发过程中根据实际情况合理选择. 1.MySQL-python MySQL-python 又叫 MySQLdb,是 Python 连接 M

随机推荐