1/*M/////////////////////////////////////////////////////////////////////////////////////// 2// 3// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4// 5// By downloading, copying, installing or using the software you agree to this license. 6// If you do not agree to this license, do not download, install, 7// copy or use the software. 8// 9// 10// License Agreement 11// For Open Source Computer Vision Library 12// 13// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. 14// Copyright (C) 2009, Willow Garage Inc., all rights reserved. 15// Third party copyrights are property of their respective owners. 16// 17// Redistribution and use in source and binary forms, with or without modification, 18// are permitted provided that the following conditions are met: 19// 20// * Redistribution's of source code must retain the above copyright notice, 21// this list of conditions and the following disclaimer. 22// 23// * Redistribution's in binary form must reproduce the above copyright notice, 24// this list of conditions and the following disclaimer in the documentation 25// and/or other materials provided with the distribution. 26// 27// * The name of the copyright holders may not be used to endorse or promote products 28// derived from this software without specific prior written permission. 29// 30// This software is provided by the copyright holders and contributors "as is" and 31// any express or implied warranties, including, but not limited to, the implied 32// warranties of merchantability and fitness for a particular purpose are disclaimed. 33// In no event shall the Intel Corporation or contributors be liable for any direct, 34// indirect, incidental, special, exemplary, or consequential damages 35// (including, but not limited to, procurement of substitute goods or services; 36// loss of use, data, or profits; or business interruption) however caused 37// and on any theory of liability, whether in contract, strict liability, 38// or tort (including negligence or otherwise) arising in any way out of 39// the use of this software, even if advised of the possibility of such damage. 40// 41//M*/ 42 43#include "test_precomp.hpp" 44 45#include <string> 46#include <iostream> 47#include <fstream> 48#include <iterator> 49#include <limits> 50#include <numeric> 51 52using namespace cv; 53using namespace std; 54 55class CV_RigidTransform_Test : public cvtest::BaseTest 56{ 57public: 58 CV_RigidTransform_Test(); 59 ~CV_RigidTransform_Test(); 60protected: 61 void run(int); 62 63 bool testNPoints(int); 64 bool testImage(); 65}; 66 67CV_RigidTransform_Test::CV_RigidTransform_Test() 68{ 69} 70CV_RigidTransform_Test::~CV_RigidTransform_Test() {} 71 72struct WrapAff2D 73{ 74 const double *F; 75 WrapAff2D(const Mat& aff) : F(aff.ptr<double>()) {} 76 Point2f operator()(const Point2f& p) 77 { 78 return Point2f( (float)(p.x * F[0] + p.y * F[1] + F[2]), 79 (float)(p.x * F[3] + p.y * F[4] + F[5]) ); 80 } 81}; 82 83bool CV_RigidTransform_Test::testNPoints(int from) 84{ 85 cv::RNG rng = ts->get_rng(); 86 87 int progress = 0; 88 int k, ntests = 10000; 89 90 for( k = from; k < ntests; k++ ) 91 { 92 ts->update_context( this, k, true ); 93 progress = update_progress(progress, k, ntests, 0); 94 95 Mat aff(2, 3, CV_64F); 96 rng.fill(aff, RNG::UNIFORM, Scalar(-2), Scalar(2)); 97 98 int n = (unsigned)rng % 100 + 10; 99 100 Mat fpts(1, n, CV_32FC2); 101 Mat tpts(1, n, CV_32FC2); 102 103 rng.fill(fpts, RNG::UNIFORM, Scalar(0,0), Scalar(10,10)); 104 transform(fpts.ptr<Point2f>(), fpts.ptr<Point2f>() + n, tpts.ptr<Point2f>(), WrapAff2D(aff)); 105 106 Mat noise(1, n, CV_32FC2); 107 rng.fill(noise, RNG::NORMAL, Scalar::all(0), Scalar::all(0.001*(n<=7 ? 0 : n <= 30 ? 1 : 10))); 108 tpts += noise; 109 110 Mat aff_est = estimateRigidTransform(fpts, tpts, true); 111 112 double thres = 0.1*cvtest::norm(aff, NORM_L2); 113 double d = cvtest::norm(aff_est, aff, NORM_L2); 114 if (d > thres) 115 { 116 double dB=0, nB=0; 117 if (n <= 4) 118 { 119 Mat A = fpts.reshape(1, 3); 120 Mat B = A - repeat(A.row(0), 3, 1), Bt = B.t(); 121 B = Bt*B; 122 dB = cv::determinant(B); 123 nB = cvtest::norm(B, NORM_L2); 124 if( fabs(dB) < 0.01*nB ) 125 continue; 126 } 127 ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); 128 ts->printf( cvtest::TS::LOG, "Threshold = %f, norm of difference = %f", thres, d ); 129 return false; 130 } 131 } 132 return true; 133} 134 135bool CV_RigidTransform_Test::testImage() 136{ 137 Mat img; 138 Mat testImg = imread( string(ts->get_data_path()) + "shared/graffiti.png", 1); 139 if (testImg.empty()) 140 { 141 ts->printf( ts->LOG, "test image can not be read"); 142 ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); 143 return false; 144 } 145 pyrDown(testImg, img); 146 147 Mat aff = cv::getRotationMatrix2D(Point(img.cols/2, img.rows/2), 1, 0.99); 148 aff.ptr<double>()[2]+=3; 149 aff.ptr<double>()[5]+=3; 150 151 Mat rotated; 152 warpAffine(img, rotated, aff, img.size()); 153 154 Mat aff_est = estimateRigidTransform(img, rotated, true); 155 156 const double thres = 0.033; 157 if (cvtest::norm(aff_est, aff, NORM_INF) > thres) 158 { 159 ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); 160 ts->printf( cvtest::TS::LOG, "Threshold = %f, norm of difference = %f", thres, 161 cvtest::norm(aff_est, aff, NORM_INF) ); 162 return false; 163 } 164 165 return true; 166} 167 168void CV_RigidTransform_Test::run( int start_from ) 169{ 170 cvtest::DefaultRngAuto dra; 171 172 if (!testNPoints(start_from)) 173 return; 174 175 if (!testImage()) 176 return; 177 178 ts->set_failed_test_info(cvtest::TS::OK); 179} 180 181TEST(Video_RigidFlow, accuracy) { CV_RigidTransform_Test test; test.safe_run(); } 182