opencv-python 基于ORB的特征检测和特征匹配(FAST+BRIEF+BF)笔记

mac2026-05-08  2

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

最新回复(0)