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

  • 检测场景中的移动物体(来自固定相机)
  • 跟踪他们
  • 尝试将它们与静态数据库匹配并识别
    他们

  • 在这张图片中,您可以在示例视频中看到结果,程序运行良好,它检测到红色汽车识别它并正在跟踪汽车::
    opencv - 使用带有 BREIF 提取器 c++ OpenCV 的 FAST 检测器结果不佳-LMLPHP

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

    问题:简而言之,我的方法是
  • 提取兴趣区域
  • 局部特征检测 [FAST 特征检测器]
  • 局部特征提取 [SIFT 描述符提取器]
  • 描述符匹配 [蛮力匹配]

  • 我有 3 个数据库,每个对象都与之进行比较。
    我希望我的程序尽可能快,因为它打算在嵌入式板上运行(如 Raspberry pi 2),但此时它很慢而且不是实时的,我确定了耗时的线路,它是 SIFT 描述符提取器 我尝试使用其他通常与 BRIEF 或 ORB 提取器等 FAST 检测器配合良好的提取器,它们的运行速度比 SIFT 快得多,相反,它们返回的结果很差,匹配率显着降低,请您帮助我了解如何我可以使用这种组合 FAST 检测器/BRIEF 或 ORB 提取器/BF 或 FLANN 匹配
    这里提到的功能::
    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 上运行,替换更快的二进制检测器和描述符是最好的选择。

    目前,我会说你的问题是:

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

  • 如果您想让程序在 pi 上“更接近”实时运行,我建议您查看 BRISK 描述符和 FLANN 索引 kNN 匹配。

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

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

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

    顺便提一下,根据我的经验,像 ORB 和 FAST 这样的二元检测器通常需要找到大约两倍于更多判别算法(如 SIFT 或 SURF)的点数。幸运的是,这不会对性能产生太大影响。

    关于opencv - 使用带有 BREIF 提取器 c++ OpenCV 的 FAST 检测器结果不佳,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31994005/

    10-16 12:04