Path: blob/master/modules/calib3d/test/test_affine_partial2d_estimator.cpp
16337 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// By downloading, copying, installing or using the software you agree to this license.3// If you do not agree to this license, do not download, install,4// copy or use the software.5//6//7// License Agreement8// For Open Source Computer Vision Library9// (3-clause BSD License)10//11// Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.12// Third party copyrights are property of their respective owners.13//14// Redistribution and use in source and binary forms, with or without modification,15// are permitted provided that the following conditions are met:16//17// * Redistributions of source code must retain the above copyright notice,18// this list of conditions and the following disclaimer.19//20// * Redistributions in binary form must reproduce the above copyright notice,21// this list of conditions and the following disclaimer in the documentation22// and/or other materials provided with the distribution.23//24// * Neither the names of the copyright holders nor the names of the contributors25// may be used to endorse or promote products derived from this software26// without specific prior written permission.27//28// This software is provided by the copyright holders and contributors "as is" and29// any express or implied warranties, including, but not limited to, the implied30// warranties of merchantability and fitness for a particular purpose are disclaimed.31// In no event shall copyright holders or contributors be liable for any direct,32// indirect, incidental, special, exemplary, or consequential damages33// (including, but not limited to, procurement of substitute goods or services;34// loss of use, data, or profits; or business interruption) however caused35// and on any theory of liability, whether in contract, strict liability,36// or tort (including negligence or otherwise) arising in any way out of37// the use of this software, even if advised of the possibility of such damage.38//39//M*/4041#include "test_precomp.hpp"4243namespace opencv_test { namespace {4445CV_ENUM(Method, RANSAC, LMEDS)46typedef TestWithParam<Method> EstimateAffinePartial2D;4748static float rngIn(float from, float to) { return from + (to-from) * (float)theRNG(); }4950// get random matrix of affine transformation limited to combinations of translation,51// rotation, and uniform scaling52static Mat rngPartialAffMat() {53double theta = rngIn(0, (float)CV_PI*2.f);54double scale = rngIn(0, 3);55double tx = rngIn(-2, 2);56double ty = rngIn(-2, 2);57double aff[2*3] = { std::cos(theta) * scale, -std::sin(theta) * scale, tx,58std::sin(theta) * scale, std::cos(theta) * scale, ty };59return Mat(2, 3, CV_64F, aff).clone();60}6162TEST_P(EstimateAffinePartial2D, test2Points)63{64// try more transformations65for (size_t i = 0; i < 500; ++i)66{67Mat aff = rngPartialAffMat();6869// setting points that are no in the same line70Mat fpts(1, 2, CV_32FC2);71Mat tpts(1, 2, CV_32FC2);7273fpts.at<Point2f>(0) = Point2f( rngIn(1,2), rngIn(5,6) );74fpts.at<Point2f>(1) = Point2f( rngIn(3,4), rngIn(3,4) );7576transform(fpts, tpts, aff);7778vector<uchar> inliers;79Mat aff_est = estimateAffinePartial2D(fpts, tpts, inliers, GetParam() /* method */);8081EXPECT_NEAR(0., cvtest::norm(aff_est, aff, NORM_INF), 1e-3);8283// all must be inliers84EXPECT_EQ(countNonZero(inliers), 2);85}86}8788TEST_P(EstimateAffinePartial2D, testNPoints)89{90// try more transformations91for (size_t i = 0; i < 500; ++i)92{93Mat aff = rngPartialAffMat();9495const int method = GetParam();96const int n = 100;97int m;98// LMEDS can't handle more than 50% outliers (by design)99if (method == LMEDS)100m = 3*n/5;101else102m = 2*n/5;103const float shift_outl = 15.f;104const float noise_level = 20.f;105106Mat fpts(1, n, CV_32FC2);107Mat tpts(1, n, CV_32FC2);108109randu(fpts, 0., 100.);110transform(fpts, tpts, aff);111112/* adding noise to some points */113Mat outliers = tpts.colRange(m, n);114outliers.reshape(1) += shift_outl;115116Mat noise (outliers.size(), outliers.type());117randu(noise, 0., noise_level);118outliers += noise;119120vector<uchar> inliers;121Mat aff_est = estimateAffinePartial2D(fpts, tpts, inliers, method);122123EXPECT_FALSE(aff_est.empty());124125EXPECT_NEAR(0., cvtest::norm(aff_est, aff, NORM_INF), 1e-4);126127bool inliers_good = count(inliers.begin(), inliers.end(), 1) == m &&128m == accumulate(inliers.begin(), inliers.begin() + m, 0);129130EXPECT_TRUE(inliers_good);131}132}133134// test conversion from other datatypes than float135TEST_P(EstimateAffinePartial2D, testConversion)136{137Mat aff = rngPartialAffMat();138aff.convertTo(aff, CV_32S); // convert to int to transform ints properly139140std::vector<Point> fpts(3);141std::vector<Point> tpts(3);142143fpts[0] = Point2f( rngIn(1,2), rngIn(5,6) );144fpts[1] = Point2f( rngIn(3,4), rngIn(3,4) );145fpts[2] = Point2f( rngIn(1,2), rngIn(3,4) );146147transform(fpts, tpts, aff);148149vector<uchar> inliers;150Mat aff_est = estimateAffinePartial2D(fpts, tpts, inliers, GetParam() /* method */);151152ASSERT_FALSE(aff_est.empty());153154aff.convertTo(aff, CV_64F); // need to convert back before compare155EXPECT_NEAR(0., cvtest::norm(aff_est, aff, NORM_INF), 1e-3);156157// all must be inliers158EXPECT_EQ(countNonZero(inliers), 3);159}160161INSTANTIATE_TEST_CASE_P(Calib3d, EstimateAffinePartial2D, Method::all());162163}} // namespace164165166