Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv_contrib
Commits
30f718d1
Commit
30f718d1
authored
Jul 04, 2016
by
Maksim Shabunin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #708 from sbokov:variational_refinement
parents
51a4f6e4
b96a5f59
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
633 additions
and
241 deletions
+633
-241
optflow.bib
modules/optflow/doc/optflow.bib
+8
-0
optflow.hpp
modules/optflow/include/opencv2/optflow.hpp
+113
-15
perf_deepflow.cpp
modules/optflow/perf/perf_deepflow.cpp
+69
-0
perf_disflow.cpp
modules/optflow/perf/perf_disflow.cpp
+103
-0
perf_main.cpp
modules/optflow/perf/perf_main.cpp
+3
-0
perf_precomp.hpp
modules/optflow/perf/perf_precomp.hpp
+17
-0
perf_variational_refinement.cpp
modules/optflow/perf/perf_variational_refinement.cpp
+77
-0
optical_flow_evaluation.cpp
modules/optflow/samples/optical_flow_evaluation.cpp
+8
-4
dis_flow.cpp
modules/optflow/src/dis_flow.cpp
+0
-0
variational_refinement.cpp
modules/optflow/src/variational_refinement.cpp
+0
-0
test_OF_accuracy.cpp
modules/optflow/test/test_OF_accuracy.cpp
+131
-131
test_OF_reproducibility.cpp
modules/optflow/test/test_OF_reproducibility.cpp
+104
-91
No files found.
modules/optflow/doc/optflow.bib
View file @
30f718d1
...
...
@@ -44,3 +44,11 @@
journal={arXiv preprint arXiv:1603.03590},
year={2016}
}
@inproceedings{Brox2004,
title={High accuracy optical flow estimation based on a theory for warping},
author={Brox, Thomas and Bruhn, Andr{\'e}s and Papenberg, Nils and Weickert, Joachim},
booktitle={European Conference on Computer Vision (ECCV)},
pages={25--36},
year={2004}
}
modules/optflow/include/opencv2/optflow.hpp
View file @
30f718d1
...
...
@@ -154,6 +154,64 @@ to the flow in the horizontal direction (u), second - vertical (v).
*/
CV_EXPORTS_W
bool
writeOpticalFlow
(
const
String
&
path
,
InputArray
flow
);
/** @brief Variational optical flow refinement
This class implements variational refinement of the input flow field, i.e.
it uses input flow to initialize the minimization of the following functional:
\f$E(U) = \int_{\Omega} \delta \Psi(E_I) + \gamma \Psi(E_G) + \alpha \Psi(E_S) \f$,
where \f$E_I,E_G,E_S\f$ are color constancy, gradient constancy and smoothness terms
respectively. \f$\Psi(s^2)=\sqrt{s^2+\epsilon^2}\f$ is a robust penalizer to limit the
influence of outliers. A complete formulation and a description of the minimization
procedure can be found in @cite Brox2004
*/
class
CV_EXPORTS_W
VariationalRefinement
:
public
DenseOpticalFlow
{
public
:
/** @brief calc function overload to handle separate horizontal (u) and vertical (v) flow components
(to avoid extra splits/merges) */
CV_WRAP
virtual
void
calcUV
(
InputArray
I0
,
InputArray
I1
,
InputOutputArray
flow_u
,
InputOutputArray
flow_v
)
=
0
;
/** @brief Number of outer (fixed-point) iterations in the minimization procedure.
@see setFixedPointIterations */
CV_WRAP
virtual
int
getFixedPointIterations
()
const
=
0
;
/** @copybrief getFixedPointIterations @see getFixedPointIterations */
CV_WRAP
virtual
void
setFixedPointIterations
(
int
val
)
=
0
;
/** @brief Number of inner successive over-relaxation (SOR) iterations
in the minimization procedure to solve the respective linear system.
@see setSorIterations */
CV_WRAP
virtual
int
getSorIterations
()
const
=
0
;
/** @copybrief getSorIterations @see getSorIterations */
CV_WRAP
virtual
void
setSorIterations
(
int
val
)
=
0
;
/** @brief Relaxation factor in SOR
@see setOmega */
CV_WRAP
virtual
float
getOmega
()
const
=
0
;
/** @copybrief getOmega @see getOmega */
CV_WRAP
virtual
void
setOmega
(
float
val
)
=
0
;
/** @brief Weight of the smoothness term
@see setAlpha */
CV_WRAP
virtual
float
getAlpha
()
const
=
0
;
/** @copybrief getAlpha @see getAlpha */
CV_WRAP
virtual
void
setAlpha
(
float
val
)
=
0
;
/** @brief Weight of the color constancy term
@see setDelta */
CV_WRAP
virtual
float
getDelta
()
const
=
0
;
/** @copybrief getDelta @see getDelta */
CV_WRAP
virtual
void
setDelta
(
float
val
)
=
0
;
/** @brief Weight of the gradient constancy term
@see setGamma */
CV_WRAP
virtual
float
getGamma
()
const
=
0
;
/** @copybrief getGamma @see getGamma */
CV_WRAP
virtual
void
setGamma
(
float
val
)
=
0
;
};
/** @brief Creates an instance of VariationalRefinement
*/
CV_EXPORTS_W
Ptr
<
VariationalRefinement
>
createVariationalFlowRefinement
();
/** @brief DeepFlow optical flow algorithm implementation.
...
...
@@ -194,40 +252,80 @@ CV_EXPORTS_W Ptr<DenseOpticalFlow> createOptFlow_SparseToDense();
/** @brief DIS optical flow algorithm.
This class implements the Dense Inverse Search (DIS) optical flow algorithm. More
details about the algorithm can be found at @cite Kroeger2016 .
details about the algorithm can be found at @cite Kroeger2016 . Includes three presets with preselected
parameters to provide reasonable trade-off between speed and quality. However, even the slowest preset is
still relatively fast, use DeepFlow if you need better quality and don't care about speed.
*/
class
CV_EXPORTS_W
DISOpticalFlow
:
public
DenseOpticalFlow
{
public
:
/** @brief Finest level of the gaussian pyramid on which the flow is computed (zero level
corresponds to the original image resolution).The final flow is obtained by bilinear upscaling.
enum
{
PRESET_ULTRAFAST
=
0
,
PRESET_FAST
=
1
,
PRESET_MEDIUM
=
2
};
/** @brief Finest level of the Gaussian pyramid on which the flow is computed (zero level
corresponds to the original image resolution). The final flow is obtained by bilinear upscaling.
@see setFinestScale */
virtual
int
getFinestScale
()
const
=
0
;
CV_WRAP
virtual
int
getFinestScale
()
const
=
0
;
/** @copybrief getFinestScale @see getFinestScale */
virtual
void
setFinestScale
(
int
val
)
=
0
;
CV_WRAP
virtual
void
setFinestScale
(
int
val
)
=
0
;
/** @brief Size of an image patch for matching (in pixels)
/** @brief Size of an image patch for matching (in pixels). Normally, default 8x8 patches work well
enough in most cases.
@see setPatchSize */
virtual
int
getPatchSize
()
const
=
0
;
CV_WRAP
virtual
int
getPatchSize
()
const
=
0
;
/** @copybrief getPatchSize @see getPatchSize */
virtual
void
setPatchSize
(
int
val
)
=
0
;
CV_WRAP
virtual
void
setPatchSize
(
int
val
)
=
0
;
/** @brief Stride between neighbor patches. Must be less than patch size.
/** @brief Stride between neighbor patches. Must be less than patch size. Lower values correspond
to higher flow quality.
@see setPatchStride */
virtual
int
getPatchStride
()
const
=
0
;
CV_WRAP
virtual
int
getPatchStride
()
const
=
0
;
/** @copybrief getPatchStride @see getPatchStride */
virtual
void
setPatchStride
(
int
val
)
=
0
;
CV_WRAP
virtual
void
setPatchStride
(
int
val
)
=
0
;
/** @brief number of gradient descent iterations in the patch inverse search stage
/** @brief Maximum number of gradient descent iterations in the patch inverse search stage. Higher values
may improve quality in some cases.
@see setGradientDescentIterations */
virtual
int
getGradientDescentIterations
()
const
=
0
;
CV_WRAP
virtual
int
getGradientDescentIterations
()
const
=
0
;
/** @copybrief getGradientDescentIterations @see getGradientDescentIterations */
CV_WRAP
virtual
void
setGradientDescentIterations
(
int
val
)
=
0
;
/** @brief Number of fixed point iterations of variational refinement per scale. Set to zero to
disable variational refinement completely. Higher values will typically result in more smooth and
high-quality flow.
@see setGradientDescentIterations */
CV_WRAP
virtual
int
getVariationalRefinementIterations
()
const
=
0
;
/** @copybrief getGradientDescentIterations @see getGradientDescentIterations */
virtual
void
setGradientDescentIterations
(
int
val
)
=
0
;
CV_WRAP
virtual
void
setVariationalRefinementIterations
(
int
val
)
=
0
;
/** @brief Whether to use mean-normalization of patches when computing patch distance. It is turned on
by default as it typically provides a noticeable quality boost because of increased robustness to
illumanition variations. Turn it off if you are certain that your sequence does't contain any changes
in illumination.
@see setUseMeanNormalization */
CV_WRAP
virtual
bool
getUseMeanNormalization
()
const
=
0
;
/** @copybrief getUseMeanNormalization @see getUseMeanNormalization */
CV_WRAP
virtual
void
setUseMeanNormalization
(
bool
val
)
=
0
;
/** @brief Whether to use spatial propagation of good optical flow vectors. This option is turned on by
default, as it tends to work better on average and can sometimes help recover from major errors
introduced by the coarse-to-fine scheme employed by the DIS optical flow algorithm. Turning this
option off can make the output flow field a bit smoother, however.
@see setUseSpatialPropagation */
CV_WRAP
virtual
bool
getUseSpatialPropagation
()
const
=
0
;
/** @copybrief getUseSpatialPropagation @see getUseSpatialPropagation */
CV_WRAP
virtual
void
setUseSpatialPropagation
(
bool
val
)
=
0
;
};
/** @brief Creates an instance of DISOpticalFlow
@param preset one of PRESET_ULTRAFAST, PRESET_FAST and PRESET_MEDIUM
*/
CV_EXPORTS_W
Ptr
<
DISOpticalFlow
>
createOptFlow_DIS
();
CV_EXPORTS_W
Ptr
<
DISOpticalFlow
>
createOptFlow_DIS
(
int
preset
=
DISOpticalFlow
::
PRESET_FAST
);
//! @}
...
...
modules/optflow/perf/perf_deepflow.cpp
0 → 100644
View file @
30f718d1
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* *Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#include "perf_precomp.hpp"
using
std
::
tr1
::
tuple
;
using
std
::
tr1
::
get
;
using
namespace
perf
;
using
namespace
testing
;
using
namespace
cv
;
using
namespace
cv
::
optflow
;
typedef
tuple
<
Size
>
DFParams
;
typedef
TestBaseWithParam
<
DFParams
>
DenseOpticalFlow_DeepFlow
;
PERF_TEST_P
(
DenseOpticalFlow_DeepFlow
,
perf
,
Values
(
szVGA
,
sz720p
))
{
DFParams
params
=
GetParam
();
Size
sz
=
get
<
0
>
(
params
);
Mat
frame1
(
sz
,
CV_8U
);
Mat
frame2
(
sz
,
CV_8U
);
Mat
flow
;
randu
(
frame1
,
0
,
255
);
randu
(
frame2
,
0
,
255
);
cv
::
setNumThreads
(
cv
::
getNumberOfCPUs
());
TEST_CYCLE_N
(
1
)
{
Ptr
<
DenseOpticalFlow
>
algo
=
createOptFlow_DeepFlow
();
algo
->
calc
(
frame1
,
frame2
,
flow
);
}
SANITY_CHECK_NOTHING
();
}
modules/optflow/perf/perf_disflow.cpp
0 → 100644
View file @
30f718d1
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* *Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#include "perf_precomp.hpp"
using
std
::
tr1
::
tuple
;
using
std
::
tr1
::
get
;
using
namespace
perf
;
using
namespace
testing
;
using
namespace
cv
;
using
namespace
cv
::
optflow
;
void
MakeArtificialExample
(
Mat
&
dst_frame1
,
Mat
&
dst_frame2
);
typedef
tuple
<
String
,
Size
>
DISParams
;
typedef
TestBaseWithParam
<
DISParams
>
DenseOpticalFlow_DIS
;
PERF_TEST_P
(
DenseOpticalFlow_DIS
,
perf
,
Combine
(
Values
(
"PRESET_ULTRAFAST"
,
"PRESET_FAST"
,
"PRESET_MEDIUM"
),
Values
(
szVGA
,
sz720p
,
sz1080p
)))
{
DISParams
params
=
GetParam
();
// use strings to print preset names in the perf test results:
String
preset_string
=
get
<
0
>
(
params
);
int
preset
=
DISOpticalFlow
::
PRESET_FAST
;
if
(
preset_string
==
"PRESET_ULTRAFAST"
)
preset
=
DISOpticalFlow
::
PRESET_ULTRAFAST
;
else
if
(
preset_string
==
"PRESET_FAST"
)
preset
=
DISOpticalFlow
::
PRESET_FAST
;
else
if
(
preset_string
==
"PRESET_MEDIUM"
)
preset
=
DISOpticalFlow
::
PRESET_MEDIUM
;
Size
sz
=
get
<
1
>
(
params
);
Mat
frame1
(
sz
,
CV_8U
);
Mat
frame2
(
sz
,
CV_8U
);
Mat
flow
;
MakeArtificialExample
(
frame1
,
frame2
);
cv
::
setNumThreads
(
cv
::
getNumberOfCPUs
());
TEST_CYCLE_N
(
10
)
{
Ptr
<
DenseOpticalFlow
>
algo
=
createOptFlow_DIS
(
preset
);
algo
->
calc
(
frame1
,
frame2
,
flow
);
}
SANITY_CHECK_NOTHING
();
}
void
MakeArtificialExample
(
Mat
&
dst_frame1
,
Mat
&
dst_frame2
)
{
int
src_scale
=
2
;
int
OF_scale
=
6
;
double
sigma
=
dst_frame1
.
cols
/
300
;
Mat
tmp
(
Size
(
dst_frame1
.
cols
/
(
int
)
pow
(
2
,
src_scale
),
dst_frame1
.
rows
/
(
int
)
pow
(
2
,
src_scale
)),
CV_8U
);
randu
(
tmp
,
0
,
255
);
resize
(
tmp
,
dst_frame1
,
dst_frame1
.
size
(),
0.0
,
0.0
,
INTER_LINEAR
);
resize
(
tmp
,
dst_frame2
,
dst_frame2
.
size
(),
0.0
,
0.0
,
INTER_LINEAR
);
Mat
displacement_field
(
Size
(
dst_frame1
.
cols
/
(
int
)
pow
(
2
,
OF_scale
),
dst_frame1
.
rows
/
(
int
)
pow
(
2
,
OF_scale
)),
CV_32FC2
);
randn
(
displacement_field
,
0.0
,
sigma
);
resize
(
displacement_field
,
displacement_field
,
dst_frame2
.
size
(),
0.0
,
0.0
,
INTER_CUBIC
);
for
(
int
i
=
0
;
i
<
displacement_field
.
rows
;
i
++
)
for
(
int
j
=
0
;
j
<
displacement_field
.
cols
;
j
++
)
displacement_field
.
at
<
Vec2f
>
(
i
,
j
)
+=
Vec2f
((
float
)
j
,
(
float
)
i
);
remap
(
dst_frame2
,
dst_frame2
,
displacement_field
,
Mat
(),
INTER_LINEAR
,
BORDER_REPLICATE
);
}
modules/optflow/perf/perf_main.cpp
0 → 100644
View file @
30f718d1
#include "perf_precomp.hpp"
CV_PERF_TEST_MAIN
(
optflow
)
modules/optflow/perf/perf_precomp.hpp
0 → 100644
View file @
30f718d1
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
# if defined __clang__ || defined __APPLE__
# pragma GCC diagnostic ignored "-Wmissing-prototypes"
# pragma GCC diagnostic ignored "-Wextra"
# endif
#endif
#ifndef __OPENCV_PERF_PRECOMP_HPP__
#define __OPENCV_PERF_PRECOMP_HPP__
#include "opencv2/ts.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/optflow.hpp"
#include "opencv2/highgui.hpp"
#endif
modules/optflow/perf/perf_variational_refinement.cpp
0 → 100644
View file @
30f718d1
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* *Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#include "perf_precomp.hpp"
using
std
::
tr1
::
tuple
;
using
std
::
tr1
::
get
;
using
namespace
perf
;
using
namespace
testing
;
using
namespace
cv
;
using
namespace
cv
::
optflow
;
typedef
tuple
<
Size
,
int
,
int
>
VarRefParams
;
typedef
TestBaseWithParam
<
VarRefParams
>
DenseOpticalFlow_VariationalRefinement
;
PERF_TEST_P
(
DenseOpticalFlow_VariationalRefinement
,
perf
,
Combine
(
Values
(
szQVGA
,
szVGA
),
Values
(
5
,
10
),
Values
(
5
,
10
)))
{
VarRefParams
params
=
GetParam
();
Size
sz
=
get
<
0
>
(
params
);
int
sorIter
=
get
<
1
>
(
params
);
int
fixedPointIter
=
get
<
2
>
(
params
);
Mat
frame1
(
sz
,
CV_8U
);
Mat
frame2
(
sz
,
CV_8U
);
Mat
flow
(
sz
,
CV_32FC2
);
randu
(
frame1
,
0
,
255
);
randu
(
frame2
,
0
,
255
);
flow
.
setTo
(
0.0
f
);
cv
::
setNumThreads
(
cv
::
getNumberOfCPUs
());
TEST_CYCLE_N
(
10
)
{
Ptr
<
VariationalRefinement
>
var
=
createVariationalFlowRefinement
();
var
->
setAlpha
(
20.0
f
);
var
->
setGamma
(
10.0
f
);
var
->
setDelta
(
5.0
f
);
var
->
setSorIterations
(
sorIter
);
var
->
setFixedPointIterations
(
fixedPointIter
);
var
->
calc
(
frame1
,
frame2
,
flow
);
}
SANITY_CHECK_NOTHING
();
}
modules/optflow/samples/optical_flow_evaluation.cpp
View file @
30f718d1
...
...
@@ -11,7 +11,7 @@ using namespace optflow;
const
String
keys
=
"{help h usage ? | | print this message }"
"{@image1 | | image1 }"
"{@image2 | | image2 }"
"{@algorithm | | [farneback, simpleflow, tvl1, deepflow, sparsetodenseflow
or DISflow
] }"
"{@algorithm | | [farneback, simpleflow, tvl1, deepflow, sparsetodenseflow
, DISflow_ultrafast, DISflow_fast, DISflow_medium
] }"
"{@groundtruth | | path to the .flo file (optional), Middlebury format }"
"{m measure |endpoint| error measure - [endpoint or angular] }"
"{r region |all | region to compute stats about [all, discontinuities, untextured] }"
...
...
@@ -229,7 +229,7 @@ int main( int argc, char** argv )
if
(
i2
.
depth
()
!=
CV_8U
)
i2
.
convertTo
(
i2
,
CV_8U
);
if
(
(
method
==
"farneback"
||
method
==
"tvl1"
||
method
==
"deepflow"
||
method
==
"DISflow"
)
&&
i1
.
channels
()
==
3
)
if
(
(
method
==
"farneback"
||
method
==
"tvl1"
||
method
==
"deepflow"
||
method
==
"DISflow
_ultrafast"
||
method
==
"DISflow_fast"
||
method
==
"DISflow_medium
"
)
&&
i1
.
channels
()
==
3
)
{
// 1-channel images are expected
cvtColor
(
i1
,
i1
,
COLOR_BGR2GRAY
);
cvtColor
(
i2
,
i2
,
COLOR_BGR2GRAY
);
...
...
@@ -252,8 +252,12 @@ int main( int argc, char** argv )
algorithm
=
createOptFlow_DeepFlow
();
else
if
(
method
==
"sparsetodenseflow"
)
algorithm
=
createOptFlow_SparseToDense
();
else
if
(
method
==
"DISflow"
)
algorithm
=
createOptFlow_DIS
();
else
if
(
method
==
"DISflow_ultrafast"
)
algorithm
=
createOptFlow_DIS
(
DISOpticalFlow
::
PRESET_ULTRAFAST
);
else
if
(
method
==
"DISflow_fast"
)
algorithm
=
createOptFlow_DIS
(
DISOpticalFlow
::
PRESET_FAST
);
else
if
(
method
==
"DISflow_medium"
)
algorithm
=
createOptFlow_DIS
(
DISOpticalFlow
::
PRESET_MEDIUM
);
else
{
printf
(
"Wrong method!
\n
"
);
...
...
modules/optflow/src/dis_flow.cpp
View file @
30f718d1
This diff is collapsed.
Click to expand it.
modules/optflow/src/variational_refinement.cpp
0 → 100644
View file @
30f718d1
This diff is collapsed.
Click to expand it.
modules/optflow/test/test_
simpleflow
.cpp
→
modules/optflow/test/test_
OF_accuracy
.cpp
View file @
30f718d1
...
...
@@ -40,151 +40,151 @@
//M*/
#include "test_precomp.hpp"
#include <string>
#include <fstream>
using
namespace
std
;
using
namespace
cv
;
using
namespace
cvtest
;
using
namespace
optflow
;
/* ///////////////////// simpleflow_test ///////////////////////// */
static
string
getDataDir
()
{
return
TS
::
ptr
()
->
get_data_path
();
}
class
CV_SimpleFlowTest
:
public
cvtest
::
BaseTest
{
public
:
CV_SimpleFlowTest
();
protected
:
void
run
(
int
);
};
CV_SimpleFlowTest
::
CV_SimpleFlowTest
()
{}
static
bool
readOpticalFlowFromFile
(
FILE
*
file
,
cv
::
Mat
&
flow
)
{
char
header
[
5
];
if
(
fread
(
header
,
1
,
4
,
file
)
<
4
&&
(
string
)
header
!=
"PIEH"
)
{
return
false
;
}
int
cols
,
rows
;
if
(
fread
(
&
cols
,
sizeof
(
int
),
1
,
file
)
!=
1
||
fread
(
&
rows
,
sizeof
(
int
),
1
,
file
)
!=
1
)
{
return
false
;
}
flow
=
cv
::
Mat
::
zeros
(
rows
,
cols
,
CV_32FC2
);
for
(
int
i
=
0
;
i
<
rows
;
++
i
)
{
for
(
int
j
=
0
;
j
<
cols
;
++
j
)
{
cv
::
Vec2f
flow_at_point
;
if
(
fread
(
&
(
flow_at_point
[
0
]),
sizeof
(
float
),
1
,
file
)
!=
1
||
fread
(
&
(
flow_at_point
[
1
]),
sizeof
(
float
),
1
,
file
)
!=
1
)
{
return
false
;
}
flow
.
at
<
cv
::
Vec2f
>
(
i
,
j
)
=
flow_at_point
;
}
}
static
bool
isFlowCorrect
(
float
u
)
{
return
!
cvIsNaN
(
u
)
&&
(
fabs
(
u
)
<
1e9
);
}
return
true
;
}
static
bool
isFlowCorrect
(
float
u
)
{
return
!
cvIsNaN
(
u
)
&&
(
fabs
(
u
)
<
1e9
);
}
static
float
calc_rmse
(
cv
::
Mat
flow1
,
cv
::
Mat
flow2
)
{
float
sum
=
0
;
int
counter
=
0
;
const
int
rows
=
flow1
.
rows
;
const
int
cols
=
flow1
.
cols
;
for
(
int
y
=
0
;
y
<
rows
;
++
y
)
{
for
(
int
x
=
0
;
x
<
cols
;
++
x
)
{
cv
::
Vec2f
flow1_at_point
=
flow1
.
at
<
cv
::
Vec2f
>
(
y
,
x
);
cv
::
Vec2f
flow2_at_point
=
flow2
.
at
<
cv
::
Vec2f
>
(
y
,
x
);
float
u1
=
flow1_at_point
[
0
];
float
v1
=
flow1_at_point
[
1
];
float
u2
=
flow2_at_point
[
0
];
float
v2
=
flow2_at_point
[
1
];
if
(
isFlowCorrect
(
u1
)
&&
isFlowCorrect
(
u2
)
&&
isFlowCorrect
(
v1
)
&&
isFlowCorrect
(
v2
))
{
sum
+=
(
u1
-
u2
)
*
(
u1
-
u2
)
+
(
v1
-
v2
)
*
(
v1
-
v2
);
counter
++
;
}
static
float
calcRMSE
(
Mat
flow1
,
Mat
flow2
)
{
float
sum
=
0
;
int
counter
=
0
;
const
int
rows
=
flow1
.
rows
;
const
int
cols
=
flow1
.
cols
;
for
(
int
y
=
0
;
y
<
rows
;
++
y
)
{
for
(
int
x
=
0
;
x
<
cols
;
++
x
)
{
Vec2f
flow1_at_point
=
flow1
.
at
<
Vec2f
>
(
y
,
x
);
Vec2f
flow2_at_point
=
flow2
.
at
<
Vec2f
>
(
y
,
x
);
float
u1
=
flow1_at_point
[
0
];
float
v1
=
flow1_at_point
[
1
];
float
u2
=
flow2_at_point
[
0
];
float
v2
=
flow2_at_point
[
1
];
if
(
isFlowCorrect
(
u1
)
&&
isFlowCorrect
(
u2
)
&&
isFlowCorrect
(
v1
)
&&
isFlowCorrect
(
v2
))
{
sum
+=
(
u1
-
u2
)
*
(
u1
-
u2
)
+
(
v1
-
v2
)
*
(
v1
-
v2
);
counter
++
;
}
}
}
}
return
(
float
)
sqrt
(
sum
/
(
1e-9
+
counter
));
return
(
float
)
sqrt
(
sum
/
(
1e-9
+
counter
));
}
void
CV_SimpleFlowTest
::
run
(
int
)
{
const
float
MAX_RMSE
=
0.6
f
;
const
string
frame1_path
=
ts
->
get_data_path
()
+
"optflow/RubberWhale1.png"
;
const
string
frame2_path
=
ts
->
get_data_path
()
+
"optflow/RubberWhale2.png"
;
const
string
gt_flow_path
=
ts
->
get_data_path
()
+
"optflow/RubberWhale.flo"
;
cv
::
Mat
frame1
=
cv
::
imread
(
frame1_path
);
cv
::
Mat
frame2
=
cv
::
imread
(
frame2_path
);
if
(
frame1
.
empty
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"could not read image %s
\n
"
,
frame2_path
.
c_str
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
if
(
frame2
.
empty
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"could not read image %s
\n
"
,
frame2_path
.
c_str
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
if
(
frame1
.
rows
!=
frame2
.
rows
&&
frame1
.
cols
!=
frame2
.
cols
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"images should be of equal sizes (%s and %s)"
,
frame1_path
.
c_str
(),
frame2_path
.
c_str
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
if
(
frame1
.
type
()
!=
16
||
frame2
.
type
()
!=
16
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"images should be of equal type CV_8UC3 (%s and %s)"
,
frame1_path
.
c_str
(),
frame2_path
.
c_str
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
cv
::
Mat
flow_gt
;
bool
readRubberWhale
(
Mat
&
dst_frame_1
,
Mat
&
dst_frame_2
,
Mat
&
dst_GT
)
{
const
string
frame1_path
=
getDataDir
()
+
"optflow/RubberWhale1.png"
;
const
string
frame2_path
=
getDataDir
()
+
"optflow/RubberWhale2.png"
;
const
string
gt_flow_path
=
getDataDir
()
+
"optflow/RubberWhale.flo"
;
FILE
*
gt_flow_file
=
fopen
(
gt_flow_path
.
c_str
(),
"rb"
);
if
(
gt_flow_file
==
NULL
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"could not read ground-thuth flow from file %s"
,
gt_flow_path
.
c_str
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
dst_frame_1
=
imread
(
frame1_path
);
dst_frame_2
=
imread
(
frame2_path
);
dst_GT
=
readOpticalFlow
(
gt_flow_path
);
if
(
!
readOpticalFlowFromFile
(
gt_flow_file
,
flow_gt
))
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"error while reading flow data from file %s"
,
gt_flow_path
.
c_str
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
fclose
(
gt_flow_file
);
if
(
dst_frame_1
.
empty
()
||
dst_frame_2
.
empty
()
||
dst_GT
.
empty
())
return
false
;
else
return
true
;
}
cv
::
Mat
flow
;
cv
::
optflow
::
calcOpticalFlowSF
(
frame1
,
frame2
,
flow
,
3
,
2
,
4
);
TEST
(
DenseOpticalFlow_SimpleFlow
,
ReferenceAccuracy
)
{
Mat
frame1
,
frame2
,
GT
;
ASSERT_TRUE
(
readRubberWhale
(
frame1
,
frame2
,
GT
));
float
target_RMSE
=
0.37
f
;
Mat
flow
;
Ptr
<
DenseOpticalFlow
>
algo
;
algo
=
createOptFlow_SimpleFlow
();
algo
->
calc
(
frame1
,
frame2
,
flow
);
ASSERT_EQ
(
GT
.
rows
,
flow
.
rows
);
ASSERT_EQ
(
GT
.
cols
,
flow
.
cols
);
EXPECT_LE
(
calcRMSE
(
GT
,
flow
),
target_RMSE
);
}
float
rmse
=
calc_rmse
(
flow_gt
,
flow
);
TEST
(
DenseOpticalFlow_DeepFlow
,
ReferenceAccuracy
)
{
Mat
frame1
,
frame2
,
GT
;
ASSERT_TRUE
(
readRubberWhale
(
frame1
,
frame2
,
GT
));
float
target_RMSE
=
0.35
f
;
cvtColor
(
frame1
,
frame1
,
COLOR_BGR2GRAY
);
cvtColor
(
frame2
,
frame2
,
COLOR_BGR2GRAY
);
Mat
flow
;
Ptr
<
DenseOpticalFlow
>
algo
;
algo
=
createOptFlow_DeepFlow
();
algo
->
calc
(
frame1
,
frame2
,
flow
);
ASSERT_EQ
(
GT
.
rows
,
flow
.
rows
);
ASSERT_EQ
(
GT
.
cols
,
flow
.
cols
);
EXPECT_LE
(
calcRMSE
(
GT
,
flow
),
target_RMSE
);
}
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Optical flow estimation RMSE for SimpleFlow algorithm : %lf
\n
"
,
rmse
);
TEST
(
DenseOpticalFlow_SparseToDenseFlow
,
ReferenceAccuracy
)
{
Mat
frame1
,
frame2
,
GT
;
ASSERT_TRUE
(
readRubberWhale
(
frame1
,
frame2
,
GT
));
float
target_RMSE
=
0.52
f
;
Mat
flow
;
Ptr
<
DenseOpticalFlow
>
algo
;
algo
=
createOptFlow_SparseToDense
();
algo
->
calc
(
frame1
,
frame2
,
flow
);
ASSERT_EQ
(
GT
.
rows
,
flow
.
rows
);
ASSERT_EQ
(
GT
.
cols
,
flow
.
cols
);
EXPECT_LE
(
calcRMSE
(
GT
,
flow
),
target_RMSE
);
}
if
(
rmse
>
MAX_RMSE
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Too big rmse error : %lf ( >= %lf )
\n
"
,
rmse
,
MAX_RMSE
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
TEST
(
DenseOpticalFlow_DIS
,
ReferenceAccuracy
)
{
Mat
frame1
,
frame2
,
GT
;
ASSERT_TRUE
(
readRubberWhale
(
frame1
,
frame2
,
GT
));
int
presets
[]
=
{
DISOpticalFlow
::
PRESET_ULTRAFAST
,
DISOpticalFlow
::
PRESET_FAST
,
DISOpticalFlow
::
PRESET_MEDIUM
};
float
target_RMSE
[]
=
{
0.86
f
,
0.74
f
,
0.49
f
};
cvtColor
(
frame1
,
frame1
,
COLOR_BGR2GRAY
);
cvtColor
(
frame2
,
frame2
,
COLOR_BGR2GRAY
);
Ptr
<
DenseOpticalFlow
>
algo
;
// iterate over presets:
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
Mat
flow
;
algo
=
createOptFlow_DIS
(
presets
[
i
]);
algo
->
calc
(
frame1
,
frame2
,
flow
);
ASSERT_EQ
(
GT
.
rows
,
flow
.
rows
);
ASSERT_EQ
(
GT
.
cols
,
flow
.
cols
);
EXPECT_LE
(
calcRMSE
(
GT
,
flow
),
target_RMSE
[
i
]);
}
}
TEST
(
Video_OpticalFlowSimpleFlow
,
accuracy
)
{
CV_SimpleFlowTest
test
;
test
.
safe_run
();
}
/* End of file. */
TEST
(
DenseOpticalFlow_VariationalRefinement
,
ReferenceAccuracy
)
{
Mat
frame1
,
frame2
,
GT
;
ASSERT_TRUE
(
readRubberWhale
(
frame1
,
frame2
,
GT
));
float
target_RMSE
=
0.86
f
;
cvtColor
(
frame1
,
frame1
,
COLOR_BGR2GRAY
);
cvtColor
(
frame2
,
frame2
,
COLOR_BGR2GRAY
);
Ptr
<
VariationalRefinement
>
var_ref
;
var_ref
=
createVariationalFlowRefinement
();
var_ref
->
setAlpha
(
20.0
f
);
var_ref
->
setDelta
(
5.0
f
);
var_ref
->
setGamma
(
10.0
f
);
var_ref
->
setSorIterations
(
25
);
var_ref
->
setFixedPointIterations
(
25
);
Mat
flow
(
frame1
.
size
(),
CV_32FC2
);
flow
.
setTo
(
0.0
f
);
var_ref
->
calc
(
frame1
,
frame2
,
flow
);
ASSERT_EQ
(
GT
.
rows
,
flow
.
rows
);
ASSERT_EQ
(
GT
.
cols
,
flow
.
cols
);
EXPECT_LE
(
calcRMSE
(
GT
,
flow
),
target_RMSE
);
}
modules/optflow/test/test_
sparsetodenseflow
.cpp
→
modules/optflow/test/test_
OF_reproducibility
.cpp
View file @
30f718d1
...
...
@@ -40,107 +40,120 @@
//M*/
#include "test_precomp.hpp"
#include <string>
#include <fstream>
using
namespace
std
;
using
namespace
std
::
tr1
;
using
namespace
cv
;
using
namespace
cvtest
;
using
namespace
perf
;
using
namespace
testing
;
using
namespace
optflow
;
/* ///////////////////// sparsetodenseflow_test ///////////////////////// */
typedef
tuple
<
Size
>
OFParams
;
typedef
TestWithParam
<
OFParams
>
DenseOpticalFlow_DIS
;
typedef
TestWithParam
<
OFParams
>
DenseOpticalFlow_VariationalRefinement
;
class
CV_SparseToDenseFlowTest
:
public
cvtest
::
BaseTest
TEST_P
(
DenseOpticalFlow_DIS
,
MultithreadReproducibility
)
{
protected
:
void
run
(
int
);
};
static
bool
isFlowCorrect
(
float
u
)
{
return
!
cvIsNaN
(
u
)
&&
(
fabs
(
u
)
<
1e9
);
}
static
float
calc_rmse
(
Mat
flow1
,
Mat
flow2
)
{
float
sum
=
0
;
int
counter
=
0
;
const
int
rows
=
flow1
.
rows
;
const
int
cols
=
flow1
.
cols
;
for
(
int
y
=
0
;
y
<
rows
;
++
y
)
{
for
(
int
x
=
0
;
x
<
cols
;
++
x
)
{
Vec2f
flow1_at_point
=
flow1
.
at
<
Vec2f
>
(
y
,
x
);
Vec2f
flow2_at_point
=
flow2
.
at
<
Vec2f
>
(
y
,
x
);
float
u1
=
flow1_at_point
[
0
];
float
v1
=
flow1_at_point
[
1
];
float
u2
=
flow2_at_point
[
0
];
float
v2
=
flow2_at_point
[
1
];
if
(
isFlowCorrect
(
u1
)
&&
isFlowCorrect
(
u2
)
&&
isFlowCorrect
(
v1
)
&&
isFlowCorrect
(
v2
))
{
sum
+=
(
u1
-
u2
)
*
(
u1
-
u2
)
+
(
v1
-
v2
)
*
(
v1
-
v2
);
counter
++
;
}
double
MAX_DIF
=
0.01
;
double
MAX_MEAN_DIF
=
0.001
;
int
loopsCount
=
2
;
RNG
rng
(
0
);
OFParams
params
=
GetParam
();
Size
size
=
get
<
0
>
(
params
);
for
(
int
iter
=
0
;
iter
<=
loopsCount
;
iter
++
)
{
Mat
frame1
(
size
,
CV_8U
);
randu
(
frame1
,
0
,
255
);
Mat
frame2
(
size
,
CV_8U
);
randu
(
frame2
,
0
,
255
);
Ptr
<
DISOpticalFlow
>
algo
=
createOptFlow_DIS
();
int
psz
=
rng
.
uniform
(
4
,
16
);
int
pstr
=
rng
.
uniform
(
1
,
psz
-
1
);
int
grad_iter
=
rng
.
uniform
(
1
,
64
);
int
var_iter
=
rng
.
uniform
(
0
,
10
);
bool
use_mean_normalization
=
!!
rng
.
uniform
(
0
,
2
);
bool
use_spatial_propagation
=
!!
rng
.
uniform
(
0
,
2
);
algo
->
setFinestScale
(
0
);
algo
->
setPatchSize
(
psz
);
algo
->
setPatchStride
(
pstr
);
algo
->
setGradientDescentIterations
(
grad_iter
);
algo
->
setVariationalRefinementIterations
(
var_iter
);
algo
->
setUseMeanNormalization
(
use_mean_normalization
);
algo
->
setUseSpatialPropagation
(
use_spatial_propagation
);
cv
::
setNumThreads
(
cv
::
getNumberOfCPUs
());
Mat
resMultiThread
;
algo
->
calc
(
frame1
,
frame2
,
resMultiThread
);
cv
::
setNumThreads
(
1
);
Mat
resSingleThread
;
algo
->
calc
(
frame1
,
frame2
,
resSingleThread
);
EXPECT_LE
(
cv
::
norm
(
resSingleThread
,
resMultiThread
,
NORM_INF
),
MAX_DIF
);
EXPECT_LE
(
cv
::
norm
(
resSingleThread
,
resMultiThread
,
NORM_L1
),
MAX_MEAN_DIF
*
frame1
.
total
());
// resulting flow should be within the frame bounds:
double
min_val
,
max_val
;
minMaxLoc
(
resMultiThread
,
&
min_val
,
&
max_val
);
EXPECT_LE
(
abs
(
min_val
),
sqrt
(
size
.
height
*
size
.
height
+
size
.
width
*
size
.
width
));
EXPECT_LE
(
abs
(
max_val
),
sqrt
(
size
.
height
*
size
.
height
+
size
.
width
*
size
.
width
));
}
}
return
(
float
)
sqrt
(
sum
/
(
1e-9
+
counter
));
}
void
CV_SparseToDenseFlowTest
::
run
(
int
)
{
const
float
MAX_RMSE
=
0.6
f
;
const
string
frame1_path
=
ts
->
get_data_path
()
+
"optflow/RubberWhale1.png"
;
const
string
frame2_path
=
ts
->
get_data_path
()
+
"optflow/RubberWhale2.png"
;
const
string
gt_flow_path
=
ts
->
get_data_path
()
+
"optflow/RubberWhale.flo"
;
Mat
frame1
=
imread
(
frame1_path
);
Mat
frame2
=
imread
(
frame2_path
);
if
(
frame1
.
empty
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"could not read image %s
\n
"
,
frame2_path
.
c_str
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
if
(
frame2
.
empty
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"could not read image %s
\n
"
,
frame2_path
.
c_str
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
if
(
frame1
.
rows
!=
frame2
.
rows
&&
frame1
.
cols
!=
frame2
.
cols
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"images should be of equal sizes (%s and %s)"
,
frame1_path
.
c_str
(),
frame2_path
.
c_str
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
if
(
frame1
.
type
()
!=
16
||
frame2
.
type
()
!=
16
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"images should be of equal type CV_8UC3 (%s and %s)"
,
frame1_path
.
c_str
(),
frame2_path
.
c_str
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
Mat
flow_gt
=
optflow
::
readOpticalFlow
(
gt_flow_path
);
if
(
flow_gt
.
empty
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"error while reading flow data from file %s"
,
gt_flow_path
.
c_str
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISSING_TEST_DATA
);
return
;
}
INSTANTIATE_TEST_CASE_P
(
FullSet
,
DenseOpticalFlow_DIS
,
Values
(
szODD
,
szQVGA
));
Mat
flow
;
optflow
::
calcOpticalFlowSparseToDense
(
frame1
,
frame2
,
flow
);
float
rmse
=
calc_rmse
(
flow_gt
,
flow
);
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Optical flow estimation RMSE for SparseToDenseFlow algorithm : %lf
\n
"
,
rmse
);
if
(
rmse
>
MAX_RMSE
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Too big rmse error : %lf ( >= %lf )
\n
"
,
rmse
,
MAX_RMSE
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
TEST_P
(
DenseOpticalFlow_VariationalRefinement
,
MultithreadReproducibility
)
{
double
MAX_DIF
=
0.01
;
double
MAX_MEAN_DIF
=
0.001
;
float
input_flow_rad
=
5.0
;
int
loopsCount
=
2
;
RNG
rng
(
0
);
OFParams
params
=
GetParam
();
Size
size
=
get
<
0
>
(
params
);
for
(
int
iter
=
0
;
iter
<=
loopsCount
;
iter
++
)
{
Mat
frame1
(
size
,
CV_8U
);
randu
(
frame1
,
0
,
255
);
Mat
frame2
(
size
,
CV_8U
);
randu
(
frame2
,
0
,
255
);
Mat
flow
(
size
,
CV_32FC2
);
randu
(
flow
,
-
input_flow_rad
,
input_flow_rad
);
Ptr
<
VariationalRefinement
>
var
=
createVariationalFlowRefinement
();
var
->
setAlpha
(
rng
.
uniform
(
1.0
f
,
100.0
f
));
var
->
setGamma
(
rng
.
uniform
(
0.1
f
,
10.0
f
));
var
->
setDelta
(
rng
.
uniform
(
0.1
f
,
10.0
f
));
var
->
setSorIterations
(
rng
.
uniform
(
1
,
20
));
var
->
setFixedPointIterations
(
rng
.
uniform
(
1
,
20
));
var
->
setOmega
(
rng
.
uniform
(
1.01
f
,
1.99
f
));
cv
::
setNumThreads
(
cv
::
getNumberOfCPUs
());
Mat
resMultiThread
;
flow
.
copyTo
(
resMultiThread
);
var
->
calc
(
frame1
,
frame2
,
resMultiThread
);
cv
::
setNumThreads
(
1
);
Mat
resSingleThread
;
flow
.
copyTo
(
resSingleThread
);
var
->
calc
(
frame1
,
frame2
,
resSingleThread
);
EXPECT_LE
(
cv
::
norm
(
resSingleThread
,
resMultiThread
,
NORM_INF
),
MAX_DIF
);
EXPECT_LE
(
cv
::
norm
(
resSingleThread
,
resMultiThread
,
NORM_L1
),
MAX_MEAN_DIF
*
frame1
.
total
());
// resulting flow should be within the frame bounds:
double
min_val
,
max_val
;
minMaxLoc
(
resMultiThread
,
&
min_val
,
&
max_val
);
EXPECT_LE
(
abs
(
min_val
),
sqrt
(
size
.
height
*
size
.
height
+
size
.
width
*
size
.
width
));
EXPECT_LE
(
abs
(
max_val
),
sqrt
(
size
.
height
*
size
.
height
+
size
.
width
*
size
.
width
));
}
}
TEST
(
Video_OpticalFlowSparseToDenseFlow
,
accuracy
)
{
CV_SparseToDenseFlowTest
test
;
test
.
safe_run
();
}
INSTANTIATE_TEST_CASE_P
(
FullSet
,
DenseOpticalFlow_VariationalRefinement
,
Values
(
szODD
,
szQVGA
));
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment