参考:https://blog.csdn.net/qq_33898609/article/details/105458599
FAST角点的主要优势就是速度快,比SIFT快了几乎一个数量级,从而可以满足SLAM实时性的要求。
Shi-Tomas角点是vins-mono中使用的角点。
下面我对这两种角点在检测上的速度和能够检测到的最大角点数量进行了对比。
使用两种角点对KITTI数据集中的28帧图片进行检测,检测结果如下:
下图显示了ShiTomas角点检测到的角点数量及其花费的时间。
Shi-Tomas
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <chrono>
using namespace cv;
using namespace std;
//描述:定义一些辅助宏
#define WINDOW_NAME "【Shi-Tomasi角点检测】"
int main(int acgc , char* acgv[])
{
vector<String> files; //存放文件路径
vector<Mat> images; //存放文件数据
Mat after_fast_image,img;
std::vector<cv::KeyPoint> keypoints;
cv::KeyPoint keypoint;
//读取文件夹下所有符合要求的文件路径
glob("/media/jankin/5622A53322A518CF/linux/picture/15_new/*.jpg", files, true);
size_t num = files.size(); //读取的符合条件的文件个数
vector<Point2f> corner;
double qualityLevel = 0.01; //角点检测可接收的最小特征
//double minDistance =10; //角点之间的最小的距离
double minDistance =5;
int blockSize = 3; //计算导数自相关矩阵时指定的邻域范围
double k = 0.04; //权重系数
chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
for (int i = 0; i < num; i++)
{
img = imread(files[i], IMREAD_GRAYSCALE); //读取灰度图像
if (img.empty())
{
cerr << files[i] << " can't be loaded!" << endl;
continue;
}
goodFeaturesToTrack(img, corner, 4000, qualityLevel, minDistance, Mat(), blockSize, false, k);
cout << "ShiTomas picture " << i << " 角点 数目 " << corner.size() << endl;
}
chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>( t2-t1 );
cout<<"ShiTomas 角点 solve time cost = "<<time_used.count()<<" seconds. "<<endl;
images.push_back(img); //将图像数据存入images中
for(int i;i<corner.size();i++)
{
keypoint.pt.x=corner[i].x;
keypoint.pt.y=corner[i].y;
keypoints.push_back(keypoint);
}
cv::drawKeypoints(img,keypoints, after_fast_image, cv::Scalar::all(-1), cv::DrawMatchesFlags::DEFAULT);
cv::imshow("after_ShiTomas_corner", after_fast_image);
waitKey();
return 0;
}
只显示最后一张效果
fast
#include <iostream>
#include <opencv2/opencv.hpp>
#include <chrono>
using namespace std;
using namespace cv;
int main(int argc , char* argv[])
{
int thread_value = 30;
vector<String> files; //存放文件路径
vector<Mat> images; //存放文件数据
Mat after_fast_image,img;
std::vector<cv::KeyPoint> keypoints;
//读取文件夹下所有符合要求的文件路径
glob("/media/jankin/5622A53322A518CF/linux/picture/15_new/*.jpg", files, true);
size_t num = files.size(); //读取的符合条件的文件个数
chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
for (int i = 0; i < num; i++)
{
img = imread(files[i], IMREAD_GRAYSCALE); //读取灰度图像
if (img.empty())
{
cerr << files[i] << " can't be loaded!" << endl;
continue;
}
cv::FAST(img, keypoints,thread_value);
cout << "fast picture " << i << "角点 数目 " << keypoints.size() << endl;
}
chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>( t2-t1 );
cout<<"fast 角点 solve time total cost = "<<time_used.count()<<" seconds. "<<endl;
images.push_back(img); //将图像数据存入images中
cv::drawKeypoints(img, keypoints, after_fast_image, cv::Scalar::all(-1), cv::DrawMatchesFlags::DEFAULT);
cv::imshow("after_fast_corner", after_fast_image);
waitKey();
return 0;
}
fast角点更快,角点更加精准