Path: blob/master/modules/features2d/test/test_descriptors_invariance.impl.hpp
16356 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html34#include "test_invariance_utils.hpp"56namespace opencv_test { namespace {78#define SHOW_DEBUG_LOG 1910typedef tuple<std::string, Ptr<FeatureDetector>, Ptr<DescriptorExtractor>, float>11String_FeatureDetector_DescriptorExtractor_Float_t;121314static15void rotateKeyPoints(const vector<KeyPoint>& src, const Mat& H, float angle, vector<KeyPoint>& dst)16{17// suppose that H is rotation given from rotateImage() and angle has value passed to rotateImage()18vector<Point2f> srcCenters, dstCenters;19KeyPoint::convert(src, srcCenters);2021perspectiveTransform(srcCenters, dstCenters, H);2223dst = src;24for(size_t i = 0; i < dst.size(); i++)25{26dst[i].pt = dstCenters[i];27float dstAngle = src[i].angle + angle;28if(dstAngle >= 360.f)29dstAngle -= 360.f;30dst[i].angle = dstAngle;31}32}3334class DescriptorInvariance : public TestWithParam<String_FeatureDetector_DescriptorExtractor_Float_t>35{36protected:37virtual void SetUp() {38// Read test data39const std::string filename = cvtest::TS::ptr()->get_data_path() + get<0>(GetParam());40image0 = imread(filename);41ASSERT_FALSE(image0.empty()) << "couldn't read input image";4243featureDetector = get<1>(GetParam());44descriptorExtractor = get<2>(GetParam());45minInliersRatio = get<3>(GetParam());46}4748Ptr<FeatureDetector> featureDetector;49Ptr<DescriptorExtractor> descriptorExtractor;50float minInliersRatio;51Mat image0;52};5354typedef DescriptorInvariance DescriptorScaleInvariance;55typedef DescriptorInvariance DescriptorRotationInvariance;5657TEST_P(DescriptorRotationInvariance, rotation)58{59Mat image1, mask1;60const int borderSize = 16;61Mat mask0(image0.size(), CV_8UC1, Scalar(0));62mask0(Rect(borderSize, borderSize, mask0.cols - 2*borderSize, mask0.rows - 2*borderSize)).setTo(Scalar(255));6364vector<KeyPoint> keypoints0;65Mat descriptors0;66featureDetector->detect(image0, keypoints0, mask0);67std::cout << "Keypoints: " << keypoints0.size() << std::endl;68EXPECT_GE(keypoints0.size(), 15u);69descriptorExtractor->compute(image0, keypoints0, descriptors0);7071BFMatcher bfmatcher(descriptorExtractor->defaultNorm());7273const float minIntersectRatio = 0.5f;74const int maxAngle = 360, angleStep = 15;75for(int angle = 0; angle < maxAngle; angle += angleStep)76{77Mat H = rotateImage(image0, mask0, static_cast<float>(angle), image1, mask1);7879vector<KeyPoint> keypoints1;80rotateKeyPoints(keypoints0, H, static_cast<float>(angle), keypoints1);81Mat descriptors1;82descriptorExtractor->compute(image1, keypoints1, descriptors1);8384vector<DMatch> descMatches;85bfmatcher.match(descriptors0, descriptors1, descMatches);8687int descInliersCount = 0;88for(size_t m = 0; m < descMatches.size(); m++)89{90const KeyPoint& transformed_p0 = keypoints1[descMatches[m].queryIdx];91const KeyPoint& p1 = keypoints1[descMatches[m].trainIdx];92if(calcIntersectRatio(transformed_p0.pt, 0.5f * transformed_p0.size,93p1.pt, 0.5f * p1.size) >= minIntersectRatio)94{95descInliersCount++;96}97}9899float descInliersRatio = static_cast<float>(descInliersCount) / keypoints0.size();100EXPECT_GE(descInliersRatio, minInliersRatio);101#if SHOW_DEBUG_LOG102std::cout103<< "angle = " << angle104<< ", inliers = " << descInliersCount105<< ", descInliersRatio = " << static_cast<float>(descInliersCount) / keypoints0.size()106<< std::endl;107#endif108}109}110111112TEST_P(DescriptorScaleInvariance, scale)113{114vector<KeyPoint> keypoints0;115featureDetector->detect(image0, keypoints0);116std::cout << "Keypoints: " << keypoints0.size() << std::endl;117EXPECT_GE(keypoints0.size(), 15u);118Mat descriptors0;119descriptorExtractor->compute(image0, keypoints0, descriptors0);120121BFMatcher bfmatcher(descriptorExtractor->defaultNorm());122for(int scaleIdx = 1; scaleIdx <= 3; scaleIdx++)123{124float scale = 1.f + scaleIdx * 0.5f;125126Mat image1;127resize(image0, image1, Size(), 1./scale, 1./scale, INTER_LINEAR_EXACT);128129vector<KeyPoint> keypoints1;130scaleKeyPoints(keypoints0, keypoints1, 1.0f/scale);131Mat descriptors1;132descriptorExtractor->compute(image1, keypoints1, descriptors1);133134vector<DMatch> descMatches;135bfmatcher.match(descriptors0, descriptors1, descMatches);136137const float minIntersectRatio = 0.5f;138int descInliersCount = 0;139for(size_t m = 0; m < descMatches.size(); m++)140{141const KeyPoint& transformed_p0 = keypoints0[descMatches[m].queryIdx];142const KeyPoint& p1 = keypoints0[descMatches[m].trainIdx];143if(calcIntersectRatio(transformed_p0.pt, 0.5f * transformed_p0.size,144p1.pt, 0.5f * p1.size) >= minIntersectRatio)145{146descInliersCount++;147}148}149150float descInliersRatio = static_cast<float>(descInliersCount) / keypoints0.size();151EXPECT_GE(descInliersRatio, minInliersRatio);152#if SHOW_DEBUG_LOG153std::cout154<< "scale = " << scale155<< ", inliers = " << descInliersCount156<< ", descInliersRatio = " << static_cast<float>(descInliersCount) / keypoints0.size()157<< std::endl;158#endif159}160}161162#undef SHOW_DEBUG_LOG163}} // namespace164165namespace std {166using namespace opencv_test;167static inline void PrintTo(const String_FeatureDetector_DescriptorExtractor_Float_t& v, std::ostream* os)168{169*os << "(\"" << get<0>(v)170<< "\", " << get<3>(v)171<< ")";172}173} // namespace174175176