在进行嵌入式开发的过程中,对于图像特征点的提取及匹配一直是一个重点问题,之前我们通过C++进行对应的orb特征点的匹配提取,本次博客,林君学长将带大家了解如何通过python实现SIFT和ORB两钟方法的特征点提取,理解sift 和orb在尺度缩放、旋转、仿射图上面的特征不变性,并进行两种提取方法的速度比较,一起来看吧!
一、python终端安装需要的图像处理库
1、打开终端,安装opencv-python
1)、安装opencv-python库
pip install --user opencv-python==3.4.2.16
2)、安装opencv-contrib-python库
pip install --user opencv-contrib-python==3.4.2.16
由于林君学长已经下载,上面出现的界面是下载好了的
2、如果之前安装其他版本操作步骤
由于sift的特征提取及匹配需要用的opencv-python版本需要的是低版本,而之前我们默认安装的是最新版本的opencv-python,所以我们需要卸载后重新安装,具体步骤如下所示:
1)、卸载opencv-contrib-python及opencv-python库
pip uninstall opencv-contrib-python
pip uninstall opencv-python
2)、重新安装opencv-contrib-python及opencv-python库
pip install --user opencv-python==3.4.2.16
pip install --user opencv-contrib-python==3.4.2.16
3、准备图片数据
1)、需要选择一张原图
2)、对原图进行旋转
3)、对原图进行缩略
4)、原图变换为仿射图
对于仿射图的变换,林君学长后面会给出代码,这里给出仿射图的结果展示:
以上的图片制作比较简单,可以用windows自带的画图板进行修改得到,这里就不讲解制作过程了!
在一切准备妥当之后,我们就可以开始特征点提取和匹配了哦!
二、SIFT特征提取及匹配
1、导入需要的python库
import numpy as np
import cv2
from matplotlib import pyplot as plt
import time
%matplotlib inline
以上导入库的功能相对简单,林君学长这里就不给出具体介绍了
2、导入图片
读取原图、旋转图、缩略图
img1 = cv2.imread('D:/image/1.jpg')#读取原图片
img2 = cv2.imread('D:/image/2.jpg')#读取旋转图片
img3 = cv2.imread('D:/image/3.jpg')#读取缩放图片
3、构建仿射图
#构建放射图
img = cv2.imread('D:/image/1.jpg')
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
rows, cols, ch = img.shape
pts1 = np.float32([[0, 0], [cols - 1, 0], [0, rows - 1]])
pts2 = np.float32([[cols * 0.2, rows * 0.1], [cols * 0.9, rows * 0.2], [cols * 0.1, rows * 0.9]])
M = cv2.getAffineTransform(pts1, pts2)
dst = cv2.warpAffine(img, M, (cols, rows))
放射图主要通过代码生成,以上dst就为仿射图,显示可通过传递dst参数便可以显示
4、将img转换为RGB格式,避免色差
#使用cv2.imread()接口读图像,读进来的是BGR格式以及[0~255]。所以要将img转换为RGB格式,不然后面显示会有色差
img1 = cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) #灰度处理图像
img2 = cv2.cvtColor(img2,cv2.COLOR_BGR2RGB)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
img3 = cv2.cvtColor(img3,cv2.COLOR_BGR2RGB)
gray3 = cv2.cvtColor(img3, cv2.COLOR_BGR2GRAY)
img4 = cv2.cvtColor(dst,cv2.COLOR_BGR2RGB)
gray4 = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)
5、SIFT特征提取及提取时间计算
1)、SIFT对四张图片的特征提取及提取时间计算
#sift 特征提取
a=time.time()
sift1 = cv2.xfeatures2d.SIFT_create()
kp1, des1 = sift1.detectAndCompute(img1,None)
kp2, des2 = sift1.detectAndCompute(img2,None)
kp3, des3 = sift1.detectAndCompute(img3,None)
kp4, des4 = sift1.detectAndCompute(img4,None)
b=time.time()
print("sift提取时间为:",b-a)
2)、SIFT对于原图片的特征提取展示
img11 = cv2.drawKeypoints(img1,kp1,img1,color=(255,0,255))
plt.figure(num=1,figsize=(16,16))
plt.imshow(img11)
plt.title('Left:yuan---Right:yuan')
plt.axis('off')
plt.show()
3)、SIFT对于旋转图片的特征提取展示
img12 = cv2.drawKeypoints(img2,kp2,img2,color=(255,0,255))
plt.figure(num=1,figsize=(16,16))
plt.imshow(img12)
plt.title('Left:yuan---Right:xuanzhuan')
plt.axis('off')
plt.show()
4)、SIFT对于缩略图的特征提取展示
img13 = cv2.drawKeypoints(img3,kp3,img3,color=(255,0,255))
plt.figure(num=1,figsize=(16,16))
plt.imshow(img13)
plt.title('Left:yuan---Right:suolue')
plt.axis('off')
plt.show()
5)、SIFT对于仿射图的特征提取展示
img14 = cv2.drawKeypoints(img4,kp4,img4,color=(255,0,255))
plt.figure(num=1,figsize=(16,16))
plt.imshow(img14)
plt.title('Left:yuan---Right:fangshe')
plt.axis('off')
plt.show()
6、SIFT特征匹配
1)、FLANN 参数设计
# FLANN 参数设计
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params,search_params)
2)、SIFT对于原图片与原图片的特征匹配
#原图与原图的匹配连线效果图展示
matches = flann.knnMatch(des1,des1,k=2)
matchesMask = [[0,0] for i in range(len(matches))]
good = []
for m,n in matches:
if m.distance < 0.7*n.distance:
good.append([m])
img41 = cv2.drawMatchesKnn(img1,kp1,img1,kp1,good,None,flags=2)
plt.figure(num=1,figsize=(16,16))
plt.imshow(img41)
plt.title('Left:yuan---Right:yuan')
plt.axis('off')
plt.show()
3)、SIFT对于原图片与旋转图片的特征匹配
#原图与旋转图的匹配连线效果图展示
matches = flann.knnMatch(des1,des2,k=2)
matchesMask = [[0,0] for i in range(len(matches))]
good = []
for m,n in matches:
if m.distance < 0.7*n.distance:
good.append([m])
img42 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2)
plt.figure(num=1,figsize=(16,16))
plt.imshow(img42)
plt.title('Left:yuan---Right:xuanzhuan')
plt.axis('off')
plt.show()
4)、SIFT对于原图片与缩略图的特征匹配
#原图与缩略图的匹配连线效果图展示
matches = flann.knnMatch(des1,des3,k=2)
matchesMask = [[0,0] for i in range(len(matches))]
good = []
for m,n in matches:
if m.distance < 0.7*n.distance:
good.append([m])
img43 = cv2.drawMatchesKnn(img1,kp1,img3,kp3,good,None,flags=2)
plt.figure(num=1,figsize=(16,16))
plt.imshow(img43)
plt.title('Left:yuan---Right:suolue')
plt.axis('off')
plt.show()
5)、SIFT对于原图片与仿射图的特征匹配
#原图与放射图的匹配结果显示
matches = flann.knnMatch(des1,des4,k=2)
matchesMask = [[0,0] for i in range(len(matches))]
good = []
for m,n in matches:
if m.distance < 0.7*n.distance:
good.append([m])
img44 = cv2.drawMatchesKnn(img1,kp1,img4,kp4,good,None,flags=2)
plt.figure(num=1,figsize=(16,16))
plt.imshow(img44)
plt.title('Left:yuan---Right:fangshe')
plt.axis('off')
plt.show()
以上就是SIFT的体征提取及匹配啦,可以看到,SIFT的特征点提取的还是非常多的,接下来我们看那一下ORB特征点的提取及匹配并做一定的对比
三、ORB特征提取及匹配
1、导入图片
img10 = cv2.imread('D:/image/1.jpg')#读取原图片
img20 = cv2.imread('D:/image/2.jpg')#读取旋转图片
img30 = cv2.imread('D:/image/3.jpg')#读取缩放图片
2、构建仿射图
通过原图片构建缩略图
#构建放射图
img = cv2.imread('D:/image/1.jpg')
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
rows, cols, ch = img.shape
pts1 = np.float32([[0, 0], [cols - 1, 0], [0, rows - 1]])
pts2 = np.float32([[cols * 0.2, rows * 0.1], [cols * 0.9, rows * 0.2], [cols * 0.1, rows * 0.9]])
M = cv2.getAffineTransform(pts1, pts2)
dst = cv2.warpAffine(img, M, (cols, rows))
其中dst即为我们需要的仿射图
3、将img转换为RGB格式,避免色差
#使用cv2.imread()接口读图像,读进来的是BGR格式以及[0~255]。所以要将img转换为RGB格式,不然后面显示会有色差
img1 = cv2.cvtColor(img10,cv2.COLOR_BGR2RGB)
gray1 = cv2.cvtColor(img10, cv2.COLOR_BGR2GRAY) #灰度处理图像
img2 = cv2.cvtColor(img20,cv2.COLOR_BGR2RGB)
gray2 = cv2.cvtColor(img20, cv2.COLOR_BGR2GRAY)
img3 = cv2.cvtColor(img30,cv2.COLOR_BGR2RGB)
gray3 = cv2.cvtColor(img30, cv2.COLOR_BGR2GRAY)
img4 = cv2.cvtColor(dst,cv2.COLOR_BGR2RGB)
gray4 = cv2.cvtColor(dst,cv2.COLOR_BGR2GRAY)
4、ORB特征提取及提取时间计算
1)、ORB特征提取及提取时间计算
#ORB 特征提取
a=time.time()
sift2 = cv2.ORB_create()
kp1, des1 = sift2.detectAndCompute(img1,None)
kp2, des2 = sift2.detectAndCompute(img2,None)
kp3, des3 = sift2.detectAndCompute(img3,None)
kp4, des4 = sift2.detectAndCompute(img4,None)
b=time.time()
print("ORB提取时间为:",b-a)
2)、ORB对于原图片的特征提取
img11 = cv2.drawKeypoints(img1,kp1,img1,color=(255,0,255))
plt.figure(num=1,figsize=(16,16))
plt.imshow(img11)
plt.title('Left:yuan---Right:yuan')
plt.axis('off')
plt.show()
3)、ORB对于旋转图片的特征提取
img12 = cv2.drawKeypoints(img2,kp2,img2,color=(255,0,255))
plt.figure(num=1,figsize=(16,16))
plt.imshow(img12)
plt.title('Left:yuan---Right:xuanzhuan')
plt.axis('off')
plt.show()
4)、ORB对于缩略图的特征提取
img13 = cv2.drawKeypoints(img3,kp3,img3,color=(255,0,255))
plt.figure(num=1,figsize=(16,16))
plt.imshow(img13)
plt.title('Left:yuan---Right:suolue')
plt.axis('off')
plt.show()
5)、ORB对于仿射图的特征提取
img14 = cv2.drawKeypoints(img4,kp4,img4,color=(255,0,255))
plt.figure(num=1,figsize=(16,16))
plt.imshow(img14)
plt.title('Left:yuan---Right:fangshe')
plt.axis('off')
plt.show()
5、ORB特征匹配
1)、ORB对于原图片与原图片的特征匹配
#原图与原图的匹配连线效果图展示
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True) # orb的normType应该使用NORM_HAMMING
matches = bf.match(des1, des1)
matches = sorted(matches, key=lambda x: x.distance)
knnMatches = bf.knnMatch(des1, des1, k = 1) # drawMatchesKnn
for m in matches:
for n in matches:
if(m != n and m.distance >= n.distance*0.75):
matches.remove(m)
break
img = cv2.drawMatches(img1, kp1, img1, kp1, matches[:50], img1, flags=2)
plt.figure(num=1,figsize=(16,16))
plt.imshow(img)
plt.title('Left:yuan---Right:yuan')
plt.axis('off')
plt.show()
2)、ORB对于原图片与旋转图片的特征匹配
#原图与旋转图的匹配连线效果图展示
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True) # orb的normType应该使用NORM_HAMMING
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
knnMatches = bf.knnMatch(des1, des2, k = 1) # drawMatchesKnn
for m in matches:
for n in matches:
if(m != n and m.distance >= n.distance*0.75):
matches.remove(m)
break
img = cv2.drawMatches(img1, kp1, img2, kp2, matches[:50], img2, flags=2)
plt.figure(num=1,figsize=(16,16))
plt.imshow(img)
plt.title('Left:yuan---Right:xuanzhuan')
plt.axis('off')
plt.show()
3)、ORB对于原图片与缩略图的特征匹配
#原图与缩略图的匹配连线效果图展示
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True) # orb的normType应该使用NORM_HAMMING
matches = bf.match(des1, des3)
matches = sorted(matches, key=lambda x: x.distance)
knnMatches = bf.knnMatch(des1, des3, k = 1) # drawMatchesKnn
for m in matches:
for n in matches:
if(m != n and m.distance >= n.distance*0.75):
matches.remove(m)
break
img = cv2.drawMatches(img1, kp1, img3, kp3, matches[:50], img3, flags=2)
plt.figure(num=1,figsize=(16,16))
plt.imshow(img)
plt.title('Left:yuan---Right:suolue')
plt.axis('off')
plt.show()
4)、ORB对于原图片与射图的特征匹配
#原图与仿射图的匹配连线效果图展示
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True) # orb的normType应该使用NORM_HAMMING
matches = bf.match(des1, des4)
matches = sorted(matches, key=lambda x: x.distance)
knnMatches = bf.knnMatch(des1, des4, k = 1) # drawMatchesKnn
for m in matches:
for n in matches:
if(m != n and m.distance >= n.distance*0.75):
matches.remove(m)
break
img = cv2.drawMatches(img1, kp1, img4, kp4, matches[:50], img4, flags=2)
plt.figure(num=1,figsize=(16,16))
plt.imshow(img)
plt.title('Left:yuan---Right:fangshe')
plt.axis('off')
plt.show()
四、SIFT及ORB特征提取及匹配分析
1、提取时间分析
两种方法的提取时间如下所示:
1)、SIFT提取时间
2)、ORB提取时间
从提取时间上来看ORB的提取时间很短,大约是SIFT提取方法的十分之一,这也是ORB特征提取方法的优越性,同时,ORB在尺度缩放、旋转、仿射上的特征点不变,具有不变性
2、提取特征点分析
1)、SIFT提取点提取
2)、ORB提取点提取
从特征点提取特征来看,SIFT提取的特征点非常多,趋近于实物,准确性非常高,这也是SIFT提取方法的优越性,同时,SIFT在尺度缩放、旋转、仿射上的特征点不变,具有不变性!
以上就是本次博客的全部内容啦,希望小伙伴们对本次博客的阅读可以帮助大家理解python中,如何进行sfit及orb特征点提取及匹配,了解在尺度缩放、旋转、仿射上的特征点不变原则!
遇到问题的小伙伴记得评论区留言,林君学长看到会为大家解答的,这个学长不太冷!
陈一月的又一天编程岁月^ _ ^
转载:https://blog.csdn.net/qq_42451251/article/details/106366675