Home | History | Annotate | Download | only in perf
      1 #include "perf_precomp.hpp"
      2 #include "opencv2/imgcodecs.hpp"
      3 #include "opencv2/flann.hpp"
      4 #include "opencv2/opencv_modules.hpp"
      5 
      6 using namespace std;
      7 using namespace cv;
      8 using namespace perf;
      9 using std::tr1::make_tuple;
     10 using std::tr1::get;
     11 
     12 #define SURF_MATCH_CONFIDENCE 0.65f
     13 #define ORB_MATCH_CONFIDENCE  0.3f
     14 #define WORK_MEGAPIX 0.6
     15 
     16 typedef TestBaseWithParam<string> stitch;
     17 typedef TestBaseWithParam<string> match;
     18 typedef std::tr1::tuple<string, int> matchVector_t;
     19 typedef TestBaseWithParam<matchVector_t> matchVector;
     20 
     21 #ifdef HAVE_OPENCV_XFEATURES2D_TODO_FIND_WHY_SURF_IS_NOT_ABLE_TO_STITCH_PANOS
     22 #define TEST_DETECTORS testing::Values("surf", "orb")
     23 #else
     24 #define TEST_DETECTORS testing::Values<string>("orb")
     25 #endif
     26 
     27 PERF_TEST_P(stitch, a123, TEST_DETECTORS)
     28 {
     29     Mat pano;
     30 
     31     vector<Mat> imgs;
     32     imgs.push_back( imread( getDataPath("stitching/a1.png") ) );
     33     imgs.push_back( imread( getDataPath("stitching/a2.png") ) );
     34     imgs.push_back( imread( getDataPath("stitching/a3.png") ) );
     35 
     36     Ptr<detail::FeaturesFinder> featuresFinder = GetParam() == "orb"
     37             ? Ptr<detail::FeaturesFinder>(new detail::OrbFeaturesFinder())
     38             : Ptr<detail::FeaturesFinder>(new detail::SurfFeaturesFinder());
     39 
     40     Ptr<detail::FeaturesMatcher> featuresMatcher = GetParam() == "orb"
     41             ? makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE)
     42             : makePtr<detail::BestOf2NearestMatcher>(false, SURF_MATCH_CONFIDENCE);
     43 
     44     declare.time(30 * 20).iterations(20);
     45 
     46     while(next())
     47     {
     48         Stitcher stitcher = Stitcher::createDefault();
     49         stitcher.setFeaturesFinder(featuresFinder);
     50         stitcher.setFeaturesMatcher(featuresMatcher);
     51         stitcher.setWarper(makePtr<SphericalWarper>());
     52         stitcher.setRegistrationResol(WORK_MEGAPIX);
     53 
     54         startTimer();
     55         stitcher.stitch(imgs, pano);
     56         stopTimer();
     57     }
     58 
     59     EXPECT_NEAR(pano.size().width, 1182, 50);
     60     EXPECT_NEAR(pano.size().height, 682, 30);
     61 
     62     SANITY_CHECK_NOTHING();
     63 }
     64 
     65 PERF_TEST_P(stitch, b12, TEST_DETECTORS)
     66 {
     67     Mat pano;
     68 
     69     vector<Mat> imgs;
     70     imgs.push_back( imread( getDataPath("stitching/b1.png") ) );
     71     imgs.push_back( imread( getDataPath("stitching/b2.png") ) );
     72 
     73     Ptr<detail::FeaturesFinder> featuresFinder = GetParam() == "orb"
     74             ? Ptr<detail::FeaturesFinder>(new detail::OrbFeaturesFinder())
     75             : Ptr<detail::FeaturesFinder>(new detail::SurfFeaturesFinder());
     76 
     77     Ptr<detail::FeaturesMatcher> featuresMatcher = GetParam() == "orb"
     78             ? makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE)
     79             : makePtr<detail::BestOf2NearestMatcher>(false, SURF_MATCH_CONFIDENCE);
     80 
     81     declare.time(30 * 20).iterations(20);
     82 
     83     while(next())
     84     {
     85         Stitcher stitcher = Stitcher::createDefault();
     86         stitcher.setFeaturesFinder(featuresFinder);
     87         stitcher.setFeaturesMatcher(featuresMatcher);
     88         stitcher.setWarper(makePtr<SphericalWarper>());
     89         stitcher.setRegistrationResol(WORK_MEGAPIX);
     90 
     91         startTimer();
     92         stitcher.stitch(imgs, pano);
     93         stopTimer();
     94     }
     95 
     96     Mat pano_small;
     97     if (!pano.empty())
     98         resize(pano, pano_small, Size(320, 240), 0, 0, INTER_AREA);
     99 
    100     SANITY_CHECK(pano_small, 5);
    101 }
    102 
    103 PERF_TEST_P( match, bestOf2Nearest, TEST_DETECTORS)
    104 {
    105     Mat img1, img1_full = imread( getDataPath("stitching/b1.png") );
    106     Mat img2, img2_full = imread( getDataPath("stitching/b2.png") );
    107     float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total()));
    108     float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total()));
    109     resize(img1_full, img1, Size(), scale1, scale1);
    110     resize(img2_full, img2, Size(), scale2, scale2);
    111 
    112     Ptr<detail::FeaturesFinder> finder;
    113     Ptr<detail::FeaturesMatcher> matcher;
    114     if (GetParam() == "surf")
    115     {
    116         finder = makePtr<detail::SurfFeaturesFinder>();
    117         matcher = makePtr<detail::BestOf2NearestMatcher>(false, SURF_MATCH_CONFIDENCE);
    118     }
    119     else if (GetParam() == "orb")
    120     {
    121         finder = makePtr<detail::OrbFeaturesFinder>();
    122         matcher = makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE);
    123     }
    124     else
    125     {
    126         FAIL() << "Unknown 2D features type: " << GetParam();
    127     }
    128 
    129     detail::ImageFeatures features1, features2;
    130     (*finder)(img1, features1);
    131     (*finder)(img2, features2);
    132 
    133     detail::MatchesInfo pairwise_matches;
    134 
    135     declare.in(features1.descriptors, features2.descriptors);
    136 
    137     while(next())
    138     {
    139         cvflann::seed_random(42);//for predictive FlannBasedMatcher
    140         startTimer();
    141         (*matcher)(features1, features2, pairwise_matches);
    142         stopTimer();
    143         matcher->collectGarbage();
    144     }
    145 
    146     std::vector<DMatch>& matches = pairwise_matches.matches;
    147     if (GetParam() == "orb") matches.resize(0);
    148     for(size_t q = 0; q < matches.size(); ++q)
    149         if (matches[q].imgIdx < 0) { matches.resize(q); break;}
    150     SANITY_CHECK_MATCHES(matches);
    151 }
    152 
    153 PERF_TEST_P( matchVector, bestOf2NearestVectorFeatures, testing::Combine(
    154                  TEST_DETECTORS,
    155                  testing::Values(2, 4, 8))
    156              )
    157 {
    158     Mat img1, img1_full = imread( getDataPath("stitching/b1.png") );
    159     Mat img2, img2_full = imread( getDataPath("stitching/b2.png") );
    160     float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total()));
    161     float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total()));
    162     resize(img1_full, img1, Size(), scale1, scale1);
    163     resize(img2_full, img2, Size(), scale2, scale2);
    164 
    165     Ptr<detail::FeaturesFinder> finder;
    166     Ptr<detail::FeaturesMatcher> matcher;
    167     string detectorName = get<0>(GetParam());
    168     int featuresVectorSize = get<1>(GetParam());
    169     if (detectorName == "surf")
    170     {
    171         finder = makePtr<detail::SurfFeaturesFinder>();
    172         matcher = makePtr<detail::BestOf2NearestMatcher>(false, SURF_MATCH_CONFIDENCE);
    173     }
    174     else if (detectorName == "orb")
    175     {
    176         finder = makePtr<detail::OrbFeaturesFinder>();
    177         matcher = makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE);
    178     }
    179     else
    180     {
    181         FAIL() << "Unknown 2D features type: " << get<0>(GetParam());
    182     }
    183 
    184     detail::ImageFeatures features1, features2;
    185     (*finder)(img1, features1);
    186     (*finder)(img2, features2);
    187     vector<detail::ImageFeatures> features;
    188     vector<detail::MatchesInfo> pairwise_matches;
    189     for(int i = 0; i < featuresVectorSize/2; i++)
    190     {
    191         features.push_back(features1);
    192         features.push_back(features2);
    193     }
    194 
    195     declare.time(200);
    196     while(next())
    197     {
    198         cvflann::seed_random(42);//for predictive FlannBasedMatcher
    199         startTimer();
    200         (*matcher)(features, pairwise_matches);
    201         stopTimer();
    202         matcher->collectGarbage();
    203     }
    204 
    205 
    206     std::vector<DMatch>& matches = pairwise_matches[detectorName == "surf" ? 1 : 0].matches;
    207     for(size_t q = 0; q < matches.size(); ++q)
    208         if (matches[q].imgIdx < 0) { matches.resize(q); break;}
    209     SANITY_CHECK_MATCHES(matches);
    210 }
    211