1#include "perf_precomp.hpp" 2#include "opencv2/imgcodecs.hpp" 3#include "opencv2/flann.hpp" 4#include "opencv2/opencv_modules.hpp" 5 6using namespace std; 7using namespace cv; 8using namespace perf; 9using std::tr1::make_tuple; 10using 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 16typedef TestBaseWithParam<string> stitch; 17typedef TestBaseWithParam<string> match; 18typedef std::tr1::tuple<string, int> matchVector_t; 19typedef 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 27PERF_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 65PERF_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 103PERF_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 153PERF_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