首页 文章

使用带有BREIF提取器c OpenCV的FAST检测器的结果很差

提问于
浏览
3

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

  • 检测场景中的移动物体(来自固定摄像机)

  • 跟踪他们

  • 尝试将它们与静态数据库匹配并识别它们

在这张图片中你可以看到一个示例视频中的结果,该程序工作正常,它检测到红色汽车识别它并且它正在跟踪汽车::
enter image description here

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

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

  • extract region of interests

  • local feature detection [快速特征检测器]

  • local feature extraction [SIFT描述符提取器]

  • descriptor matching [蛮力匹配]

我有3个数据库,每个对象都与之比较 . 我希望我的程序尽可能快,因为它在这一点上安静缓慢而不是实时,我精确定位了耗时的线路并且它是 SIFT descriptor extractor 我试图使用通常与之配合使用的其他提取器快速检测器,如BRIEF或ORB提取器,它们运行速度比SIFT快得多,反而它们返回效果不佳,匹配率显着降低,请你帮我理解如何使用这种组合 FAST detector/ BRIEF or ORB extractor/ BF or 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;
            }
        }
    }
}

1 回答

  • 2

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

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

    • 使用SIFT描述符提取器和

    • 使用BruteForce匹配器

    如果你希望你的程序在pi上“接近”实时运行,我建议你看一下BRISK描述符和FLANN索引kNN匹配 .

    这些都可以调整,非常可靠 .

    此外,您可以使用ORB(基本上是快速但面向)作为关键点检测器,使用BRISK作为解析器 . 这从我的经验中得到了不错的结果 .

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

    另一方面,根据我的经验,二元探测器(如ORB和FAST)通常需要找到大约两倍的点数,因为更多的判别算法如SIFT或SURF . 幸运的是,这不会对性能产生太大影响 .

相关问题