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
PERF_TEST_P(stitch,a123,TEST_DETECTORS)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
PERF_TEST_P(stitch,b12,TEST_DETECTORS)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
PERF_TEST_P(match,bestOf2Nearest,TEST_DETECTORS)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