Path: blob/master/modules/stitching/perf/perf_matchers.cpp
16339 views
#include "perf_precomp.hpp"1#include "opencv2/imgcodecs.hpp"2#include "opencv2/opencv_modules.hpp"3#include "opencv2/flann.hpp"45namespace opencv_test6{7using namespace perf;89typedef TestBaseWithParam<size_t> FeaturesFinderVec;10typedef TestBaseWithParam<string> match;11typedef tuple<string, int> matchVector_t;12typedef TestBaseWithParam<matchVector_t> matchVector;1314#define NUMBER_IMAGES testing::Values(1, 5, 20)15#define SURF_MATCH_CONFIDENCE 0.65f16#define ORB_MATCH_CONFIDENCE 0.3f17#define WORK_MEGAPIX 0.61819#ifdef HAVE_OPENCV_XFEATURES2D20#define TEST_DETECTORS testing::Values("surf", "orb")21#else22#define TEST_DETECTORS testing::Values<string>("orb")23#endif2425PERF_TEST_P(FeaturesFinderVec, ParallelFeaturesFinder, NUMBER_IMAGES)26{27Mat img = imread( getDataPath("stitching/a1.png") );28vector<Mat> imgs(GetParam(), img);29vector<detail::ImageFeatures> features(imgs.size());3031Ptr<detail::FeaturesFinder> featuresFinder = makePtr<detail::OrbFeaturesFinder>();3233TEST_CYCLE()34{35(*featuresFinder)(imgs, features);36}3738SANITY_CHECK_NOTHING();39}4041PERF_TEST_P(FeaturesFinderVec, SerialFeaturesFinder, NUMBER_IMAGES)42{43Mat img = imread( getDataPath("stitching/a1.png") );44vector<Mat> imgs(GetParam(), img);45vector<detail::ImageFeatures> features(imgs.size());4647Ptr<detail::FeaturesFinder> featuresFinder = makePtr<detail::OrbFeaturesFinder>();4849TEST_CYCLE()50{51for (size_t i = 0; i < imgs.size(); ++i)52(*featuresFinder)(imgs[i], features[i]);53}5455SANITY_CHECK_NOTHING();56}5758PERF_TEST_P( match, bestOf2Nearest, TEST_DETECTORS)59{60Mat img1, img1_full = imread( getDataPath("stitching/boat1.jpg") );61Mat img2, img2_full = imread( getDataPath("stitching/boat2.jpg") );62float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total()));63float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total()));64resize(img1_full, img1, Size(), scale1, scale1, INTER_LINEAR_EXACT);65resize(img2_full, img2, Size(), scale2, scale2, INTER_LINEAR_EXACT);6667Ptr<detail::FeaturesFinder> finder;68Ptr<detail::FeaturesMatcher> matcher;69if (GetParam() == "surf")70{71finder = makePtr<detail::SurfFeaturesFinder>();72matcher = makePtr<detail::BestOf2NearestMatcher>(false, SURF_MATCH_CONFIDENCE);73}74else if (GetParam() == "orb")75{76finder = makePtr<detail::OrbFeaturesFinder>();77matcher = makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE);78}79else80{81FAIL() << "Unknown 2D features type: " << GetParam();82}8384detail::ImageFeatures features1, features2;85(*finder)(img1, features1);86(*finder)(img2, features2);8788detail::MatchesInfo pairwise_matches;8990declare.in(features1.descriptors, features2.descriptors);9192while(next())93{94cvflann::seed_random(42);//for predictive FlannBasedMatcher95startTimer();96(*matcher)(features1, features2, pairwise_matches);97stopTimer();98matcher->collectGarbage();99}100101Mat dist (pairwise_matches.H, Range::all(), Range(2, 3));102Mat R (pairwise_matches.H, Range::all(), Range(0, 2));103// separate transform matrix, use lower error on rotations104SANITY_CHECK(dist, 1., ERROR_ABSOLUTE);105SANITY_CHECK(R, .06, ERROR_ABSOLUTE);106}107108PERF_TEST_P( matchVector, bestOf2NearestVectorFeatures, testing::Combine(109TEST_DETECTORS,110testing::Values(2, 4, 8))111)112{113Mat img1, img1_full = imread( getDataPath("stitching/boat1.jpg") );114Mat img2, img2_full = imread( getDataPath("stitching/boat2.jpg") );115float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total()));116float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total()));117resize(img1_full, img1, Size(), scale1, scale1, INTER_LINEAR_EXACT);118resize(img2_full, img2, Size(), scale2, scale2, INTER_LINEAR_EXACT);119120Ptr<detail::FeaturesFinder> finder;121Ptr<detail::FeaturesMatcher> matcher;122string detectorName = get<0>(GetParam());123int featuresVectorSize = get<1>(GetParam());124if (detectorName == "surf")125{126finder = makePtr<detail::SurfFeaturesFinder>();127matcher = makePtr<detail::BestOf2NearestMatcher>(false, SURF_MATCH_CONFIDENCE);128}129else if (detectorName == "orb")130{131finder = makePtr<detail::OrbFeaturesFinder>();132matcher = makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE);133}134else135{136FAIL() << "Unknown 2D features type: " << get<0>(GetParam());137}138139detail::ImageFeatures features1, features2;140(*finder)(img1, features1);141(*finder)(img2, features2);142vector<detail::ImageFeatures> features;143vector<detail::MatchesInfo> pairwise_matches;144for(int i = 0; i < featuresVectorSize/2; i++)145{146features.push_back(features1);147features.push_back(features2);148}149150declare.time(200);151while(next())152{153cvflann::seed_random(42);//for predictive FlannBasedMatcher154startTimer();155(*matcher)(features, pairwise_matches);156stopTimer();157matcher->collectGarbage();158}159160size_t matches_count = 0;161for (size_t i = 0; i < pairwise_matches.size(); ++i)162{163if (pairwise_matches[i].src_img_idx < 0)164continue;165166EXPECT_GT(pairwise_matches[i].matches.size(), 95u);167EXPECT_FALSE(pairwise_matches[i].H.empty());168++matches_count;169}170171EXPECT_GT(matches_count, 0u);172173SANITY_CHECK_NOTHING();174}175176PERF_TEST_P( match, affineBestOf2Nearest, TEST_DETECTORS)177{178Mat img1, img1_full = imread( getDataPath("stitching/s1.jpg") );179Mat img2, img2_full = imread( getDataPath("stitching/s2.jpg") );180float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total()));181float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total()));182resize(img1_full, img1, Size(), scale1, scale1, INTER_LINEAR_EXACT);183resize(img2_full, img2, Size(), scale2, scale2, INTER_LINEAR_EXACT);184185Ptr<detail::FeaturesFinder> finder;186Ptr<detail::FeaturesMatcher> matcher;187if (GetParam() == "surf")188{189finder = makePtr<detail::SurfFeaturesFinder>();190matcher = makePtr<detail::AffineBestOf2NearestMatcher>(false, false, SURF_MATCH_CONFIDENCE);191}192else if (GetParam() == "orb")193{194finder = makePtr<detail::OrbFeaturesFinder>();195matcher = makePtr<detail::AffineBestOf2NearestMatcher>(false, false, ORB_MATCH_CONFIDENCE);196}197else198{199FAIL() << "Unknown 2D features type: " << GetParam();200}201202detail::ImageFeatures features1, features2;203(*finder)(img1, features1);204(*finder)(img2, features2);205206detail::MatchesInfo pairwise_matches;207208declare.in(features1.descriptors, features2.descriptors);209210while(next())211{212cvflann::seed_random(42);//for predictive FlannBasedMatcher213startTimer();214(*matcher)(features1, features2, pairwise_matches);215stopTimer();216matcher->collectGarbage();217}218219// separate rotation and translation in transform matrix220Mat T (pairwise_matches.H, Range(0, 2), Range(2, 3));221Mat R (pairwise_matches.H, Range(0, 2), Range(0, 2));222Mat h (pairwise_matches.H, Range(2, 3), Range::all());223SANITY_CHECK(T, 5, ERROR_ABSOLUTE); // allow 5 pixels diff in translations224SANITY_CHECK(R, .01, ERROR_ABSOLUTE); // rotations must be more precise225// last row should be precisely (0, 0, 1) as it is just added for representation in homogeneous226// coordinates227EXPECT_DOUBLE_EQ(h.at<double>(0), 0.);228EXPECT_DOUBLE_EQ(h.at<double>(1), 0.);229EXPECT_DOUBLE_EQ(h.at<double>(2), 1.);230}231232PERF_TEST_P( matchVector, affineBestOf2NearestVectorFeatures, testing::Combine(233TEST_DETECTORS,234testing::Values(2, 4, 8))235)236{237Mat img1, img1_full = imread( getDataPath("stitching/s1.jpg") );238Mat img2, img2_full = imread( getDataPath("stitching/s2.jpg") );239float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total()));240float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total()));241resize(img1_full, img1, Size(), scale1, scale1, INTER_LINEAR_EXACT);242resize(img2_full, img2, Size(), scale2, scale2, INTER_LINEAR_EXACT);243244Ptr<detail::FeaturesFinder> finder;245Ptr<detail::FeaturesMatcher> matcher;246string detectorName = get<0>(GetParam());247int featuresVectorSize = get<1>(GetParam());248if (detectorName == "surf")249{250finder = makePtr<detail::SurfFeaturesFinder>();251matcher = makePtr<detail::AffineBestOf2NearestMatcher>(false, false, SURF_MATCH_CONFIDENCE);252}253else if (detectorName == "orb")254{255finder = makePtr<detail::OrbFeaturesFinder>();256matcher = makePtr<detail::AffineBestOf2NearestMatcher>(false, false, ORB_MATCH_CONFIDENCE);257}258else259{260FAIL() << "Unknown 2D features type: " << get<0>(GetParam());261}262263detail::ImageFeatures features1, features2;264(*finder)(img1, features1);265(*finder)(img2, features2);266vector<detail::ImageFeatures> features;267vector<detail::MatchesInfo> pairwise_matches;268for(int i = 0; i < featuresVectorSize/2; i++)269{270features.push_back(features1);271features.push_back(features2);272}273274declare.time(200);275while(next())276{277cvflann::seed_random(42);//for predictive FlannBasedMatcher278startTimer();279(*matcher)(features, pairwise_matches);280stopTimer();281matcher->collectGarbage();282}283284size_t matches_count = 0;285for (size_t i = 0; i < pairwise_matches.size(); ++i)286{287if (pairwise_matches[i].src_img_idx < 0)288continue;289290EXPECT_TRUE(pairwise_matches[i].matches.size() > 400);291EXPECT_FALSE(pairwise_matches[i].H.empty());292++matches_count;293}294295EXPECT_TRUE(matches_count > 0);296297SANITY_CHECK_NOTHING();298}299300} // namespace301302303