#include "perf_precomp.hpp" #include "opencv2/imgcodecs.hpp" #include "opencv2/flann.hpp" #include "opencv2/opencv_modules.hpp" using namespace std; using namespace cv; using namespace perf; using std::tr1::make_tuple; using std::tr1::get; #define SURF_MATCH_CONFIDENCE 0.65f #define ORB_MATCH_CONFIDENCE 0.3f #define WORK_MEGAPIX 0.6 typedef TestBaseWithParam<string> stitch; typedef TestBaseWithParam<string> match; typedef std::tr1::tuple<string, int> matchVector_t; typedef TestBaseWithParam<matchVector_t> matchVector; #ifdef HAVE_OPENCV_XFEATURES2D_TODO_FIND_WHY_SURF_IS_NOT_ABLE_TO_STITCH_PANOS #define TEST_DETECTORS testing::Values("surf", "orb") #else #define TEST_DETECTORS testing::Values<string>("orb") #endif PERF_TEST_P(stitch, a123, TEST_DETECTORS) { Mat pano; vector<Mat> 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<detail::FeaturesFinder> featuresFinder = GetParam() == "orb" ? Ptr<detail::FeaturesFinder>(new detail::OrbFeaturesFinder()) : Ptr<detail::FeaturesFinder>(new detail::SurfFeaturesFinder()); Ptr<detail::FeaturesMatcher> featuresMatcher = GetParam() == "orb" ? makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE) : makePtr<detail::BestOf2NearestMatcher>(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<SphericalWarper>()); 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<Mat> imgs; imgs.push_back( imread( getDataPath("stitching/b1.png") ) ); imgs.push_back( imread( getDataPath("stitching/b2.png") ) ); Ptr<detail::FeaturesFinder> featuresFinder = GetParam() == "orb" ? Ptr<detail::FeaturesFinder>(new detail::OrbFeaturesFinder()) : Ptr<detail::FeaturesFinder>(new detail::SurfFeaturesFinder()); Ptr<detail::FeaturesMatcher> featuresMatcher = GetParam() == "orb" ? makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE) : makePtr<detail::BestOf2NearestMatcher>(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<SphericalWarper>()); stitcher.setRegistrationResol(WORK_MEGAPIX); startTimer(); stitcher.stitch(imgs, pano); stopTimer(); } Mat pano_small; if (!pano.empty()) resize(pano, pano_small, Size(320, 240), 0, 0, INTER_AREA); SANITY_CHECK(pano_small, 5); } PERF_TEST_P( match, bestOf2Nearest, TEST_DETECTORS) { Mat img1, img1_full = imread( getDataPath("stitching/b1.png") ); Mat img2, img2_full = imread( getDataPath("stitching/b2.png") ); float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total())); float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total())); resize(img1_full, img1, Size(), scale1, scale1); resize(img2_full, img2, Size(), scale2, scale2); Ptr<detail::FeaturesFinder> finder; Ptr<detail::FeaturesMatcher> matcher; if (GetParam() == "surf") { finder = makePtr<detail::SurfFeaturesFinder>(); matcher = makePtr<detail::BestOf2NearestMatcher>(false, SURF_MATCH_CONFIDENCE); } else if (GetParam() == "orb") { finder = makePtr<detail::OrbFeaturesFinder>(); matcher = makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE); } else { FAIL() << "Unknown 2D features type: " << GetParam(); } detail::ImageFeatures features1, features2; (*finder)(img1, features1); (*finder)(img2, features2); detail::MatchesInfo pairwise_matches; declare.in(features1.descriptors, features2.descriptors); while(next()) { cvflann::seed_random(42);//for predictive FlannBasedMatcher startTimer(); (*matcher)(features1, features2, pairwise_matches); stopTimer(); matcher->collectGarbage(); } std::vector<DMatch>& matches = pairwise_matches.matches; if (GetParam() == "orb") matches.resize(0); for(size_t q = 0; q < matches.size(); ++q) if (matches[q].imgIdx < 0) { matches.resize(q); break;} SANITY_CHECK_MATCHES(matches); } PERF_TEST_P( matchVector, bestOf2NearestVectorFeatures, testing::Combine( TEST_DETECTORS, testing::Values(2, 4, 8)) ) { Mat img1, img1_full = imread( getDataPath("stitching/b1.png") ); Mat img2, img2_full = imread( getDataPath("stitching/b2.png") ); float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total())); float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total())); resize(img1_full, img1, Size(), scale1, scale1); resize(img2_full, img2, Size(), scale2, scale2); Ptr<detail::FeaturesFinder> finder; Ptr<detail::FeaturesMatcher> matcher; string detectorName = get<0>(GetParam()); int featuresVectorSize = get<1>(GetParam()); if (detectorName == "surf") { finder = makePtr<detail::SurfFeaturesFinder>(); matcher = makePtr<detail::BestOf2NearestMatcher>(false, SURF_MATCH_CONFIDENCE); } else if (detectorName == "orb") { finder = makePtr<detail::OrbFeaturesFinder>(); matcher = makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE); } else { FAIL() << "Unknown 2D features type: " << get<0>(GetParam()); } detail::ImageFeatures features1, features2; (*finder)(img1, features1); (*finder)(img2, features2); vector<detail::ImageFeatures> features; vector<detail::MatchesInfo> pairwise_matches; for(int i = 0; i < featuresVectorSize/2; i++) { features.push_back(features1); features.push_back(features2); } declare.time(200); while(next()) { cvflann::seed_random(42);//for predictive FlannBasedMatcher startTimer(); (*matcher)(features, pairwise_matches); stopTimer(); matcher->collectGarbage(); } std::vector<DMatch>& matches = pairwise_matches[detectorName == "surf" ? 1 : 0].matches; for(size_t q = 0; q < matches.size(); ++q) if (matches[q].imgIdx < 0) { matches.resize(q); break;} SANITY_CHECK_MATCHES(matches); }