此opencv系列博客只是为了记录本人对<<opencv3计算机视觉-pyhton语言实现>>的学习笔记,所有代码在我的github主页https://github.com/RenDong3/OpenCV_Notes.
欢迎star,不定时更新...
之前我们已经介绍了SIFT算法,以及SURF算法,但是由于计算速度较慢的原因。人们提出了使用ORB来替代SIFT和SURF。与前两者相比,ORB有更快的速度。ORB在2011年才首次发布。在前面小节中,我们已经提到了ORB算法。ORB算法将基于FAST关键点的技术和基于BRIEF描述符的技术相结合,但是ORB并没有解决尺度不一致的问题,在OpenCV的ORB实现中采用了图像金字塔来改善这方面的性能,我们通过构建高斯金字塔,然后在每一层金字塔图像上检测角点,来实现尺度不变性。ORB主要解决了BRIEF描述子不具备旋转不变性的问题.
OpenCV实现
ORB中有很多参数可以设置,在OpenCV中它可以通过ORB来创建一个ORB检测器。
cv2.ORB([nfeatures[, scaleFactor[, nlevels[, edgeThreshold[, firstLevel[, WTA_K[, scoreType[, patchSize]]]]]]]]) → <ORB object>
参数说明:
- nfeatures :最多提取的特征点的数量;
- scaleFactor : 金字塔图像之间的尺度参数,类似于SIFT中的kk;
- nlevels: 高斯金字塔的层数;
- edgeThreshold :边缘阈值,这个值主要是根据后面的patchSize来定的,靠近边缘edgeThreshold以内的像素是不检测特征点的。
- firstLevel-:看过SIFT都知道,我们可以指定第一层的索引值,这里默认为0。
- WET_K : 用于产生BIREF描述子的点对的个数,一般为2个,也可以设置为3个或4个,那么这时候描述子之间的距离计算就不能用汉明距离了,而是应该用一个变种。OpenCV中,如果设置WET_K = 2,则选用点对就只有2个点,匹配的时候距离参数选择NORM_HAMMING,如果WET_K设置为3或4,则BIREF描述子会选择3个或4个点,那么后面匹配的时候应该选择的距离参数为NORM_HAMMING2。
- scoreType :用于对特征点进行排序的算法,你可以选择HARRIS_SCORE,也可以选择FAST_SCORE,但是它也只是比前者快一点点而已。
- patchSize :用于计算BIREF描述子的特征点邻域大小。
完整代码如下:
# -*- coding:utf-8 -*-
import os
import cv2
import numpy as np
'''
created on 09:05:10 2018-11-22
@author ren_dong
使用ORB特征匹配
'''
def orb_test():
# 加载图片 灰色
img1 = cv2.imread('orb1.jpg')
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
img2 = cv2.imread('orb2.jpg')
img2 = cv2.resize(img2, dsize=(450, 300))
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
image1 = gray1.copy()
image2 = gray2.copy()
'''
1.使用ORB算法检测特征点、描述符
'''
orb = cv2.ORB_create(128)
keypoints1, descriptors1 = orb.detectAndCompute(image1, None)
keypoints2, descriptors2 = orb.detectAndCompute(image2, None)
# 在图像上绘制关键点
image1 = cv2.drawKeypoints(image=image1, keypoints=keypoints1, outImage=image1, color=(255, 0, 255),
flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
image2 = cv2.drawKeypoints(image=image2, keypoints=keypoints2, outImage=image2, color=(255, 0, 255),
flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# 显示图像
cv2.imshow('orb_keypoints1', image1)
cv2.imshow('orb_keypoints2', image2)
cv2.waitKey(20)
'''
2、匹配
'''
##使用暴力匹配进行描述符的匹配
matcher = cv2.BFMatcher_create(cv2.HAMMING_NORM_TYPE, crossCheck=True)
matchePoints = matcher.match(descriptors1, descriptors2)
print(type(matchePoints), len(matchePoints), matchePoints[0])
# 按照距离从小到大排序,选取最优匹配的
sorted(matchePoints, key=lambda x: x.distance)
# 绘制最优匹配点
outImg = None
outImg = cv2.drawMatches(img1, keypoints1, img2, keypoints2, matchePoints[:40], outImg, matchColor=(0, 255, 0),
flags=cv2.DRAW_MATCHES_FLAGS_DEFAULT)
cv2.imshow('matche', outImg)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == '__main__':
orb_test()
运行结果如图:
因为选择的图标相似性很明显,所以这里调用ORB进行特征匹配的效果还不错,另外想要了解更多原理的小伙伴可以去大神博客围观哦,下面是地址https://www.cnblogs.com/zyly/p/9622873.html
因为呢好不容易有点空闲时间,所以赶紧把之前几天看到相关特征匹配算法进行了汇总发布,好记性不如烂博客啊,所以可能有些地方有瑕疵,欢迎指正,另外还是要感谢一下大神哦...