opencv图像特征检测及匹配(harris,sift,surf,fast,breif,orb,BFmatch,FlannBasedMatcher)

本文简单概括各种算法的提出背景及opencv实现,对具体原理不做讨论


一般而言,一个物体的角点最能够代表物体的特征,所以所谓的特征检测又叫角点(Corner)检测
harris是最早提出的特征提取算法:
opencv实现如下:


dst=cv2.cornerHarris(gray,blockSize=2,ksize=5,k=0.04)
# blockSize -检测的临点数
# •ksize - sobel边缘检测的核
# •k - 目标函数的一个参数(一般取值较小)


sift:harris Corner算法能够解决旋转不变性问题,但不能解决尺度变化问题,由此背景提出了sift算法
opencv实现如下:


sift=cv2.xfeatures2d.SIFT_create()
kp,des=sift.detectAndCompute(gray,None) #计算描述子
其中kp指关键点 des指关键点的特征描述


surf:尽管sift的计算效果较好,但是计算速度较慢 surf(speed up robust features)算法是一个加速算法
速度是sift算法的3倍。
opencv实现如下:


# 400 是Hessian矩阵的阈值,阈值越大能检测的特征就越少
surf=cv2.xfeatures2d.SURF_create(400)
# None为mask参数
kp,des=surf.detectAndCompute(gray,None)


下面结合surf算法做一个简单的测试,上代码:


import cv2
import numpy as np
import matplotlib.pyplot as plt


img=cv2.imread('../images/example_01.jpg')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Here I set Hessian Threshold to 400 阈值越大能检测的特征就越少
surf=cv2.xfeatures2d.SURF_create(400)
# None 为mask参数
kp,des=surf.detectAndCompute(gray,None)


surf.setHessianThreshold(5000)
kp,des=surf.detectAndCompute(gray,None)




img2=cv2.drawKeypoints(img,kp,None,(0,255,0),4)
plt.imshow(img2),plt.title('surf'),plt.xticks([]),plt.yticks([]),plt.show()


上效果:
opencv图像特征检测及匹配(harris,sift,surf,fast,breif,orb,BFmatch,FlannBasedMatcher)_第1张图片

orb算法结合了fast算法与brief算法优点,是目前最快的目标检测算法:
fast算法是特征检测的再提速(能够满足实时检测关键点的要求),breif是特征描述子计算的简化与提速,sift与surf算法
每个关键的特征描述子是128维都是单精度,所以每个描述子占128*4=512bytes的内存,breif每个特征描述子32bytes,大大减少内存,
且运算快(利于嵌入式开发)
orb的opencv实现:
import numpy as np
import cv2
import matplotlib.pyplot as plt


img=cv2.imread('../images/example_01.jpg',0)


orb=cv2.ORB_create()
# kp=orb.detect(img,None)
# kp,des=orb.compute(img,kp)


kp,des=orb.detectAndCompute(img,None)
img2=cv2.drawKeypoints(img,kp,None,(0,255,0),flags=0)
plt.imshow(img2),plt.show()
上效果:
opencv图像特征检测及匹配(harris,sift,surf,fast,breif,orb,BFmatch,FlannBasedMatcher)_第2张图片

特征匹配:
BFmatch(暴力匹配):计算匹配图层的一个特征描述子与待匹配图层的所有特征描述子的距离返回最近距离。
上代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
train=cv2.imread('../images/train.jpg',0)
query=cv2.imread('../images/example_01.jpg',0)
# 暴力匹配
orb=cv2.ORB_create()
kp1,des1=orb.detectAndCompute(train,None)
kp2,des2=orb.detectAndCompute(query,None)
# 针对ORB算法 NORM_HAMMING 计算特征距离 True判断交叉验证
bf=cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True)
# 特征描述子匹配
matches=bf.match(des1,des2)


matches=sorted(matches,key=lambda x:x.distance)
# print(len(matches))
img3=cv2.drawMatches(train,kp1,query,kp2,matches[:20],None,flags=2)
plt.imshow(img3),plt.show()

上效果:

opencv图像特征检测及匹配(harris,sift,surf,fast,breif,orb,BFmatch,FlannBasedMatcher)_第3张图片

FlannBasedMatcher:是目前最快的特征匹配算法(最近邻搜索)
上代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
train=cv2.imread('../images/train.jpg',0)
query=cv2.imread('../images/example_01.jpg',0)


sift=cv2.xfeatures2d.SIFT_create()
kp1,des1=sift.detectAndCompute(train,None)
kp2,des2=sift.detectAndCompute(query,None)


# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(train,None)
kp2, des2 = sift.detectAndCompute(query,None)


# FLANN parameters
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50)   # or pass empty dictionary


flann = cv2.FlannBasedMatcher(index_params,search_params)


matches = flann.knnMatch(des1,des2,k=2)


# Need to draw only good matches, so create a mask
matchesMask = [[0,0] for i in range(len(matches))]


# ratio test as per Lowe's paper

for i,(m,n) in enumerate(matches):

#如果第一个邻近距离比第二个邻近距离的0.7倍小,则保留

    if m.distance < 0.7*n.distance:
        matchesMask[i]=[1,0]


draw_params = dict(matchColor = (0,255,0),
                   singlePointColor = (255,0,0),
                   matchesMask = matchesMask,
                   flags = 0)


img3 = cv2.drawMatchesKnn(train,kp1,query,kp2,matches,None,**draw_params)
plt.imshow(img3,),plt.show()


上效果:

opencv图像特征检测及匹配(harris,sift,surf,fast,breif,orb,BFmatch,FlannBasedMatcher)_第4张图片

你可能感兴趣的:(opencv_python)