#include "perf_precomp.hpp" #include "opencv2/imgcodecs.hpp" #include "opencv2/opencv_modules.hpp" using namespace std; using namespace cv; using namespace perf; using std::tr1::tuple; using std::tr1::get; #define SURF_MATCH_CONFIDENCE 0.65f #define ORB_MATCH_CONFIDENCE 0.3f #define WORK_MEGAPIX 0.6 typedef TestBaseWithParam stitch; typedef TestBaseWithParam > stitchDatasets; #ifdef HAVE_OPENCV_XFEATURES2D #define TEST_DETECTORS testing::Values("surf", "orb") #else #define TEST_DETECTORS testing::Values("orb") #endif #define AFFINE_DATASETS testing::Values("s", "budapest", "newspaper", "prague") PERF_TEST_P(stitch, a123, TEST_DETECTORS) { Mat pano; vector imgs; imgs.push_back( imread( getDataPath("stitching/a1.png") ) ); imgs.push_back( imread( getDataPath("stitching/a2.png") ) ); imgs.push_back( imread( getDataPath("stitching/a3.png") ) ); Ptr featuresFinder = GetParam() == "orb" ? Ptr(new detail::OrbFeaturesFinder()) : Ptr(new detail::SurfFeaturesFinder()); Ptr featuresMatcher = GetParam() == "orb" ? makePtr(false, ORB_MATCH_CONFIDENCE) : makePtr(false, SURF_MATCH_CONFIDENCE); declare.time(30 * 20).iterations(20); while(next()) { Stitcher stitcher = Stitcher::createDefault(); stitcher.setFeaturesFinder(featuresFinder); stitcher.setFeaturesMatcher(featuresMatcher); stitcher.setWarper(makePtr()); stitcher.setRegistrationResol(WORK_MEGAPIX); startTimer(); stitcher.stitch(imgs, pano); stopTimer(); } EXPECT_NEAR(pano.size().width, 1182, 50); EXPECT_NEAR(pano.size().height, 682, 30); SANITY_CHECK_NOTHING(); } PERF_TEST_P(stitch, b12, TEST_DETECTORS) { Mat pano; vector imgs; imgs.push_back( imread( getDataPath("stitching/b1.png") ) ); imgs.push_back( imread( getDataPath("stitching/b2.png") ) ); Ptr featuresFinder = GetParam() == "orb" ? Ptr(new detail::OrbFeaturesFinder()) : Ptr(new detail::SurfFeaturesFinder()); Ptr featuresMatcher = GetParam() == "orb" ? makePtr(false, ORB_MATCH_CONFIDENCE) : makePtr(false, SURF_MATCH_CONFIDENCE); declare.time(30 * 20).iterations(20); while(next()) { Stitcher stitcher = Stitcher::createDefault(); stitcher.setFeaturesFinder(featuresFinder); stitcher.setFeaturesMatcher(featuresMatcher); stitcher.setWarper(makePtr()); stitcher.setRegistrationResol(WORK_MEGAPIX); startTimer(); stitcher.stitch(imgs, pano); stopTimer(); } EXPECT_NEAR(pano.size().width, 1117, 50); EXPECT_NEAR(pano.size().height, 642, 30); Mat pano_small; resize(pano, pano_small, Size(320, 240), 0, 0, INTER_AREA); // results from orb and surf are slightly different (but both of them are good). Regression data // are for orb. /* transformations are: orb: [0.99213386, 0.062509097, -351.83731; -0.073042989, 1.0615162, -89.869858; 0.0005330033, -4.0937066e-05, 1] surf: [1.0034728, 0.022535477, -352.76849; -0.080653802, 1.0742083, -89.602058; 0.0004876224, 0.00012311155, 1] */ if (GetParam() == "orb") SANITY_CHECK(pano_small, 5); else SANITY_CHECK_NOTHING(); } PERF_TEST_P(stitchDatasets, affine, testing::Combine(AFFINE_DATASETS, TEST_DETECTORS)) { string dataset = get<0>(GetParam()); string detector = get<1>(GetParam()); Mat pano; vector imgs; int width, height, allowed_diff = 10; Ptr featuresFinder; if(detector == "orb") featuresFinder = makePtr(); else featuresFinder = makePtr(); if(dataset == "budapest") { imgs.push_back(imread(getDataPath("stitching/budapest1.jpg"))); imgs.push_back(imread(getDataPath("stitching/budapest2.jpg"))); imgs.push_back(imread(getDataPath("stitching/budapest3.jpg"))); imgs.push_back(imread(getDataPath("stitching/budapest4.jpg"))); imgs.push_back(imread(getDataPath("stitching/budapest5.jpg"))); imgs.push_back(imread(getDataPath("stitching/budapest6.jpg"))); width = 2313; height = 1158; // this dataset is big, the results between surf and orb differ slightly, // but both are still good allowed_diff = 27; } else if (dataset == "newspaper") { imgs.push_back(imread(getDataPath("stitching/newspaper1.jpg"))); imgs.push_back(imread(getDataPath("stitching/newspaper2.jpg"))); imgs.push_back(imread(getDataPath("stitching/newspaper3.jpg"))); imgs.push_back(imread(getDataPath("stitching/newspaper4.jpg"))); width = 1791; height = 1136; // we need to boost ORB number of features to be able to stitch this dataset // SURF works just fine with default settings if(detector == "orb") featuresFinder = makePtr(Size(3,1), 3000); } else if (dataset == "prague") { imgs.push_back(imread(getDataPath("stitching/prague1.jpg"))); imgs.push_back(imread(getDataPath("stitching/prague2.jpg"))); width = 983; height = 1759; } else // dataset == "s" { imgs.push_back(imread(getDataPath("stitching/s1.jpg"))); imgs.push_back(imread(getDataPath("stitching/s2.jpg"))); width = 1815; height = 700; } declare.time(30 * 20).iterations(20); while(next()) { Ptr stitcher = Stitcher::create(Stitcher::SCANS, false); stitcher->setFeaturesFinder(featuresFinder); startTimer(); stitcher->stitch(imgs, pano); stopTimer(); } EXPECT_NEAR(pano.size().width, width, allowed_diff); EXPECT_NEAR(pano.size().height, height, allowed_diff); SANITY_CHECK_NOTHING(); }