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