IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> OpenCv特征匹配 -> 正文阅读

[人工智能]OpenCv特征匹配

OpenCv提供了两种描述符匹配方法:Brute-Force匹配与FLANN匹配

1.Brute-Force匹配

1.1创建BFMatcher对象

1.2使用两个方法:match()或knnMatch()进行描述符匹配?

1.3基于ORB或SIFT的BF匹配

2.FLANN匹配

2.1第一个字典是IndexParams

2.2第二个字典是SearchParams:

2.3FLANN匹配器示例


1.Brute-Force匹配

Brute-Force匹配又称蛮力匹配,?将一组特征点中的每一个特征点描述符与另一组的最接近的特征点描述符匹配。

下面介绍OpenCv中的使用流程:

1.1创建BFMatcher对象

retval = cv.BFMatcher_create([, normType[, crossCheck]])?,参数详解如下

1.normType:NORM_L1,NORM_L2,NORM_HAMMING,NORM_HAMMING2四种可选。

SIFT与SUFT描述符应使用NORM_L1、NORM_L2。ORB、BRISK和BRIEF描述符应该使用NORM_HAMMING。使用ORB描述符但当WTA_K等于3或4时应该选用NORM_HAMMING2。

2.crossCheck:默认为FALSE。如果设置为TRUE,只有当两组中特征点互相匹配时才算匹配成功。也就是说A组中x点描述符的最佳匹配点是B组的y点,那么B组的y点的描述符最佳匹配点也要是A组的x点才算匹配成功。

1.2使用两个方法:match()或knnMatch()进行描述符匹配?

二者的区别是match()返回最佳匹配,knnMathch()返回最佳的k个匹配。

matches = cv.DescriptorMatcher.match( queryDescriptors, trainDescriptors[, mask] )

# 创建BF匹配器对象
bf = cv2.BFMatcher_create(cv2.NORM_HAMMING, crossCheck=True)

# 特征点描述符匹配
matches = bf.match(des1,des2)

# 距离排序
matches = sorted(matches, key = lambda x:x.distance)

# 画出前30匹配
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:30], None, flags=2)

matches = cv.DescriptorMatcher.knnMatch( queryDescriptors, trainDescriptors, k[, mask[, compactResult]] )

**注意,两种方法对应的画点方法也不一样。?

# 创建BF匹配器对象
bf = cv2.BFMatcher_create(cv2.NORM_HAMMING, crossCheck=True)

# 特征点描述符匹配
matches = bf.knnMatch(des1,des2,k=1)

# 画出前30匹配
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches[:30], None, flags=2)

**关于Matcher对象:?

可能会有人好奇返回的变量matches是什么?其实是一种DMatch数据结构的列表。

DMatch结构含有:?

DMatch.distance:描述符之间的距离,越低越好。

DMatch.queryIdx:主动匹配的描述符组中描述符的索引。

DMatch.trainIdx:被匹配的描述符组中描述符的索引。

DMatch.imgIdx:目标图像的索引。

更详细见:

opencv中match与KnnMatch返回值解释?

1.3基于ORB或SIFT的BF匹配

# 使用ORB描述符进行Brute-Force匹配:

import cv2

img1 = cv2.imread('gyy.jpg')

# 设一个ROI为被匹配的图像
ROI = img1[100:350,150:300]
img2=cv2.resize(ROI,None,fx=2,fy=2,interpolation=cv2.INTER_CUBIC)

# 初始化ORB特征点检测器
orb = cv2.ORB_create()

# 检测特征点与描述符
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)

# 创建蛮力(BF)匹配器
bf = cv2.BFMatcher_create(cv2.NORM_HAMMING, crossCheck=True)

# 匹配描述符
matches = bf.match(des1,des2)

# 整理排序匹配后的描述符
matches = sorted(matches, key = lambda x:x.distance)

# 画出前10个匹配的描述符
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=2)

cv2.imshow("show",img3)
cv2.waitKey()
cv2.destroyAllWindows()

# 带有SIFT描述符和比例测试的BF匹配:

import cv2

img1 = cv2.imread('gyy.jpg')

# 设一个ROI为被匹配的图像
ROI = img1[250:350,150:300]             # trainImage
img2=cv2.resize(ROI,None,fx=2,fy=2,interpolation=cv2.INTER_CUBIC)

# 初始化SIFT特征点检测器
sift = cv2.xfeatures2d.SIFT_create()

# 检测特征点与描述符
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)

# 创建蛮力(BF)匹配器
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)

# 比值测试,首先获取与 A 距离最近的点 B(最近)和 C(次近),只有当 B/C
# 小于阈值时( 0.75)才被认为是匹配,因为假设匹配是一一对应的,真正的匹配的理想距离为 0
good = []
for m,n in matches:
    if m.distance < 0.75*n.distance:
        good.append([m])

# cv.drawMatchesKnn()把列表作为匹配项。
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2)

cv2.imshow("show",img3)
cv2.waitKey()
cv2.destroyAllWindows()

2.FLANN匹配

FLANN是近似最近邻的快速库。它包含一组算法,这些算法针对大型数据集中的快速最近邻搜索和高维特征进行了优化。对于大型数据集,它的运行速度比BFMatcher快。

基于FLANN的匹配器,我们需要传递两个字典,这些字典指定要使用的算法,其相关参数等。

2.1第一个字典是IndexParams

对于SIFT、SUFT算法应该是:

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, # 12
                   key_size = 12,     # 20
                   multi_probe_level = 1) #2

2.2第二个字典是SearchParams:

它指定索引中的树应递归遍历的次数。较高的值可提供更好的精度,但也需要更多时间。例如:

search_params = dict(checks = 100)

2.3FLANN匹配器示例

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

img1 = cv.imread('gyy.jpg',cv.IMREAD_GRAYSCALE)    # 索引图像
img2 = cv.imread('gyy.jpg',cv.IMREAD_GRAYSCALE)    # 训练图像

# 初始化SIFT描述符
sift = cv.xfeatures2d.SIFT_create()

# 基于SIFT找到关键点和描述符
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(checks=50)   # 或传递一个空字典
flann = cv.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1,des2,k=2)

# 只需要绘制好匹配项,因此创建一个掩码
matchesMask = [[0,0] for i in range(len(matches))]

# 根据Lowe的论文进行比例测试
for i,(m,n) in enumerate(matches):
    if m.distance < 0.7*n.distance:
        matchesMask[i]=[1,0]
draw_params = dict(matchColor = (0,255,0),
                   singlePointColor = (255,0,0),
                   matchesMask = matchesMask,
                   flags = cv.DrawMatchesFlags_DEFAULT)
img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,**draw_params)

plt.imshow(img3,),plt.show()
  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-08-10 13:25:17  更:2021-08-10 13:26:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 21:33:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码