使用 FAST 检测器和 BREIF 提取器 c++ OpenCV 的结果不佳

Poor results using FAST detector with BREIF extractor c++ OpenCV

首先,感谢您阅读我的问题。 我写了一个程序

在此图片中,您可以看到示例视频中的结果,程序运行良好,它检测到红色汽车并识别它并正在跟踪汽车::

注意:橙色点显示为动态数据库获取额外样本以供将来使用的位置。

问题:简而言之,我的方法是

  1. 提取兴趣区域
  2. 局部特征检测[FAST特征检测器]
  3. 局部特征提取[SIFT 描述符提取器]
  4. 描述符匹配[暴力匹配]

我有 3 个数据库,每个对象都与之进行比较。 我希望我的程序尽可能快,因为它意味着 运行 在嵌入式板上(如 Raspberry pi 2),但它很慢而且在这一点上不是实时的,我指出耗时的线,它是 SIFT 描述符提取器 我尝试使用其他通常与 FAST 检测器配合良好的提取器,如 BRIEF 或 ORB 提取器,它们 运行 比 SIFT 快得多相反,他们 return 糟糕的结果和匹配率显着下降,请您帮助我了解如何使用这种组合 FAST detector/BRIEF 或 ORB extractor/ BF 或 FLANN match 这里提到的函数::

void Objects::calKeypointDiscriptor(Mat inputFrame,Mat &ROI,Rect RegionArea,vector<KeyPoint> &fastKey, Mat &briefDescriptors,bool display)
{
    SurfFeatureDetector detectorSURF(300);
    SiftFeatureDetector detectorSIFT(400);
    FastFeatureDetector detectorFAST(30);
    OrbFeatureDetector  detectorORB (400);


    SurfDescriptorExtractor  extractorSURF;
    SiftDescriptorExtractor  extractorSIFT;
    OrbDescriptorExtractor   extractorORB;
    BriefDescriptorExtractor extractorBRIEF;
    FREAK                    extractorFREAK;

    Mat regionTemp;
    Mat frame=inputFrame;
    regionTemp=frame(RegionArea);
    ROI=regionTemp.clone();
    detectorFAST.detect(regionTemp, fastKey);
    extractorSIFT.compute(regionTemp, fastKey, briefDescriptors);

}

void Objects::matchDiscriptorFlann(Mat ROI,int distance,Point2i center,vector<KeyPoint>keypo,Mat descriptors,vector<Objects> objectVector,bool &matched,int vctorEnd,int &index)
{

    BFMatcher matcherBF(NORM_L2);
    FlannBasedMatcher matcherFLANN;
    Mat img_matches;


    for(int i=0; i<=vctorEnd; i++)
    {
        if (distance>0)
        {
            bool chk= euclideanDistance(objectVector[i]. center_obj,center)<distance;

        }
        else
        {
            bool chk=true;
        }


        vector< DMatch > good_matches;
        vector<DMatch> matches;


        if (descriptors.rows*descriptors.cols!=0&&objectVector[i].discriptor_obj.rows*objectVector[i].discriptor_obj.cols!=0)
        {
            matcherBF.match(descriptors,objectVector[i].discriptor_obj,matches);
            double max_dist = 0;
            double min_dist = 100;

            for( int i = 0; i < descriptors.rows; i++ )
            {
                double dist = matches[i].distance;
                if( dist < min_dist ) min_dist = dist;
                if( dist > max_dist ) max_dist = dist;
            }

            for( int i = 0; i < descriptors.rows; i++ )
            {
                if( matches[i].distance <=2*min_dist )
                {
                    good_matches.push_back( matches[i]);
                }
            }

            if(good_matches.size()>2)
            {

                matched=true;
                index=i;
            }
        }
    }
}

不能期望 Raspberry Pi 实时 运行 浮点描述符(例如 SIFT 或 SURF)。它根本没有处理能力。如果在 pi 上 运行ning,那么用更快的二进制检测器和描述符替换是你最好的选择。

目前,我认为您的问题是:

  • 使用 SIFT 描述符提取器和
  • 使用 BruteForce 匹配器

如果你想让你的程序运行 'closer'在pi上实时,我建议你看看BRISK描述符和FLANN索引kNN匹配。

这些都可以调整并且非常可靠。

此外,您可以使用 ORB(基本上是快速但有方向的)作为关键点检测器,使用 BRISK 作为描述器。根据我的经验,这给出了不错的结果。

我对 LATCH 或 KAZE/AKAZE 没有太多经验,但是,我不确定这些是否能满足您的性能要求。

附带说明一下,根据我的经验,ORB 和 FAST 等二元检测器通常需要找到大约两倍于 SIFT 或 SURF 等判别算法的点数。幸运的是,这不会对性能造成太大影响。