Skip to content

Commit 30f718d

Browse files
committed
Merge pull request #708 from sbokov:variational_refinement
2 parents 51a4f6e + b96a5f5 commit 30f718d

14 files changed

+2692
-525
lines changed

modules/optflow/doc/optflow.bib

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,11 @@ @article{Kroeger2016
4444
journal={arXiv preprint arXiv:1603.03590},
4545
year={2016}
4646
}
47+
48+
@inproceedings{Brox2004,
49+
title={High accuracy optical flow estimation based on a theory for warping},
50+
author={Brox, Thomas and Bruhn, Andr{\'e}s and Papenberg, Nils and Weickert, Joachim},
51+
booktitle={European Conference on Computer Vision (ECCV)},
52+
pages={25--36},
53+
year={2004}
54+
}

modules/optflow/include/opencv2/optflow.hpp

Lines changed: 113 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,64 @@ to the flow in the horizontal direction (u), second - vertical (v).
154154
*/
155155
CV_EXPORTS_W bool writeOpticalFlow( const String& path, InputArray flow );
156156

157+
/** @brief Variational optical flow refinement
158+
159+
This class implements variational refinement of the input flow field, i.e.
160+
it uses input flow to initialize the minimization of the following functional:
161+
\f$E(U) = \int_{\Omega} \delta \Psi(E_I) + \gamma \Psi(E_G) + \alpha \Psi(E_S) \f$,
162+
where \f$E_I,E_G,E_S\f$ are color constancy, gradient constancy and smoothness terms
163+
respectively. \f$\Psi(s^2)=\sqrt{s^2+\epsilon^2}\f$ is a robust penalizer to limit the
164+
influence of outliers. A complete formulation and a description of the minimization
165+
procedure can be found in @cite Brox2004
166+
*/
167+
class CV_EXPORTS_W VariationalRefinement : public DenseOpticalFlow
168+
{
169+
public:
170+
/** @brief calc function overload to handle separate horizontal (u) and vertical (v) flow components
171+
(to avoid extra splits/merges) */
172+
CV_WRAP virtual void calcUV(InputArray I0, InputArray I1, InputOutputArray flow_u, InputOutputArray flow_v) = 0;
173+
174+
/** @brief Number of outer (fixed-point) iterations in the minimization procedure.
175+
@see setFixedPointIterations */
176+
CV_WRAP virtual int getFixedPointIterations() const = 0;
177+
/** @copybrief getFixedPointIterations @see getFixedPointIterations */
178+
CV_WRAP virtual void setFixedPointIterations(int val) = 0;
179+
180+
/** @brief Number of inner successive over-relaxation (SOR) iterations
181+
in the minimization procedure to solve the respective linear system.
182+
@see setSorIterations */
183+
CV_WRAP virtual int getSorIterations() const = 0;
184+
/** @copybrief getSorIterations @see getSorIterations */
185+
CV_WRAP virtual void setSorIterations(int val) = 0;
186+
187+
/** @brief Relaxation factor in SOR
188+
@see setOmega */
189+
CV_WRAP virtual float getOmega() const = 0;
190+
/** @copybrief getOmega @see getOmega */
191+
CV_WRAP virtual void setOmega(float val) = 0;
192+
193+
/** @brief Weight of the smoothness term
194+
@see setAlpha */
195+
CV_WRAP virtual float getAlpha() const = 0;
196+
/** @copybrief getAlpha @see getAlpha */
197+
CV_WRAP virtual void setAlpha(float val) = 0;
198+
199+
/** @brief Weight of the color constancy term
200+
@see setDelta */
201+
CV_WRAP virtual float getDelta() const = 0;
202+
/** @copybrief getDelta @see getDelta */
203+
CV_WRAP virtual void setDelta(float val) = 0;
204+
205+
/** @brief Weight of the gradient constancy term
206+
@see setGamma */
207+
CV_WRAP virtual float getGamma() const = 0;
208+
/** @copybrief getGamma @see getGamma */
209+
CV_WRAP virtual void setGamma(float val) = 0;
210+
};
211+
212+
/** @brief Creates an instance of VariationalRefinement
213+
*/
214+
CV_EXPORTS_W Ptr<VariationalRefinement> createVariationalFlowRefinement();
157215

158216
/** @brief DeepFlow optical flow algorithm implementation.
159217
@@ -194,40 +252,80 @@ CV_EXPORTS_W Ptr<DenseOpticalFlow> createOptFlow_SparseToDense();
194252
/** @brief DIS optical flow algorithm.
195253
196254
This class implements the Dense Inverse Search (DIS) optical flow algorithm. More
197-
details about the algorithm can be found at @cite Kroeger2016 .
255+
details about the algorithm can be found at @cite Kroeger2016 . Includes three presets with preselected
256+
parameters to provide reasonable trade-off between speed and quality. However, even the slowest preset is
257+
still relatively fast, use DeepFlow if you need better quality and don't care about speed.
198258
*/
199259
class CV_EXPORTS_W DISOpticalFlow : public DenseOpticalFlow
200260
{
201261
public:
202-
/** @brief Finest level of the gaussian pyramid on which the flow is computed (zero level
203-
corresponds to the original image resolution).The final flow is obtained by bilinear upscaling.
262+
enum
263+
{
264+
PRESET_ULTRAFAST = 0,
265+
PRESET_FAST = 1,
266+
PRESET_MEDIUM = 2
267+
};
268+
269+
/** @brief Finest level of the Gaussian pyramid on which the flow is computed (zero level
270+
corresponds to the original image resolution). The final flow is obtained by bilinear upscaling.
204271
@see setFinestScale */
205-
virtual int getFinestScale() const = 0;
272+
CV_WRAP virtual int getFinestScale() const = 0;
206273
/** @copybrief getFinestScale @see getFinestScale */
207-
virtual void setFinestScale(int val) = 0;
274+
CV_WRAP virtual void setFinestScale(int val) = 0;
208275

209-
/** @brief Size of an image patch for matching (in pixels)
276+
/** @brief Size of an image patch for matching (in pixels). Normally, default 8x8 patches work well
277+
enough in most cases.
210278
@see setPatchSize */
211-
virtual int getPatchSize() const = 0;
279+
CV_WRAP virtual int getPatchSize() const = 0;
212280
/** @copybrief getPatchSize @see getPatchSize */
213-
virtual void setPatchSize(int val) = 0;
281+
CV_WRAP virtual void setPatchSize(int val) = 0;
214282

215-
/** @brief Stride between neighbor patches. Must be less than patch size.
283+
/** @brief Stride between neighbor patches. Must be less than patch size. Lower values correspond
284+
to higher flow quality.
216285
@see setPatchStride */
217-
virtual int getPatchStride() const = 0;
286+
CV_WRAP virtual int getPatchStride() const = 0;
218287
/** @copybrief getPatchStride @see getPatchStride */
219-
virtual void setPatchStride(int val) = 0;
288+
CV_WRAP virtual void setPatchStride(int val) = 0;
220289

221-
/** @brief number of gradient descent iterations in the patch inverse search stage
290+
/** @brief Maximum number of gradient descent iterations in the patch inverse search stage. Higher values
291+
may improve quality in some cases.
222292
@see setGradientDescentIterations */
223-
virtual int getGradientDescentIterations() const = 0;
293+
CV_WRAP virtual int getGradientDescentIterations() const = 0;
294+
/** @copybrief getGradientDescentIterations @see getGradientDescentIterations */
295+
CV_WRAP virtual void setGradientDescentIterations(int val) = 0;
296+
297+
/** @brief Number of fixed point iterations of variational refinement per scale. Set to zero to
298+
disable variational refinement completely. Higher values will typically result in more smooth and
299+
high-quality flow.
300+
@see setGradientDescentIterations */
301+
CV_WRAP virtual int getVariationalRefinementIterations() const = 0;
224302
/** @copybrief getGradientDescentIterations @see getGradientDescentIterations */
225-
virtual void setGradientDescentIterations(int val) = 0;
303+
CV_WRAP virtual void setVariationalRefinementIterations(int val) = 0;
304+
305+
/** @brief Whether to use mean-normalization of patches when computing patch distance. It is turned on
306+
by default as it typically provides a noticeable quality boost because of increased robustness to
307+
illumanition variations. Turn it off if you are certain that your sequence does't contain any changes
308+
in illumination.
309+
@see setUseMeanNormalization */
310+
CV_WRAP virtual bool getUseMeanNormalization() const = 0;
311+
/** @copybrief getUseMeanNormalization @see getUseMeanNormalization */
312+
CV_WRAP virtual void setUseMeanNormalization(bool val) = 0;
313+
314+
/** @brief Whether to use spatial propagation of good optical flow vectors. This option is turned on by
315+
default, as it tends to work better on average and can sometimes help recover from major errors
316+
introduced by the coarse-to-fine scheme employed by the DIS optical flow algorithm. Turning this
317+
option off can make the output flow field a bit smoother, however.
318+
@see setUseSpatialPropagation */
319+
CV_WRAP virtual bool getUseSpatialPropagation() const = 0;
320+
/** @copybrief getUseSpatialPropagation @see getUseSpatialPropagation */
321+
CV_WRAP virtual void setUseSpatialPropagation(bool val) = 0;
226322
};
227323

228324
/** @brief Creates an instance of DISOpticalFlow
325+
326+
@param preset one of PRESET_ULTRAFAST, PRESET_FAST and PRESET_MEDIUM
229327
*/
230-
CV_EXPORTS_W Ptr<DISOpticalFlow> createOptFlow_DIS();
328+
CV_EXPORTS_W Ptr<DISOpticalFlow> createOptFlow_DIS(int preset = DISOpticalFlow::PRESET_FAST);
231329

232330
//! @}
233331

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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 Agreement
8+
* For Open Source Computer Vision Library
9+
* (3 - clause BSD License)
10+
*
11+
* Redistribution and use in source and binary forms, with or without modification,
12+
* are permitted provided that the following conditions are met :
13+
*
14+
* *Redistributions of source code must retain the above copyright notice,
15+
* this list of conditions and the following disclaimer.
16+
*
17+
* * Redistributions in binary form must reproduce the above copyright notice,
18+
* this list of conditions and the following disclaimer in the documentation
19+
* and / or other materials provided with the distribution.
20+
*
21+
* * Neither the names of the copyright holders nor the names of the contributors
22+
* may be used to endorse or promote products derived from this software
23+
* without specific prior written permission.
24+
*
25+
* This software is provided by the copyright holders and contributors "as is" and
26+
* any express or implied warranties, including, but not limited to, the implied
27+
* warranties of merchantability and fitness for a particular purpose are disclaimed.
28+
* In no event shall copyright holders or contributors be liable for any direct,
29+
* indirect, incidental, special, exemplary, or consequential damages
30+
* (including, but not limited to, procurement of substitute goods or services;
31+
* loss of use, data, or profits; or business interruption) however caused
32+
* and on any theory of liability, whether in contract, strict liability,
33+
* or tort(including negligence or otherwise) arising in any way out of
34+
* the use of this software, even if advised of the possibility of such damage.
35+
*/
36+
37+
#include "perf_precomp.hpp"
38+
39+
using std::tr1::tuple;
40+
using std::tr1::get;
41+
using namespace perf;
42+
using namespace testing;
43+
using namespace cv;
44+
using namespace cv::optflow;
45+
46+
typedef tuple<Size> DFParams;
47+
typedef TestBaseWithParam<DFParams> DenseOpticalFlow_DeepFlow;
48+
49+
PERF_TEST_P(DenseOpticalFlow_DeepFlow, perf, Values(szVGA, sz720p))
50+
{
51+
DFParams params = GetParam();
52+
Size sz = get<0>(params);
53+
54+
Mat frame1(sz, CV_8U);
55+
Mat frame2(sz, CV_8U);
56+
Mat flow;
57+
58+
randu(frame1, 0, 255);
59+
randu(frame2, 0, 255);
60+
61+
cv::setNumThreads(cv::getNumberOfCPUs());
62+
TEST_CYCLE_N(1)
63+
{
64+
Ptr<DenseOpticalFlow> algo = createOptFlow_DeepFlow();
65+
algo->calc(frame1, frame2, flow);
66+
}
67+
68+
SANITY_CHECK_NOTHING();
69+
}

modules/optflow/perf/perf_disflow.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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 Agreement
8+
* For Open Source Computer Vision Library
9+
* (3 - clause BSD License)
10+
*
11+
* Redistribution and use in source and binary forms, with or without modification,
12+
* are permitted provided that the following conditions are met :
13+
*
14+
* *Redistributions of source code must retain the above copyright notice,
15+
* this list of conditions and the following disclaimer.
16+
*
17+
* * Redistributions in binary form must reproduce the above copyright notice,
18+
* this list of conditions and the following disclaimer in the documentation
19+
* and / or other materials provided with the distribution.
20+
*
21+
* * Neither the names of the copyright holders nor the names of the contributors
22+
* may be used to endorse or promote products derived from this software
23+
* without specific prior written permission.
24+
*
25+
* This software is provided by the copyright holders and contributors "as is" and
26+
* any express or implied warranties, including, but not limited to, the implied
27+
* warranties of merchantability and fitness for a particular purpose are disclaimed.
28+
* In no event shall copyright holders or contributors be liable for any direct,
29+
* indirect, incidental, special, exemplary, or consequential damages
30+
* (including, but not limited to, procurement of substitute goods or services;
31+
* loss of use, data, or profits; or business interruption) however caused
32+
* and on any theory of liability, whether in contract, strict liability,
33+
* or tort(including negligence or otherwise) arising in any way out of
34+
* the use of this software, even if advised of the possibility of such damage.
35+
*/
36+
37+
#include "perf_precomp.hpp"
38+
39+
using std::tr1::tuple;
40+
using std::tr1::get;
41+
using namespace perf;
42+
using namespace testing;
43+
using namespace cv;
44+
using namespace cv::optflow;
45+
46+
void MakeArtificialExample(Mat &dst_frame1, Mat &dst_frame2);
47+
48+
typedef tuple<String, Size> DISParams;
49+
typedef TestBaseWithParam<DISParams> DenseOpticalFlow_DIS;
50+
51+
PERF_TEST_P(DenseOpticalFlow_DIS, perf,
52+
Combine(Values("PRESET_ULTRAFAST", "PRESET_FAST", "PRESET_MEDIUM"), Values(szVGA, sz720p, sz1080p)))
53+
{
54+
DISParams params = GetParam();
55+
56+
// use strings to print preset names in the perf test results:
57+
String preset_string = get<0>(params);
58+
int preset = DISOpticalFlow::PRESET_FAST;
59+
if (preset_string == "PRESET_ULTRAFAST")
60+
preset = DISOpticalFlow::PRESET_ULTRAFAST;
61+
else if (preset_string == "PRESET_FAST")
62+
preset = DISOpticalFlow::PRESET_FAST;
63+
else if (preset_string == "PRESET_MEDIUM")
64+
preset = DISOpticalFlow::PRESET_MEDIUM;
65+
Size sz = get<1>(params);
66+
67+
Mat frame1(sz, CV_8U);
68+
Mat frame2(sz, CV_8U);
69+
Mat flow;
70+
71+
MakeArtificialExample(frame1, frame2);
72+
73+
cv::setNumThreads(cv::getNumberOfCPUs());
74+
TEST_CYCLE_N(10)
75+
{
76+
Ptr<DenseOpticalFlow> algo = createOptFlow_DIS(preset);
77+
algo->calc(frame1, frame2, flow);
78+
}
79+
80+
SANITY_CHECK_NOTHING();
81+
}
82+
83+
void MakeArtificialExample(Mat &dst_frame1, Mat &dst_frame2)
84+
{
85+
int src_scale = 2;
86+
int OF_scale = 6;
87+
double sigma = dst_frame1.cols / 300;
88+
89+
Mat tmp(Size(dst_frame1.cols / (int)pow(2, src_scale), dst_frame1.rows / (int)pow(2, src_scale)), CV_8U);
90+
randu(tmp, 0, 255);
91+
resize(tmp, dst_frame1, dst_frame1.size(), 0.0, 0.0, INTER_LINEAR);
92+
resize(tmp, dst_frame2, dst_frame2.size(), 0.0, 0.0, INTER_LINEAR);
93+
94+
Mat displacement_field(Size(dst_frame1.cols / (int)pow(2, OF_scale), dst_frame1.rows / (int)pow(2, OF_scale)),
95+
CV_32FC2);
96+
randn(displacement_field, 0.0, sigma);
97+
resize(displacement_field, displacement_field, dst_frame2.size(), 0.0, 0.0, INTER_CUBIC);
98+
for (int i = 0; i < displacement_field.rows; i++)
99+
for (int j = 0; j < displacement_field.cols; j++)
100+
displacement_field.at<Vec2f>(i, j) += Vec2f((float)j, (float)i);
101+
102+
remap(dst_frame2, dst_frame2, displacement_field, Mat(), INTER_LINEAR, BORDER_REPLICATE);
103+
}

modules/optflow/perf/perf_main.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "perf_precomp.hpp"
2+
3+
CV_PERF_TEST_MAIN(optflow)

modules/optflow/perf/perf_precomp.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifdef __GNUC__
2+
# pragma GCC diagnostic ignored "-Wmissing-declarations"
3+
# if defined __clang__ || defined __APPLE__
4+
# pragma GCC diagnostic ignored "-Wmissing-prototypes"
5+
# pragma GCC diagnostic ignored "-Wextra"
6+
# endif
7+
#endif
8+
9+
#ifndef __OPENCV_PERF_PRECOMP_HPP__
10+
#define __OPENCV_PERF_PRECOMP_HPP__
11+
12+
#include "opencv2/ts.hpp"
13+
#include "opencv2/imgproc.hpp"
14+
#include "opencv2/optflow.hpp"
15+
#include "opencv2/highgui.hpp"
16+
17+
#endif

0 commit comments

Comments
 (0)