Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/videostab/test/test_motion_estimation.cpp
16337 views
1
// This file is part of OpenCV project.
2
// It is subject to the license terms in the LICENSE file found in the top-level directory
3
// of this distribution and at http://opencv.org/license.html
4
5
#include "test_precomp.hpp"
6
7
namespace opencv_test { namespace {
8
9
namespace testUtil
10
{
11
12
cv::RNG rng(/*std::time(0)*/0);
13
14
const float sigma = 1.f;
15
const float pointsMaxX = 500.f;
16
const float pointsMaxY = 500.f;
17
const int testRun = 5000;
18
19
void generatePoints(cv::Mat points);
20
void addNoise(cv::Mat points);
21
22
cv::Mat generateTransform(const cv::videostab::MotionModel model);
23
24
double performTest(const cv::videostab::MotionModel model, int size);
25
26
}
27
28
void testUtil::generatePoints(cv::Mat points)
29
{
30
CV_Assert(!points.empty());
31
for(int i = 0; i < points.cols; ++i)
32
{
33
points.at<float>(0, i) = rng.uniform(0.f, pointsMaxX);
34
points.at<float>(1, i) = rng.uniform(0.f, pointsMaxY);
35
points.at<float>(2, i) = 1.f;
36
}
37
}
38
39
void testUtil::addNoise(cv::Mat points)
40
{
41
CV_Assert(!points.empty());
42
for(int i = 0; i < points.cols; i++)
43
{
44
points.at<float>(0, i) += static_cast<float>(rng.gaussian(sigma));
45
points.at<float>(1, i) += static_cast<float>(rng.gaussian(sigma));
46
47
}
48
}
49
50
51
cv::Mat testUtil::generateTransform(const cv::videostab::MotionModel model)
52
{
53
/*----------Params----------*/
54
const float minAngle = 0.f, maxAngle = static_cast<float>(CV_PI);
55
const float minScale = 0.5f, maxScale = 2.f;
56
const float maxTranslation = 100.f;
57
const float affineCoeff = 3.f;
58
/*----------Params----------*/
59
60
cv::Mat transform = cv::Mat::eye(3, 3, CV_32F);
61
62
if(model != cv::videostab::MM_ROTATION)
63
{
64
transform.at<float>(0,2) = rng.uniform(-maxTranslation, maxTranslation);
65
transform.at<float>(1,2) = rng.uniform(-maxTranslation, maxTranslation);
66
}
67
68
if(model != cv::videostab::MM_AFFINE)
69
{
70
71
if(model != cv::videostab::MM_TRANSLATION_AND_SCALE &&
72
model != cv::videostab::MM_TRANSLATION)
73
{
74
const float angle = rng.uniform(minAngle, maxAngle);
75
76
transform.at<float>(1,1) = transform.at<float>(0,0) = std::cos(angle);
77
transform.at<float>(0,1) = std::sin(angle);
78
transform.at<float>(1,0) = -transform.at<float>(0,1);
79
80
}
81
82
if(model == cv::videostab::MM_TRANSLATION_AND_SCALE ||
83
model == cv::videostab::MM_SIMILARITY)
84
{
85
const float scale = rng.uniform(minScale, maxScale);
86
87
transform.at<float>(0,0) *= scale;
88
transform.at<float>(1,1) *= scale;
89
90
}
91
92
}
93
else
94
{
95
transform.at<float>(0,0) = rng.uniform(-affineCoeff, affineCoeff);
96
transform.at<float>(0,1) = rng.uniform(-affineCoeff, affineCoeff);
97
transform.at<float>(1,0) = rng.uniform(-affineCoeff, affineCoeff);
98
transform.at<float>(1,1) = rng.uniform(-affineCoeff, affineCoeff);
99
}
100
101
return transform;
102
}
103
104
105
double testUtil::performTest(const cv::videostab::MotionModel model, int size)
106
{
107
cv::Ptr<cv::videostab::MotionEstimatorRansacL2> estimator = cv::makePtr<cv::videostab::MotionEstimatorRansacL2>(model);
108
109
estimator->setRansacParams(cv::videostab::RansacParams(size, 3.f*testUtil::sigma /*3 sigma rule*/, 0.5f, 0.5f));
110
111
double disparity = 0.;
112
113
for(int attempt = 0; attempt < testUtil::testRun; attempt++)
114
{
115
const cv::Mat transform = testUtil::generateTransform(model);
116
117
const int pointsNumber = testUtil::rng.uniform(10, 100);
118
119
cv::Mat points(3, pointsNumber, CV_32F);
120
121
testUtil::generatePoints(points);
122
123
cv::Mat transformedPoints = transform * points;
124
125
testUtil::addNoise(transformedPoints);
126
127
const cv::Mat src = points.rowRange(0,2).t();
128
const cv::Mat dst = transformedPoints.rowRange(0,2).t();
129
130
bool isOK = false;
131
const cv::Mat estTransform = estimator->estimate(src.reshape(2), dst.reshape(2), &isOK);
132
133
CV_Assert(isOK);
134
const cv::Mat testPoints = estTransform * points;
135
136
const double norm = cv::norm(testPoints, transformedPoints, cv::NORM_INF);
137
138
disparity = std::max(disparity, norm);
139
}
140
141
return disparity;
142
143
}
144
145
TEST(Regression, MM_TRANSLATION)
146
{
147
EXPECT_LT(testUtil::performTest(cv::videostab::MM_TRANSLATION, 2), 7.f);
148
}
149
150
TEST(Regression, MM_TRANSLATION_AND_SCALE)
151
{
152
EXPECT_LT(testUtil::performTest(cv::videostab::MM_TRANSLATION_AND_SCALE, 3), 7.f);
153
}
154
155
TEST(Regression, MM_ROTATION)
156
{
157
EXPECT_LT(testUtil::performTest(cv::videostab::MM_ROTATION, 2), 7.f);
158
}
159
160
TEST(Regression, MM_RIGID)
161
{
162
EXPECT_LT(testUtil::performTest(cv::videostab::MM_RIGID, 3), 7.f);
163
}
164
165
TEST(Regression, MM_SIMILARITY)
166
{
167
EXPECT_LT(testUtil::performTest(cv::videostab::MM_SIMILARITY, 4), 7.f);
168
}
169
170
TEST(Regression, MM_AFFINE)
171
{
172
EXPECT_LT(testUtil::performTest(cv::videostab::MM_AFFINE, 6), 9.f);
173
}
174
175
}} // namespace
176
177