Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/videostab/src/outlier_rejection.cpp
16339 views
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-2011, 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 "precomp.hpp"
44
#include "opencv2/videostab/outlier_rejection.hpp"
45
46
namespace cv
47
{
48
namespace videostab
49
{
50
51
void NullOutlierRejector::process(
52
Size /*frameSize*/, InputArray points0, InputArray points1, OutputArray mask)
53
{
54
CV_INSTRUMENT_REGION();
55
56
CV_Assert(points0.type() == points1.type());
57
CV_Assert(points0.getMat().checkVector(2) == points1.getMat().checkVector(2));
58
59
int npoints = points0.getMat().checkVector(2);
60
mask.create(1, npoints, CV_8U);
61
Mat mask_ = mask.getMat();
62
mask_.setTo(1);
63
}
64
65
TranslationBasedLocalOutlierRejector::TranslationBasedLocalOutlierRejector()
66
{
67
setCellSize(Size(50, 50));
68
setRansacParams(RansacParams::default2dMotion(MM_TRANSLATION));
69
}
70
71
72
void TranslationBasedLocalOutlierRejector::process(
73
Size frameSize, InputArray points0, InputArray points1, OutputArray mask)
74
{
75
CV_INSTRUMENT_REGION();
76
77
CV_Assert(points0.type() == points1.type());
78
CV_Assert(points0.getMat().checkVector(2) == points1.getMat().checkVector(2));
79
80
int npoints = points0.getMat().checkVector(2);
81
82
const Point2f* points0_ = points0.getMat().ptr<Point2f>();
83
const Point2f* points1_ = points1.getMat().ptr<Point2f>();
84
85
mask.create(1, npoints, CV_8U);
86
uchar* mask_ = mask.getMat().ptr<uchar>();
87
88
Size ncells((frameSize.width + cellSize_.width - 1) / cellSize_.width,
89
(frameSize.height + cellSize_.height - 1) / cellSize_.height);
90
91
// fill grid cells
92
93
grid_.assign(ncells.area(), Cell());
94
95
for (int i = 0; i < npoints; ++i)
96
{
97
int cx = std::min(cvRound(points0_[i].x / cellSize_.width), ncells.width - 1);
98
int cy = std::min(cvRound(points0_[i].y / cellSize_.height), ncells.height - 1);
99
grid_[cy * ncells.width + cx].push_back(i);
100
}
101
102
// process each cell
103
104
RNG rng(0);
105
int niters = ransacParams_.niters();
106
std::vector<int> inliers;
107
108
for (size_t ci = 0; ci < grid_.size(); ++ci)
109
{
110
// estimate translation model at the current cell using RANSAC
111
112
float x1, y1;
113
const Cell &cell = grid_[ci];
114
int ninliers, ninliersMax = 0;
115
float dxBest = 0.f, dyBest = 0.f;
116
117
// find the best hypothesis
118
119
if (!cell.empty())
120
{
121
for (int iter = 0; iter < niters; ++iter)
122
{
123
int idx = cell[static_cast<unsigned>(rng) % cell.size()];
124
float dx = points1_[idx].x - points0_[idx].x;
125
float dy = points1_[idx].y - points0_[idx].y;
126
127
ninliers = 0;
128
for (size_t i = 0; i < cell.size(); ++i)
129
{
130
x1 = points0_[cell[i]].x + dx;
131
y1 = points0_[cell[i]].y + dy;
132
if (sqr(x1 - points1_[cell[i]].x) + sqr(y1 - points1_[cell[i]].y) <
133
sqr(ransacParams_.thresh))
134
{
135
ninliers++;
136
}
137
}
138
139
if (ninliers > ninliersMax)
140
{
141
ninliersMax = ninliers;
142
dxBest = dx;
143
dyBest = dy;
144
}
145
}
146
}
147
148
// get the best hypothesis inliers
149
150
ninliers = 0;
151
inliers.resize(ninliersMax);
152
for (size_t i = 0; i < cell.size(); ++i)
153
{
154
x1 = points0_[cell[i]].x + dxBest;
155
y1 = points0_[cell[i]].y + dyBest;
156
if (sqr(x1 - points1_[cell[i]].x) + sqr(y1 - points1_[cell[i]].y) <
157
sqr(ransacParams_.thresh))
158
{
159
inliers[ninliers++] = cell[i];
160
}
161
}
162
163
// refine the best hypothesis
164
165
dxBest = dyBest = 0.f;
166
for (size_t i = 0; i < inliers.size(); ++i)
167
{
168
dxBest += points1_[inliers[i]].x - points0_[inliers[i]].x;
169
dyBest += points1_[inliers[i]].y - points0_[inliers[i]].y;
170
}
171
if (!inliers.empty())
172
{
173
dxBest /= inliers.size();
174
dyBest /= inliers.size();
175
}
176
177
// set mask elements for refined model inliers
178
179
for (size_t i = 0; i < cell.size(); ++i)
180
{
181
x1 = points0_[cell[i]].x + dxBest;
182
y1 = points0_[cell[i]].y + dyBest;
183
if (sqr(x1 - points1_[cell[i]].x) + sqr(y1 - points1_[cell[i]].y) <
184
sqr(ransacParams_.thresh))
185
{
186
mask_[cell[i]] = 1;
187
}
188
else
189
{
190
mask_[cell[i]] = 0;
191
}
192
}
193
}
194
}
195
196
} // namespace videostab
197
} // namespace cv
198
199