Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/calib3d/test/test_affine2d_estimator.cpp
16337 views
1
/*M///////////////////////////////////////////////////////////////////////////////////////
2
//
3
// By downloading, copying, installing or using the software you agree to this license.
4
// If you do not agree to this license, do not download, install,
5
// copy or use the software.
6
//
7
//
8
// License Agreement
9
// For Open Source Computer Vision Library
10
// (3-clause BSD License)
11
//
12
// Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
13
// Third party copyrights are property of their respective owners.
14
//
15
// Redistribution and use in source and binary forms, with or without modification,
16
// are permitted provided that the following conditions are met:
17
//
18
// * Redistributions of source code must retain the above copyright notice,
19
// this list of conditions and the following disclaimer.
20
//
21
// * Redistributions in binary form must reproduce the above copyright notice,
22
// this list of conditions and the following disclaimer in the documentation
23
// and/or other materials provided with the distribution.
24
//
25
// * Neither the names of the copyright holders nor the names of the contributors
26
// may be used to endorse or promote products derived from this software
27
// without specific prior written permission.
28
//
29
// This software is provided by the copyright holders and contributors "as is" and
30
// any express or implied warranties, including, but not limited to, the implied
31
// warranties of merchantability and fitness for a particular purpose are disclaimed.
32
// In no event shall copyright holders or contributors be liable for any direct,
33
// indirect, incidental, special, exemplary, or consequential damages
34
// (including, but not limited to, procurement of substitute goods or services;
35
// loss of use, data, or profits; or business interruption) however caused
36
// and on any theory of liability, whether in contract, strict liability,
37
// or tort (including negligence or otherwise) arising in any way out of
38
// the use of this software, even if advised of the possibility of such damage.
39
//
40
//M*/
41
42
#include "test_precomp.hpp"
43
44
namespace opencv_test { namespace {
45
46
CV_ENUM(Method, RANSAC, LMEDS)
47
typedef TestWithParam<Method> EstimateAffine2D;
48
49
static float rngIn(float from, float to) { return from + (to-from) * (float)theRNG(); }
50
51
TEST_P(EstimateAffine2D, test3Points)
52
{
53
// try more transformations
54
for (size_t i = 0; i < 500; ++i)
55
{
56
Mat aff(2, 3, CV_64F);
57
cv::randu(aff, 1., 3.);
58
59
Mat fpts(1, 3, CV_32FC2);
60
Mat tpts(1, 3, CV_32FC2);
61
62
// setting points that are not in the same line
63
fpts.at<Point2f>(0) = Point2f( rngIn(1,2), rngIn(5,6) );
64
fpts.at<Point2f>(1) = Point2f( rngIn(3,4), rngIn(3,4) );
65
fpts.at<Point2f>(2) = Point2f( rngIn(1,2), rngIn(3,4) );
66
67
transform(fpts, tpts, aff);
68
69
vector<uchar> inliers;
70
Mat aff_est = estimateAffine2D(fpts, tpts, inliers, GetParam() /* method */);
71
72
EXPECT_NEAR(0., cvtest::norm(aff_est, aff, NORM_INF), 1e-3);
73
74
// all must be inliers
75
EXPECT_EQ(countNonZero(inliers), 3);
76
}
77
}
78
79
TEST_P(EstimateAffine2D, testNPoints)
80
{
81
// try more transformations
82
for (size_t i = 0; i < 500; ++i)
83
{
84
Mat aff(2, 3, CV_64F);
85
cv::randu(aff, -2., 2.);
86
const int method = GetParam();
87
const int n = 100;
88
int m;
89
// LMEDS can't handle more than 50% outliers (by design)
90
if (method == LMEDS)
91
m = 3*n/5;
92
else
93
m = 2*n/5;
94
const float shift_outl = 15.f;
95
const float noise_level = 20.f;
96
97
Mat fpts(1, n, CV_32FC2);
98
Mat tpts(1, n, CV_32FC2);
99
100
randu(fpts, 0., 100.);
101
transform(fpts, tpts, aff);
102
103
/* adding noise to some points */
104
Mat outliers = tpts.colRange(m, n);
105
outliers.reshape(1) += shift_outl;
106
107
Mat noise (outliers.size(), outliers.type());
108
randu(noise, 0., noise_level);
109
outliers += noise;
110
111
vector<uchar> inliers;
112
Mat aff_est = estimateAffine2D(fpts, tpts, inliers, method);
113
114
EXPECT_FALSE(aff_est.empty()) << "estimation failed, unable to estimate transform";
115
116
EXPECT_NEAR(0., cvtest::norm(aff_est, aff, NORM_INF), 1e-4);
117
118
bool inliers_good = count(inliers.begin(), inliers.end(), 1) == m &&
119
m == accumulate(inliers.begin(), inliers.begin() + m, 0);
120
121
EXPECT_TRUE(inliers_good);
122
}
123
}
124
125
// test conversion from other datatypes than float
126
TEST_P(EstimateAffine2D, testConversion)
127
{
128
Mat aff(2, 3, CV_32S);
129
cv::randu(aff, 1., 3.);
130
131
std::vector<Point> fpts(3);
132
std::vector<Point> tpts(3);
133
134
// setting points that are not in the same line
135
fpts[0] = Point2f( rngIn(1,2), rngIn(5,6) );
136
fpts[1] = Point2f( rngIn(3,4), rngIn(3,4) );
137
fpts[2] = Point2f( rngIn(1,2), rngIn(3,4) );
138
139
transform(fpts, tpts, aff);
140
141
vector<uchar> inliers;
142
Mat aff_est = estimateAffine2D(fpts, tpts, inliers, GetParam() /* method */);
143
144
ASSERT_FALSE(aff_est.empty());
145
146
aff.convertTo(aff, CV_64F); // need to convert before compare
147
EXPECT_NEAR(0., cvtest::norm(aff_est, aff, NORM_INF), 1e-3);
148
149
// all must be inliers
150
EXPECT_EQ(countNonZero(inliers), 3);
151
}
152
153
INSTANTIATE_TEST_CASE_P(Calib3d, EstimateAffine2D, Method::all());
154
155
}} // namespace
156
157