using namespace cv;
//由图像得到FAST特征点(先得到候选点,进行非极大值抑制,计算Harris评分)
/*基本思想:
* 1、遍历每个像素点,以像素点为中心,半径上的16个点,计算与中心点的灰度差,若灰度差小于阈值,则选为候选点集;
* 使用小技巧加速该算法,这里取设定数目为12。
(1)判断点1和点9灰度值与点p差值绝对值是否都大于阈值,如果是则继续;否则pass该点
(2)判断点1、点5、点9、点13四点与点p灰度值差值大于阈值的数目是否大于2,如果是则继续;否则pass该点
(3)判断圆周上16点与点p灰度值差值大于阈值的数目是否不小于12,如果是则认为该点是候选点;否则pass该点
对图像中所有像素点进行上述操作后,得到候选点点集
*/
int sumDelta(uchar* delta, int size)
{
int sum = 0;
for (int i = 0; i < size; i++)
{
sum += *delta;
delta++;
}
return sum;
}
void fastDector(Mat& image)
{
Mat featureCandidate(image.size(), CV_8U, Scalar(0));
Mat fastScore(image.size(), CV_32F, Scalar(0));
int threshold = 20;
vector points;
int size = 16;
for (int x = 3; x < image.rows - 3; x++)
{
for(int y = 3; y < image.cols - 3; y++)
{
//定义数组存放偏差
uchar diff[16] = {0};
uchar delta[16] = {0};
delta[0] = (diff[0] = abs(image.at(x, y) - image.at(x, y - 3)) > threshold);
delta[8] = (diff[8] = abs(image.at(x, y) - image.at(x, y + 3)) > threshold);
if (sumDelta(delta, size) ==0 )
continue;
else
{
delta[4] = (diff[4] = abs(image.at(x, y) - image.at(x - 3, y)) > threshold);
delta[12] = (diff[12] = abs(image.at(x, y) - image.at(x + 3, y)) > threshold);
if (sumDelta(delta, size) < 3)
continue;
else
{
delta[1] = (diff[1] = abs(image.at(x,y) - image.at(x+1, y-3))) > threshold;
delta[2] = (diff[2] = abs(image.at(x,y) - image.at(x+2, y-2))) > threshold;
delta[3] = (diff[3] = abs(image.at(x,y) - image.at(x+3, y-1))) > threshold;
delta[5] = (diff[5] = abs(image.at(x,y) - image.at(x+3, y+1))) > threshold;
delta[6] = (diff[6] = abs(image.at(x,y) - image.at(x+2, y+2))) > threshold;
delta[7] = (diff[7] = abs(image.at(x,y) - image.at(x+1, y+3))) > threshold;
delta[9] = (diff[9] = abs(image.at(x,y) - image.at(x-1, y+3))) > threshold;
delta[10] = (diff[10] = abs(image.at(x,y) - image.at(x-2, y+2))) > threshold;
delta[11] = (diff[11] = abs(image.at(x,y) - image.at(x-3, y+1))) > threshold;
delta[13] = (diff[13] = abs(image.at(x,y) - image.at(x-3, y-1))) > threshold;
delta[14] = (diff[14] = abs(image.at(x,y) - image.at(x-2, y-2))) > threshold;
delta[15] = (diff[15] = abs(image.at(x,y) - image.at(x-1, y-3))) > threshold;
if (sumDelta(delta, size) >= 12)
{
points.push_back(Point(y, x));
fastScore.at(x, y) = (sumDelta(delta, size));
featureCandidate.at(x, y) = 255;
}
}
}
}
}
vector::const_iterator itp = points.begin();
Mat image1;
image.copyTo(image1);
while(itp != points.end())
{
circle(image1, *itp, 3, Scalar(255), 1);
++itp;
}
imshow("筛选前", image1);
waitKey(0);
imwrite("筛选前.png", image1);
//利用膨胀与比较的组合实现非极大值的抑制
Mat image2;
image.copyTo(image2);
Mat dilated(fastScore.size(), CV_32F, Scalar(0));
Mat localMax;
dilate(fastScore, dilated, Mat());
compare(fastScore, dilated, localMax, CMP_EQ);
bitwise_and(featureCandidate, localMax, featureCandidate);
for(int x = 0; x < featureCandidate.rows; x++)
{
for(int y = 0; y < featureCandidate.cols; y++)
{
if (featureCandidate.at(x, y))
{
circle(image2, Point(y, x), 3, Scalar(255), 1);
}
}
}
imshow("极大值抑制", image2);
imwrite("极大值抑制.png", image2);
}
#include "opencv2/opencv.hpp"
#include "../include/orb.h"
using namespace cv;
int main(int argc, char**argv)
{
Mat image = imread("imgL.jpg", 0);
fastDector(image);
return 0;
}
参考链接:
https://blog.csdn.net/lwx309025167/article/details/80234307
包含fast的改进
https://www.cnblogs.com/Wiley-hiking/p/6901486.html?utm_source=itdadao&utm_medium=referral