参考博文
lambda表达式
nth_element
FAST特征检测原理
FAST 特征点提取代码
//
// Created by jlm on 2020/8/11.
//
#include <iostream>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
int main(int argc, char** argv){
if(argc != 2){
std::cerr << "don't get right numbers of images" << std::endl;
return -1;
}
cv::Mat image = cv::imread(argv[1],cv::IMREAD_GRAYSCALE);
cv::imshow("rignial", image);
cv::waitKey(0);
// 关键点向量
std::vector< cv::KeyPoint> vkeypoints;
// FAST 特征检测器, 阈值位40
cv::Ptr<cv::FastFeatureDetector> ptrFAST =
cv::FastFeatureDetector::create(40);
// 定义要提取的关键点个数 100个
const int numberOfPoints = 100;
const int hstep = 5, vstep = 3;
int hsize(image.cols/hstep), vsize(image.rows/vstep);
int subtotal(numberOfPoints/(hstep * vstep));
cv::Mat imageROI;
std::vector<cv::KeyPoint> gridPoint;
ptrFAST -> setThreshold(30);
ptrFAST -> setNonmaxSuppression(true);
vkeypoints.clear();
for(int i = 0; i < vstep; i++)
for(int j = 0; j < hstep; j++){
// 在当前网络创建ROI
imageROI = image(cv::Rect(j*hsize, i*vsize, hsize, vsize));
gridPoint.clear();
ptrFAST -> detect(imageROI, gridPoint);
// 获取强度最大的FASt特征
auto itEnd(gridPoint.end());
if(gridPoint.size() > subtotal){
// 选取最强的特征
std::nth_element(gridPoint.begin(),
gridPoint.begin() + subtotal,
gridPoint.end(),
[](cv::KeyPoint& a, cv::KeyPoint& b){
return a.response > b.response;
});
itEnd = gridPoint.begin() + subtotal;
}
//加入全局特征容器
for (auto it = gridPoint.begin(); it != itEnd; ++it){
// 转换程图像上的坐标
it -> pt += cv::Point2f(j*hsize, i*vsize);
vkeypoints.push_back(*it);
}
}
cv::drawKeypoints(image,
vkeypoints,
image,
cv::Scalar(255, 255, 255),
cv::DrawMatchesFlags::DRAW_OVER_OUTIMG);
cv::imshow("Processed",image);
std::cout << "the numbers of keypoints: " << vkeypoints.size() << std::endl;
cv::waitKey(0);
return 0;
}