Opencv中的“暴力”特征匹配和FLANN特征匹配(python实现)

本文详细介绍了图像处理中的关键点检测技术,包括ORB、SURF、SIFT、Shi-Tomasi和Harris角点检测,并探讨了特征匹配的方法,如暴力匹配和FLANN快速邻近搜索。通过代码实战展示了如何使用SIFT特征和BFMatcher进行匹配,以及FLANN匹配器的设置与应用,强调了FLANN在大批量匹配时的速度优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.ORB关键点检测,SURF关键点检测,SIFT关键点检测,Shi-Tomasi角点检测,Harris角点检测

Harris:
https://blog.csdn.net/Keep_Trying_Go/article/details/125384144
Shi-Tomasi:
https://blog.csdn.net/Keep_Trying_Go/article/details/125384218
SIFT:
https://blog.csdn.net/Keep_Trying_Go/article/details/125384278
SURF:
https://blog.csdn.net/Keep_Trying_Go/article/details/125384513
ORB:
https://mydreamambitious.blog.csdn.net/article/details/125384635


2.特征匹配的方法

(1)BF(Brute-Force),暴力特征匹配的方法;
(2)FLANN 最快邻近区特征匹配方法;


3.暴力特征匹配

使用第一组中的每个特征的描述子与第二组中的所有特征描述子进行匹配;计算它们之间的差距,然后将接近一个匹配返回。


4.特征匹配步骤

(1)创建匹配器

Tf=cv2.BFMatcher(normType=None, crossCheck=None):
normType:NORM_L1(L1正则化), NORM_L2(L2正则化——默认值), NORM_HAMMING, NORM_HAMMING2.
crossCheck:是否进行交叉匹配,默认值为false;

(2)进行特征匹配

Tf.match(queryDescriptors, trainDescriptors, mask=None)
参数为SIFT,SURE,ORB,等计算的描述子;对两幅图的描述子进行计算。

(3)进行特征匹配绘制点

drawMatches(img1, keypoints1, img2, keypoints2, matches1to2, outImg, matchColor=None, singlePointColor=None, matchesMask=None, flags=None):

Img1:输入搜索的图
Keypoints1:输入搜索的图kp;
Img2:输入匹配的图
Keypoints2:输入匹配的图kp;
Matches1to2:从第一幅图到第二幅图的匹配
outImg:输出绘制的结果图形
matchColor:匹配连线关键点点的颜色,如果为-1,表示随机颜色
singlePointColor:没有匹配的关键点的颜色,-1代表为随机颜色
matchesMask:确定绘制哪些匹配的掩码,如果为空,这绘制所有的匹配项
Flags:绘图的一些标志
(1)cv2.DRAW_MATCHES_FLAGS_DEFAULT:创建输出图像矩阵,使用现存的输出图像绘制匹配对和特征点,对每一个关键点只绘制中间点
(2)cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG:不创建输出图像矩阵,而是在输出图像上绘制匹配对
(3)cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS:对每一个特征点绘制带大小和方向的关键点图形
(4)cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS:单点的特征点不被绘制

函数返回匹配的结果;


5.代码实战

import os
import cv2

#读取图片和缩放图片
img1=cv2.imread('images/img1.jpg')
img1=cv2.resize(src=img1,dsize=(450,450))
gray1=cv2.cvtColor(src=img1,code=cv2.COLOR_BGR2GRAY)

img2=cv2.imread('images/img2.jpg')
img2=cv2.resize(src=img2,dsize=(450,450))
gray2=cv2.cvtColor(src=img2,code=cv2.COLOR_BGR2GRAY)

#创建SIFT
sift=cv2.xfeatures2d.SIFT_create()
#计算特征点和描述点
kp1,des1=sift.detectAndCompute(gray1,None)
kp2,des2=sift.detectAndCompute(gray2,None)

#创建匹配器
tf=cv2.BFMatcher(cv2.NORM_L1)
#特这点匹配
match=tf.match(des1,des2)
#绘制匹配特征点
dest=cv2.drawMatches(img1=img1,keypoints1=kp1,img2=img2,keypoints2=kp2,matches1to2=match,outImg=None)

cv2.imshow('dest',dest)
cv2.waitKey(0)
cv2.destroyAllWindows()


if __name__ == '__main__':
    print('Pycharm')

在这里插入图片描述


6.FLANN特征匹配

优点:批量特征匹配时,FLANN速度快;
缺点:由于使用的是邻近近似值,所以精度较差;


7.FLANN步骤

(1)创建FLANN匹配器FlannBasedMatches(……)

Index_params字典:匹配算法KDTREE,LSH;
Search_parames字典:指定KDTREE算法中遍历树的次数;
其中KDTREE的设置:
Index_params=dict(
Algorithm=FLANN_INDEX_KDTREE,
Trees=5
)
Search_params=dict(checks=50)

(2)进行特征匹配:flann.match/knnMatch(……)

knnMatch:参数为SIFT,SURE,ORB,等计算的描述子;k表示取欧式距离最近的前k个关键点;返回一个DMatch对象。
其中DMatch中的内容:
Distanc:描述子之间的距离,值越低越好;
queryIdx:第一幅图的描述子索引值;
TrainIdx:第二幅图的描述子索引值;
imgIdx:第二幅图的索引值;


(3)绘制特征匹配点:cv2.drawMatches/drawMatchesKnn(……)

drawMatchesKnn(img1, keypoints1, img2, keypoints2, matches1to2, outImg, matchColor=None, singlePointColor=None, matchesMask=None, flags=None):

Img1:输入搜索的图
Keypoints1:输入搜索的图kp;
Img2:输入匹配的图
Keypoints2:输入匹配的图kp;
Matches1to2:从第一幅图到第二幅图的匹配
outImg:输出绘制的结果图形
matchColor:匹配连线关键点点的颜色,如果为-1,表示随机颜色
singlePointColor:没有匹配的关键点的颜色,-1代表为随机颜色
matchesMask:确定绘制哪些匹配的掩码,如果为空,这绘制所有的匹配项
Flags:绘图的一些标志
(1)cv2.DRAW_MATCHES_FLAGS_DEFAULT:创建输出图像矩阵,使用现存的输出图像绘制匹配对和特征点,对每一个关键点只绘制中间点
(2)cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG:不创建输出图像矩阵,而是在输出图像上绘制匹配对
(3)cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS:对每一个特征点绘制带大小和方向的关键点图形
(4)cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS:单点的特征点不被绘制


8.代码实战

import os
import cv2

#读取图片和缩放图片
img1=cv2.imread('images/img1.jpg')
img1=cv2.resize(src=img1,dsize=(450,450))
gray1=cv2.cvtColor(src=img1,code=cv2.COLOR_BGR2GRAY)

img2=cv2.imread('images/img2.jpg')
img2=cv2.resize(src=img2,dsize=(450,450))
gray2=cv2.cvtColor(src=img2,code=cv2.COLOR_BGR2GRAY)

#创建SIFT
sift=cv2.xfeatures2d.SIFT_create()
#计算特征点和描述点
kp1,des1=sift.detectAndCompute(gray1,None)
kp2,des2=sift.detectAndCompute(gray2,None)

#使用KDTREE算法,树的层级使用5
index_params=dict(algorithm=1,trees=5)
search_params=dict(checks=50)
#创建匹配器
flann=cv2.FlannBasedMatcher(index_params,search_params)
#特征点匹配
match=flann.knnMatch(des1,des2,k=2)
#绘制匹配特征点
good=[]
for i ,(m,n) in enumerate(match):
    if m.distance<0.7*n.distance:
        good.append(m)

dest=cv2.drawMatchesKnn(img1=img1,keypoints1=kp1,img2=img2,keypoints2=kp2,matches1to2=[good],outImg=None,matchColor=(0,255,0))

cv2.imshow('dest',dest)
cv2.waitKey(0)
cv2.destroyAllWindows()


if __name__ == '__main__':
    print('Pycharm')

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值