文章目录
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')