计算机视觉攻略 6 (FAST 快速检测特征)

参考博文

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;
}

猜你喜欢

转载自blog.csdn.net/jlm7689235/article/details/107949742