0.前言
昨天看了关于SLAM的综述文章一篇,对于其中提到的SIFT,SURF,ORB三种特征提取匹配的方法,非常想要实践学习其Python的编写方法。同时我爸让我帮他写一个树莓派(raspberry pi)检测黑点的程序,黑点有什么好检测的(╯•̀ὤ•́)╯,考虑到神经网络识别计算复杂度过高,我决定用模板匹配法去做。
1.程序汇总
链接: https://pan.baidu.com/s/1dXqLmXQBNA9tshokU4nSgA 提取码: fws5
2.预备工作
首先我们应该明确,怎么开发这个程序最快。肯定是用opencv,所以读了《OpenCV3计算机视觉Python语言实现》,获得了相关程序与图片。然后于Linux下安装opencv。
3.学习特征提取与匹配方法
3.1SIFT特征提取
先学习的是SIFT。使用书中的程序;
import cv2
import sys
import numpy as np
imgpath = sys.argv[1]
img = cv2.imread(imgpath)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create()
keypoints, descriptor = sift.detectAndCompute(gray,None)
img = cv2.drawKeypoints(image=img, outImage=img, keypoints = keypoints, flags = 4, color = (51, 163, 236))
cv2.imshow('sift_keypoints', img)
while (True):
if cv2.waitKey(1000/12) & 0xff == ord("q"):
break
cv2.destroyAllWindows()
有两个问题: 其一,Anaconda使用run file按钮无法添加输入内容,也就是argv[1]。所以直接从右下窗口输入:
runfile('/home/emin/Temp/Tensorflow/pycv-master/chapter6/sift.py',args='/home/emin/Temp/Tensorflow/pycv-master/images/varese.jpg', wdir='/home/emin/Temp/Tensorflow/pycv-master/chapter6')
也就是带输入的运行文件。 其二,产生如下问题:
if cv2.waitKey(1000 / 12) & 0xff == ord("q"):
TypeError: integer argument expected, got float
这个百度后明白了原程序的意思应该是等待键位按下,出现问题是1000/12产生了浮点,改为:
if cv2.waitKey(1) & 0xff == ord("q"):
问题解决,生成了SIFT特征提取图像。
3.2SIRF特征提取
同理3.1,修改程序后,通过Ipython consolo命令输入arg运行。
import cv2
import sys
import numpy as np
imgpath = sys.argv[1]
img = cv2.imread(imgpath)
alg = sys.argv[2]
def fd(algorithm):
algorithms = {
"SIFT": cv2.xfeatures2d.SIFT_create(),
"SURF": cv2.xfeatures2d.SURF_create(float(sys.argv[3]) if len(sys.argv) == 4 else 4000),
}
return algorithms[algorithm]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
fd_alg = fd(alg)
keypoints, descriptor = fd_alg.detectAndCompute(gray,None)
img = cv2.drawKeypoints(image=img, outImage=img, keypoints = keypoints, flags = 4, color = (51, 163, 236))
cv2.imshow('keypoints', img)
while (True):
if cv2.waitKey(1) & 0xff == ord("q"):
break
cv2.destroyAllWindows()
由于需要输入双参数,进行模式的选择,所以使用命令:
runfile('/home/emin/Temp/Tensorflow/pycv-master/chapter6/surf+sift.py',args='/home/emin/Temp/Tensorflow/pycv-master/images/varese.jpg SURF', wdir='/home/emin/Temp/Tensorflow/pycv-master/chapter6')
两个arg之间使用了空格。
3.3ORB特征提取与匹配
这里使用的是自己的图片,所以拍摄的尺寸较大,要进行压缩,程序结果如下。
import numpy as np
import cv2
from matplotlib import pyplot as plt
# query and test images
img1 = cv2.imread('/home/emin/Temp/3.jpg',0)
img2 = cv2.imread('/home/emin/Temp/4.jpg',0)
# create the ORB detector
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)
# brute force matching
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1,des2)
# Sort by distance.
matches = sorted(matches, key = lambda x:x.distance)
img3 = cv2.drawMatches(img1,kp1,img2,kp2, matches[:25], img2,flags=2)
img3 = cv2.resize(img3, (1000,800), interpolation=cv2.INTER_AREA)
cv2.imshow('orb_result', img3)
while (True):
if cv2.waitKey(1) & 0xff == ord("q"):
break
cv2.destroyAllWindows()
#plt.imshow(img3),plt.show()
将匹配对应的点数量增加。