原理:取图像中的监测点,以该店为圆心的周围邻域内像素点判断是否为角点。(如果一个像素周围有一定数量的像素与该点像素值不同,则认为该点是角点)
基本流程:
- 遍历图像中所有像素点p,判断是否是关键点。I为p点灰度值。
- 以r为半径画圆,覆盖p点周围的M个像素(一般r = 3, M = 16)。
- 设置阈值t,如果M个像素中有n个连续像素点的灰度值都该与“ I + t ”,或者低于“ I + t”则认为p是交点。
- 非特征点判别方法:首先对候选点周围90°的点进行测试,如果p是角点,那么这4ge90°的点中至少有3个符合要求,否则剔除。
缺点:
- 获得的候选点多
- 特征点选取不是最优
- 进行非特征点判别时大量的点被丢弃
前三个可以利用机器学习进行解决
- 检测到很多的特征点都是相邻的
最后一个可以利用非极大值抑制进行解决
将p点与周围16个点进行求差取模累加,将获得时值V与16个候选交点进行比较,将V值较小的候选角点进行剔除
# 实例化
fastv = cv.FastFeatureDetector_create(threshold, nonmasSuppression)
# threshold:阈值,默认为10
# nonmasSuppression:是否进行极大值抑制,默认为True
# 返回一个FastFeatureFetector对象
kp = fast.detect(grayImg, None)
# grayImy:灰度图像
# kp:关键点信息(位置、尺度、方向信息)
# 关键点绘制
cv.drawKeyPoints(img, keypoint, outputImg, color, flags)
# img:绘制图像
# keypoint:关键点
# outputImg:输出图像
# color:绘制颜色
# flag:绘制标识
代码实现:
import cv2 as cv
# 读取图像,转换成灰度图
img = cv.imread('img/25.png')
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# Fast检测
fast = cv.FastFeatureDetector_create(threshold=30)
# 检测guanjiandian
kp = fast.detect(img, None)
# 绘制检测结果
cv.drawKeypoints(img, kp, img, color=(0, 0, 255))
cv.imshow("Max-Img", img)
cv.waitKey(0)
# 关闭非极大值抑制
fast.setNonmaxSuppression(0)
kp = fast.detect(img, None)
img1 = cv.drawKeypoints(img, kp, img, color=(0, 0, 255))
cv.imshow("NoMax-Img", img1)
cv.waitKey(0)
非极大值抑制处理:
没有经过非极大值处理:(给我看出密集恐惧症了都)
算法步骤
- 图像过滤:原始图像存在噪声时,会对结果产生影响,需要对图像进行滤波和降噪处理。
- 选取点对:以特征点为中心,取S*S的邻域窗口,在窗口内随机选取N组点对(128、256、512),默认是256,如果选取随机点对,如下:
- x、y方向平均分布采样
- x、y服从Guass(0,S^2/25)各向同性
- x服从Guass(0,S2/25),y服从Guass(0,S2/100)采样
- x、y从网络中随机获取
- x一直在(0,0),y在网络中随机选取
- 构建描述符:假设x、y时某个点对的两个端点,p(x),p(y)时两点对应像素,则有:
对每一个点对进行上述的二进制赋值,行程BRIEF的关键点的描述特征向量(一般为128-512位的字符串,其中仅包含1和0)
# 实例化
orb = cv.xfeature2d.orb_create(nfeature)
# nfeature: 特征点的最大数量
# 检测关键点并计算
kp, des = orb.detectAndCompute(gray, None)
# gray:输入的灰度图像
# kp:关键点信息(位置、方向、尺度)
# des:关键点描述符,每个关键点BRIEF特征向量,二进制字符串
# 关键点绘制
cv.drawKeyPoints(img, keypoint, outputImg, color, flags)
# img:绘制图像
# keypoint:关键点
# outputImg:输出图像
# color:绘制颜色
# flag:绘制标识
代码测试
import cv2 as cv
# 读取图像,转换成灰度图
img = cv.imread('img/25.png')
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# ORB检测,1000个关键点数量
orb = cv.ORB_create(nfeatures=1000)
# 检测guanjiandian
kp, des = orb.detectAndCompute(img, None)
# 绘制检测结果
img1 = cv.drawKeypoints(img, kp, img, color=(0, 0, 255), flags=0)
cv.imshow("ORB-Img", img1)
cv.waitKey(0)