opencv-python 基于ORB的特征检测和特征匹配(FAST+BRIEF+BF)笔记
opencv-python 基于ORB的特征检测和特征匹配(FAST+BRIEF+BF)笔记
FAST(Features from Accelerated Segment Test)角点检测:
首先选取一个像素点p,并判断p点是否为关键点。设ip为像素点p的灰度值。
选取适当的阈值t。
如图,对p点周围的16个像素点进行检测。
如果16个点当中存在n个连续的像素点都高于Ip+t或者都小于Ip−t,那么像素点p可看作一个角点。
上图中n为12,如虚线所示。
为了取得更快的速度,对于每个待检测的像素点,使用何种顺序去寻找周围的16个像素点也是有讲究的:
首先先找12点、3点、6点、9点钟方向的四个点,先检测12点和6点钟方向的点,然后是3点和9点钟方向的点。如果p点为角点,那么四个点至少有3个符合要求。如果小于3个,那么p点不是角点。
不过,上面的方法有如下的几条缺点:
1.当n<12时不会舍弃数量过多的候选点
2.像素的选取不是最优的,因为效果取决于问题的要求和角点的分布。
3.高速检测的结果被丢弃
4.检测到的特征点互相连接
前三个问题使用机器学习的手段解决,最后一个问题使用非极大值抑制的方法解决。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('img/lena.jpg')
fast = cv2.FastFeatureDetector_create(threshold=40, nonmaxSuppression=True,
type=cv2.FAST_FEATURE_DETECTOR_TYPE_9_16)# 获取FAST角点探测器
kp = fast.detect(img, None)
img = cv2.drawKeypoints(img, kp, img, color=(255, 0, 255))
print(len(kp))
cv2.imshow('sp', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
BRIEF(Binary Robus Independent Elementary Features)描述子:
我们知道SIFT使用128-dim向量作为描述符,由于它使用浮点数,因此基本上需要512个字节,类似地,SURF也至少需要256个字节(对于64-dim),为数千个特征创建这样的向量需要大量的内存,这对于资源约束应用程序尤其是嵌入式系统是不可行的,内存越大,匹配所需的时间越长.
BRIEF:一种对已检测到的特征点进行描述的算法,它是一种二进制编码的描述子,在图像匹配时使用BRIEF能极大的提升匹配速度.
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('img/img.jpg')
# FAST探测器
star = cv2.xfeatures2d.StarDetector_create()
# BRIEF提取器
brief = cv2.xfeatures2d.BriefDescriptorExtractor_create()
# 用STAR找到关键点
kp = star.detect(img, None)
# 用BRIEF计算探测器的值
kp, des = brief.compute(img, kp)
print(brief.descriptorSize())
print(des.shape)
Brute-Force(暴力匹配法):
暴力匹配法是一种描述符匹配方法,该方法会比较两个描述符,并产生匹配结果的列表。称为暴力匹配的原因是该算法基本上不涉及优化,第一个描述符的所有特征都用来和第二个描述符的特征进行比较。每次比较都会给出一个距离值,而最好的比较结果会被认为是一个匹配。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img1 = cv2.imread('img/box.png', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('img/box_in_scene.png', cv2.IMREAD_GRAYSCALE)
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
# Brute-Force暴力匹配法
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x:x.distance)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[0:10], img2, flags=2)
plt.imshow(img3), plt.show()
参考文章:
https://blog.csdn.net/tengfei461807914/article/details/79492012
https://segmentfault.com/a/1190000015731950
上一篇: 阿里云基于OSS的云上统一数据保护方案2.0技术解析 c申诉游戏情感
下一篇: 简单的CAS单点登录