Commit 40b238b0 authored by Tobias Senst's avatar Tobias Senst Committed by Alexander Alekhin

Merge pull request #2367 from tsenst:add_robust_interpolation_of_correspondence

Add RIC method for sparse match interpolation

* * add RIC

* sparse_match_interpolators EdgeAwareInterpolation - enhance limitation of the maximal number of matches to be interpolated from SHORT_MAX to INT_MAX by substituting short by int types

* * add RIC citation

* * update EdgeAwareInterpolatorImpl

* * add intermediate RIC implementation

* * implementation of new paralelization classes. First test where sucessfull.

* * update documentation RICInterpolatorImpl and RLOF

* * update CMakeLists.txt remove highgui
* add test for RIC
* add ASSERTION for curr image

* * add cost map interface

* * fix internal cost map allocation bug

* * remove white spaces
* fix warnings

* *fix compiler warnings

* * remove double whitespaces
* underscore from parameters
* substitute parallel_for_() classes with lambda functions
* remove complex assertion statements
* remove dead code
* substitute swap function with std::swap()
* ocv_define_module now contains video instead of tracking module

* * remove whitespace endings

* * documentation update

* * remove double declarations that lead to warnings

* * unrole tracker.py
*  remove double space
* use static for inner functions
* update create function
* modify mem init. to avoid manual memory management

* * uncomment parallel_for_ for parallelization

* * unrole unwanted changes
* uncomment paralellization

* * remove empty comment
* change CHECK to CHK_GD
* remove not necessary ;

* *documentation remove double space
parent cacec38e
Optical Flow Algorithms
=======================
Algorithms for running and evaluating deepflow, simpleflow, sparsetodenseflow and motion templates (silhouette flow).
Algorithms for running and evaluating deepflow, simpleflow, sparsetodenseflow, robust local optical flow and motion templates (silhouette flow).
......@@ -104,9 +104,26 @@
number = {9},
}
@phdthesis{Senst2019,
title={Estimation and analysis of motion in video data},
author={Senst, Tobias},
year={2019},
school={Technical Univerity Berlin},
doi = {10.14279/depositonce-9085},
url = {https://doi.org/10.14279/depositonce-9085}
}
@article{Tibshirani2008,
title={Fast computation of the median by successive binning},
author={Tibshirani, Ryan J},
journal={arXiv preprint arXiv:0806.3301},
year={2008}
}
@inproceedings{Hu2017,
title={Robust interpolation of correspondences for large displacement optical flow},
author={Hu, Yinlin and Li, Yunsong and Song, Rui},
booktitle={IEEE Conference on Computer Vision and Pattern Recognition},
pages={481--489},
year={2017}
}
\ No newline at end of file
......@@ -30,14 +30,16 @@ enum SolverType {
enum InterpolationType
{
INTERP_GEO = 0, /**< Fast geodesic interpolation, see @cite Geistert2016 */
INTERP_EPIC = 1, /**< Edge-preserving interpolation, see @cite Revaud2015,Geistert2016. */
INTERP_EPIC = 1, /**< Edge-preserving interpolation using ximgproc::EdgeAwareInterpolator, see @cite Revaud2015,Geistert2016. */
INTERP_RIC = 2, /**< SLIC based robust interpolation using ximgproc::RICInterpolator, see @cite Hu2017. */
};
/** @brief This is used store and set up the parameters of the robust local optical flow (RLOF) algoritm.
*
* The RLOF is a fast local optical flow approach described in @cite Senst2012 @cite Senst2013 @cite Senst2014
* and @cite Senst2016 similar to the pyramidal iterative Lucas-Kanade method as
* proposed by @cite Bouguet00. The implementation is derived from optflow::calcOpticalFlowPyrLK().
* proposed by @cite Bouguet00. More details and experiments can be found in the following thesis @cite Senst2019.
* The implementation is derived from optflow::calcOpticalFlowPyrLK().
* This RLOF implementation can be seen as an improved pyramidal iterative Lucas-Kanade and includes
* a set of improving modules. The main improvements in respect to the pyramidal iterative Lucas-Kanade
* are:
......@@ -200,7 +202,8 @@ public:
*
* The RLOF is a fast local optical flow approach described in @cite Senst2012 @cite Senst2013 @cite Senst2014
* and @cite Senst2016 similar to the pyramidal iterative Lucas-Kanade method as
* proposed by @cite Bouguet00. The implementation is derived from optflow::calcOpticalFlowPyrLK().
* proposed by @cite Bouguet00. More details and experiments can be found in the following thesis @cite Senst2019.
* The implementation is derived from optflow::calcOpticalFlowPyrLK().
*
* The sparse-to-dense interpolation scheme allows for fast computation of dense optical flow using RLOF (see @cite Geistert2016).
* For this scheme the following steps are applied:
......@@ -324,6 +327,35 @@ public:
* @see ximgproc::fastGlobalSmootherFilter, setUsePostProc
*/
CV_WRAP virtual bool getUsePostProc() const = 0;
//! @brief enables VariationalRefinement
/**
* @see getUseVariationalRefinement
*/
CV_WRAP virtual void setUseVariationalRefinement(bool val) = 0;
/** @copybrief setUseVariationalRefinement
* @see ximgproc::fastGlobalSmootherFilter, setUsePostProc
*/
CV_WRAP virtual bool getUseVariationalRefinement() const = 0;
//! @brief Parameter to tune the approximate size of the superpixel used for oversegmentation.
/**
* @see cv::ximgproc::createSuperpixelSLIC, cv::ximgproc::RICInterpolator
*/
CV_WRAP virtual void setRICSPSize(int val) = 0;
/** @copybrief setRICSPSize
* @see setRICSPSize
*/
CV_WRAP virtual int getRICSPSize() const = 0;
/** @brief Parameter to choose superpixel algorithm variant to use:
* - cv::ximgproc::SLICType SLIC segments image using a desired region_size (value: 100)
* - cv::ximgproc::SLICType SLICO will optimize using adaptive compactness factor (value: 101)
* - cv::ximgproc::SLICType MSLIC will optimize using manifold methods resulting in more content-sensitive superpixels (value: 102).
* @see cv::ximgproc::createSuperpixelSLIC, cv::ximgproc::RICInterpolator
*/
CV_WRAP virtual void setRICSLICType(int val) = 0;
/** @copybrief setRICSLICType
* @see setRICSLICType
*/
CV_WRAP virtual int getRICSLICType() const = 0;
//! @brief Creates instance of optflow::DenseRLOFOpticalFlow
/**
* @param rlofParam see optflow::RLOFOpticalFlowParameter
......@@ -333,9 +365,12 @@ public:
* @param epicK see setEPICK
* @param epicSigma see setEPICSigma
* @param epicLambda see setEPICLambda
* @param ricSPSize see setRICSPSize
* @param ricSLICType see setRICSLICType
* @param use_post_proc see setUsePostProc
* @param fgsLambda see setFgsLambda
* @param fgsSigma see setFgsSigma
* @param use_variational_refinement see setUseVariationalRefinement
*/
CV_WRAP static Ptr<DenseRLOFOpticalFlow> create(
Ptr<RLOFOpticalFlowParameter> rlofParam = Ptr<RLOFOpticalFlowParameter>(),
......@@ -345,16 +380,20 @@ public:
int epicK = 128,
float epicSigma = 0.05f,
float epicLambda = 999.0f,
int ricSPSize = 15,
int ricSLICType = 100,
bool use_post_proc = true,
float fgsLambda = 500.0f,
float fgsSigma = 1.5f);
float fgsSigma = 1.5f,
bool use_variational_refinement = false);
};
/** @brief Class used for calculation sparse optical flow and feature tracking with robust local optical flow (RLOF) algorithms.
*
* The RLOF is a fast local optical flow approach described in @cite Senst2012 @cite Senst2013 @cite Senst2014
* and @cite Senst2016 similar to the pyramidal iterative Lucas-Kanade method as
* proposed by @cite Bouguet00. The implementation is derived from optflow::calcOpticalFlowPyrLK().
* proposed by @cite Bouguet00. More details and experiments can be found in the following thesis @cite Senst2019.
* The implementation is derived from optflow::calcOpticalFlowPyrLK().
*
* For the RLOF configuration see optflow::RLOFOpticalFlowParameter for further details.
* Parameters have been described in @cite Senst2012, @cite Senst2013, @cite Senst2014 and @cite Senst2016.
......@@ -401,7 +440,8 @@ public:
*
* The RLOF is a fast local optical flow approach described in @cite Senst2012 @cite Senst2013 @cite Senst2014
* and @cite Senst2016 similar to the pyramidal iterative Lucas-Kanade method as
* proposed by @cite Bouguet00. The implementation is derived from optflow::calcOpticalFlowPyrLK().
* proposed by @cite Bouguet00. More details and experiments can be found in the following thesis @cite Senst2019.
* The implementation is derived from optflow::calcOpticalFlowPyrLK().
*
* The sparse-to-dense interpolation scheme allows for fast computation of dense optical flow using RLOF (see @cite Geistert2016).
* For this scheme the following steps are applied:
......@@ -430,12 +470,15 @@ public:
* supported:
* - **INTERP_GEO** applies the fast geodesic interpolation, see @cite Geistert2016.
* - **INTERP_EPIC_RESIDUAL** applies the edge-preserving interpolation, see @cite Revaud2015,Geistert2016.
* @param epicK see ximgproc::EdgeAwareInterpolator() sets the respective parameter.
* @param epicSigma see ximgproc::EdgeAwareInterpolator() sets the respective parameter.
* @param epicLambda see ximgproc::EdgeAwareInterpolator() sets the respective parameter.
* @param epicK see ximgproc::EdgeAwareInterpolator sets the respective parameter.
* @param epicSigma see ximgproc::EdgeAwareInterpolator sets the respective parameter.
* @param epicLambda see ximgproc::EdgeAwareInterpolator sets the respective parameter.
* @param ricSPSize see ximgproc::RICInterpolator sets the respective parameter.
* @param ricSLICType see ximgproc::RICInterpolator sets the respective parameter.
* @param use_post_proc enables ximgproc::fastGlobalSmootherFilter() parameter.
* @param fgsLambda sets the respective ximgproc::fastGlobalSmootherFilter() parameter.
* @param fgsSigma sets the respective ximgproc::fastGlobalSmootherFilter() parameter.
* @param use_variational_refinement enables VariationalRefinement
*
* Parameters have been described in @cite Senst2012, @cite Senst2013, @cite Senst2014, @cite Senst2016.
* For the RLOF configuration see optflow::RLOFOpticalFlowParameter for further details.
......@@ -451,14 +494,17 @@ CV_EXPORTS_W void calcOpticalFlowDenseRLOF(InputArray I0, InputArray I1, InputOu
float forwardBackwardThreshold = 0, Size gridStep = Size(6, 6),
InterpolationType interp_type = InterpolationType::INTERP_EPIC,
int epicK = 128, float epicSigma = 0.05f, float epicLambda = 100.f,
bool use_post_proc = true, float fgsLambda = 500.0f, float fgsSigma = 1.5f);
int ricSPSize = 15, int ricSLICType = 100,
bool use_post_proc = true, float fgsLambda = 500.0f, float fgsSigma = 1.5f,
bool use_variational_refinement = false);
/** @brief Calculates fast optical flow for a sparse feature set using the robust local optical flow (RLOF) similar
* to optflow::calcOpticalFlowPyrLK().
*
* The RLOF is a fast local optical flow approach described in @cite Senst2012 @cite Senst2013 @cite Senst2014
* and @cite Senst2016 similar to the pyramidal iterative Lucas-Kanade method as
* proposed by @cite Bouguet00. The implementation is derived from optflow::calcOpticalFlowPyrLK().
* proposed by @cite Bouguet00. More details and experiments can be found in the following thesis @cite Senst2019.
* The implementation is derived from optflow::calcOpticalFlowPyrLK().
*
* @param prevImg first 8-bit input image. If The cross-based RLOF is used (by selecting optflow::RLOFOpticalFlowParameter::supportRegionType
* = SupportRegionType::SR_CROSS) image has to be a 8-bit 3 channel image.
......
......@@ -12,7 +12,7 @@ using namespace optflow;
const String keys = "{help h usage ? | | print this message }"
"{@image1 | | image1 }"
"{@image2 | | image2 }"
"{@algorithm | | [farneback, simpleflow, tvl1, deepflow, sparsetodenseflow, pcaflow, DISflow_ultrafast, DISflow_fast, DISflow_medium] }"
"{@algorithm | | [farneback, simpleflow, tvl1, deepflow, sparsetodenseflow, RLOF_EPIC, RLOF_RIC, pcaflow, 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] }"
......@@ -259,6 +259,20 @@ int main( int argc, char** argv )
algorithm = createOptFlow_DeepFlow();
else if ( method == "sparsetodenseflow" )
algorithm = createOptFlow_SparseToDense();
else if (method == "RLOF_EPIC")
{
algorithm = createOptFlow_DenseRLOF();
Ptr<DenseRLOFOpticalFlow> rlof = algorithm.dynamicCast< DenseRLOFOpticalFlow>();
rlof->setInterpolation(INTERP_EPIC);
rlof->setForwardBackward(1.f);
}
else if (method == "RLOF_RIC")
{
algorithm = createOptFlow_DenseRLOF();
Ptr<DenseRLOFOpticalFlow> rlof = algorithm.dynamicCast< DenseRLOFOpticalFlow>();;
rlof->setInterpolation(INTERP_RIC);
rlof->setForwardBackward(1.f);
}
else if ( method == "pcaflow" ) {
if ( parser.has("prior") ) {
String prior = parser.get<String>("prior");
......
......@@ -70,6 +70,9 @@ public:
, fgs_lambda(500.0f)
, fgs_sigma(1.5f)
, use_post_proc(true)
, use_variational_refinement(false)
, sp_size(15)
, slic_type(ximgproc::SLIC)
{
prevPyramid[0] = cv::Ptr<CImageBuffer>(new CImageBuffer);
......@@ -107,6 +110,15 @@ public:
virtual bool getUsePostProc() const CV_OVERRIDE { return use_post_proc; }
virtual void setUsePostProc(bool val) CV_OVERRIDE { use_post_proc = val; }
virtual void setUseVariationalRefinement(bool val) CV_OVERRIDE { use_variational_refinement = val; }
virtual bool getUseVariationalRefinement() const CV_OVERRIDE { return use_variational_refinement; }
virtual void setRICSPSize(int val) CV_OVERRIDE { sp_size = val; }
virtual int getRICSPSize() const CV_OVERRIDE { return sp_size; }
virtual void setRICSLICType(int val) CV_OVERRIDE { slic_type = static_cast<ximgproc::SLICType>(val); }
virtual int getRICSLICType() const CV_OVERRIDE { return slic_type; }
virtual void calc(InputArray I0, InputArray I1, InputOutputArray flow) CV_OVERRIDE
{
CV_Assert(!I0.empty() && I0.depth() == CV_8U && (I0.channels() == 3 || I0.channels() == 1));
......@@ -116,7 +128,7 @@ public:
param = Ptr<RLOFOpticalFlowParameter>(new RLOFOpticalFlowParameter());
if (param->supportRegionType == SR_CROSS)
CV_Assert( I0.channels() == 3 && I1.channels() == 3);
CV_Assert(interp_type == InterpolationType::INTERP_EPIC || interp_type == InterpolationType::INTERP_GEO);
CV_Assert(interp_type == InterpolationType::INTERP_EPIC || interp_type == InterpolationType::INTERP_GEO || interp_type == InterpolationType::INTERP_RIC);
// if no parameter is used use the default parameter
Mat prevImage = I0.getMat();
......@@ -184,9 +196,23 @@ public:
gd->setK(k);
gd->setSigma(sigma);
gd->setLambda(lambda);
gd->setFGSLambda(fgs_lambda);
gd->setFGSSigma(fgs_sigma);
gd->setUsePostProcessing(false);
gd->interpolate(prevImage, filtered_prevPoints, currImage, filtered_currPoints, dense_flow);
}
else if (interp_type == InterpolationType::INTERP_RIC)
{
Ptr<ximgproc::RICInterpolator> gd = ximgproc::createRICInterpolator();
gd->setK(k);
gd->setFGSLambda(fgs_lambda);
gd->setFGSSigma(fgs_sigma);
gd->setSuperpixelSize(sp_size);
gd->setSuperpixelMode(slic_type);
gd->setUseGlobalSmootherFilter(false);
gd->setUseVariationalRefinement(false);
gd->interpolate(prevImage, filtered_prevPoints, currImage, filtered_currPoints, dense_flow);
}
else
{
Mat blurredPrevImage, blurredCurrImage;
......@@ -200,6 +226,15 @@ public:
cv::bilateralFilter(vecMats[1], vecMats2[1], 5, 2, 20);
cv::merge(vecMats2, dense_flow);
}
if (use_variational_refinement)
{
Mat prevGrey, currGrey;
Ptr<VariationalRefinement > variationalrefine = VariationalRefinement::create();
cvtColor(prevImage, prevGrey, COLOR_BGR2GRAY);
cvtColor(currImage, currGrey, COLOR_BGR2GRAY);
variationalrefine->setOmega(1.9f);
variationalrefine->calc(prevGrey, currGrey, flow);
}
if (use_post_proc)
{
ximgproc::fastGlobalSmootherFilter(prevImage, flow, flow, fgs_lambda, fgs_sigma);
......@@ -227,6 +262,9 @@ protected:
float fgs_lambda;
float fgs_sigma;
bool use_post_proc;
bool use_variational_refinement;
int sp_size;
ximgproc::SLICType slic_type;
};
Ptr<DenseRLOFOpticalFlow> DenseRLOFOpticalFlow::create(
......@@ -237,9 +275,12 @@ Ptr<DenseRLOFOpticalFlow> DenseRLOFOpticalFlow::create(
int epicK,
float epicSigma,
float epicLambda,
int ricSPSize,
int ricSLICType,
bool use_post_proc,
float fgs_lambda,
float fgs_sigma)
float fgs_sigma,
bool use_variational_refinement)
{
Ptr<DenseRLOFOpticalFlow> algo = makePtr<DenseOpticalFlowRLOFImpl>();
algo->setRLOFOpticalFlowParameter(rlofParam);
......@@ -252,6 +293,9 @@ Ptr<DenseRLOFOpticalFlow> DenseRLOFOpticalFlow::create(
algo->setUsePostProc(use_post_proc);
algo->setFgsLambda(fgs_lambda);
algo->setFgsSigma(fgs_sigma);
algo->setRICSLICType(ricSLICType);
algo->setRICSPSize(ricSPSize);
algo->setUseVariationalRefinement(use_variational_refinement);
return algo;
}
......@@ -381,11 +425,13 @@ void calcOpticalFlowDenseRLOF(InputArray I0, InputArray I1, InputOutputArray flo
float forewardBackwardThreshold, Size gridStep,
InterpolationType interp_type,
int epicK, float epicSigma, float epicLambda,
bool use_post_proc, float fgsLambda, float fgsSigma)
int superpixelSize, int superpixelType,
bool use_post_proc, float fgsLambda, float fgsSigma, bool use_variational_refinement)
{
Ptr<DenseRLOFOpticalFlow> algo = DenseRLOFOpticalFlow::create(
rlofParam, forewardBackwardThreshold, gridStep, interp_type,
epicK, epicSigma, epicLambda, use_post_proc, fgsLambda, fgsSigma);
epicK, epicSigma, epicLambda, superpixelSize, superpixelType,
use_post_proc, fgsLambda, fgsSigma, use_variational_refinement);
algo->calc(I0, I1, flow);
algo->collectGarbage();
}
......
set(the_description "Extended image processing module. It includes edge-aware filters and etc.")
ocv_define_module(ximgproc opencv_core opencv_imgproc opencv_calib3d opencv_imgcodecs WRAP python java)
ocv_define_module(ximgproc opencv_core opencv_imgproc opencv_calib3d opencv_imgcodecs opencv_video WRAP python java)
......@@ -328,3 +328,11 @@ year={2016},
publisher={Springer International Publishing},
pages={617--632},
}
@inproceedings{Hu2017,
title={Robust interpolation of correspondences for large displacement optical flow},
author={Hu, Yinlin and Li, Yunsong and Song, Rui},
booktitle={IEEE Conference on Computer Vision and Pattern Recognition},
pages={481--489},
year={2017}
}
\ No newline at end of file
......@@ -77,6 +77,18 @@ estimator from @cite Revaud2015 and Fast Global Smoother as post-processing filt
class CV_EXPORTS_W EdgeAwareInterpolator : public SparseMatchInterpolator
{
public:
/** @brief Interface to provide a more elaborated cost map, i.e. edge map, for the edge-aware term.
* This implementation is based on a rather simple gradient-based edge map estimation.
* To used more complex edge map estimator (e.g. StructuredEdgeDetection that has been
* used in the original publication) that may lead to improved accuracies, the internal
* edge map estimation can be bypassed here.
* @param _costMap a type CV_32FC1 Mat is required.
* @see cv::ximgproc::createSuperpixelSLIC
*/
CV_WRAP virtual void setCostMap(const Mat & _costMap) = 0;
/** @brief Parameter to tune the approximate size of the superpixel used for oversegmentation.
* @see cv::ximgproc::createSuperpixelSLIC
*/
/** @brief K is a number of nearest-neighbor matches considered, when fitting a locally affine
model. Usually it should be around 128. However, lower values would make the interpolation
noticeably faster.
......@@ -125,6 +137,132 @@ EdgeAwareInterpolator.
CV_EXPORTS_W
Ptr<EdgeAwareInterpolator> createEdgeAwareInterpolator();
/** @brief Sparse match interpolation algorithm based on modified piecewise locally-weighted affine
* estimator called Robust Interpolation method of Correspondences or RIC from @cite Hu2017 and Variational
* and Fast Global Smoother as post-processing filter. The RICInterpolator is a extension of the EdgeAwareInterpolator.
* Main concept of this extension is an piece-wise affine model based on over-segmentation via SLIC superpixel estimation.
* The method contains an efficient propagation mechanism to estimate among the pieces-wise models.
*/
class CV_EXPORTS_W RICInterpolator : public SparseMatchInterpolator
{
public:
/** @brief K is a number of nearest-neighbor matches considered, when fitting a locally affine
*model for a superpixel segment. However, lower values would make the interpolation
*noticeably faster. The original implementation of @cite Hu2017 uses 32.
*/
CV_WRAP virtual void setK(int k = 32) = 0;
/** @copybrief setK
* @see setK
*/
CV_WRAP virtual int getK() const = 0;
/** @brief Interface to provide a more elaborated cost map, i.e. edge map, for the edge-aware term.
* This implementation is based on a rather simple gradient-based edge map estimation.
* To used more complex edge map estimator (e.g. StructuredEdgeDetection that has been
* used in the original publication) that may lead to improved accuracies, the internal
* edge map estimation can be bypassed here.
* @param costMap a type CV_32FC1 Mat is required.
* @see cv::ximgproc::createSuperpixelSLIC
*/
CV_WRAP virtual void setCostMap(const Mat & costMap) = 0;
/** @brief Get the internal cost, i.e. edge map, used for estimating the edge-aware term.
* @see setCostMap
*/
CV_WRAP virtual void setSuperpixelSize(int spSize = 15) = 0;
/** @copybrief setSuperpixelSize
* @see setSuperpixelSize
*/
CV_WRAP virtual int getSuperpixelSize() const = 0;
/** @brief Parameter defines the number of nearest-neighbor matches for each superpixel considered, when fitting a locally affine
*model.
*/
CV_WRAP virtual void setSuperpixelNNCnt(int spNN = 150) = 0;
/** @copybrief setSuperpixelNNCnt
* @see setSuperpixelNNCnt
*/
CV_WRAP virtual int getSuperpixelNNCnt() const = 0;
/** @brief Parameter to tune enforcement of superpixel smoothness factor used for oversegmentation.
* @see cv::ximgproc::createSuperpixelSLIC
*/
CV_WRAP virtual void setSuperpixelRuler(float ruler = 15.f) = 0;
/** @copybrief setSuperpixelRuler
* @see setSuperpixelRuler
*/
CV_WRAP virtual float getSuperpixelRuler() const = 0;
/** @brief Parameter to choose superpixel algorithm variant to use:
* - cv::ximgproc::SLICType SLIC segments image using a desired region_size (value: 100)
* - cv::ximgproc::SLICType SLICO will optimize using adaptive compactness factor (value: 101)
* - cv::ximgproc::SLICType MSLIC will optimize using manifold methods resulting in more content-sensitive superpixels (value: 102).
* @see cv::ximgproc::createSuperpixelSLIC
*/
CV_WRAP virtual void setSuperpixelMode(int mode = 100) = 0;
/** @copybrief setSuperpixelMode
* @see setSuperpixelMode
*/
CV_WRAP virtual int getSuperpixelMode() const = 0;
/** @brief Alpha is a parameter defining a global weight for transforming geodesic distance into weight.
*/
CV_WRAP virtual void setAlpha(float alpha = 0.7f) = 0;
/** @copybrief setAlpha
* @see setAlpha
*/
CV_WRAP virtual float getAlpha() const = 0;
/** @brief Parameter defining the number of iterations for piece-wise affine model estimation.
*/
CV_WRAP virtual void setModelIter(int modelIter = 4) = 0;
/** @copybrief setModelIter
* @see setModelIter
*/
CV_WRAP virtual int getModelIter() const = 0;
/** @brief Parameter to choose wether additional refinement of the piece-wise affine models is employed.
*/
CV_WRAP virtual void setRefineModels(bool refineModles = true) = 0;
/** @copybrief setRefineModels
* @see setRefineModels
*/
CV_WRAP virtual bool getRefineModels() const = 0;
/** @brief MaxFlow is a threshold to validate the predictions using a certain piece-wise affine model.
* If the prediction exceeds the treshold the translational model will be applied instead.
*/
CV_WRAP virtual void setMaxFlow(float maxFlow = 250.f) = 0;
/** @copybrief setMaxFlow
* @see setMaxFlow
*/
CV_WRAP virtual float getMaxFlow() const = 0;
/** @brief Parameter to choose wether the VariationalRefinement post-processing is employed.
*/
CV_WRAP virtual void setUseVariationalRefinement(bool use_variational_refinement = false) = 0;
/** @copybrief setUseVariationalRefinement
* @see setUseVariationalRefinement
*/
CV_WRAP virtual bool getUseVariationalRefinement() const = 0;
/** @brief Sets whether the fastGlobalSmootherFilter() post-processing is employed.
*/
CV_WRAP virtual void setUseGlobalSmootherFilter(bool use_FGS = true) = 0;
/** @copybrief setUseGlobalSmootherFilter
* @see setUseGlobalSmootherFilter
*/
CV_WRAP virtual bool getUseGlobalSmootherFilter() const = 0;
/** @brief Sets the respective fastGlobalSmootherFilter() parameter.
*/
CV_WRAP virtual void setFGSLambda(float lambda = 500.f) = 0;
/** @copybrief setFGSLambda
* @see setFGSLambda
*/
CV_WRAP virtual float getFGSLambda() const = 0;
/** @brief Sets the respective fastGlobalSmootherFilter() parameter.
*/
CV_WRAP virtual void setFGSSigma(float sigma = 1.5f) = 0;
/** @copybrief setFGSSigma
* @see setFGSSigma
*/
CV_WRAP virtual float getFGSSigma() const = 0;
};
/** @brief Factory method that creates an instance of the
RICInterpolator.
*/
CV_EXPORTS_W
Ptr<RICInterpolator> createRICInterpolator();
//! @}
}
}
......
......@@ -95,6 +95,54 @@ TEST(InterpolatorTest, ReferenceAccuracy)
EXPECT_LE(cv::norm(res_flow, ref_flow, NORM_L1) , MAX_MEAN_DIF*res_flow.total());
}
TEST(InterpolatorTest, RICReferenceAccuracy)
{
double MAX_DIF = 6.0;
double MAX_MEAN_DIF = 60.0 / 256.0;
string dir = getDataDir() + "cv/sparse_match_interpolator";
Mat src = imread(getDataDir() + "cv/optflow/RubberWhale1.png", IMREAD_COLOR);
ASSERT_FALSE(src.empty());
Mat ref_flow = readOpticalFlow(dir + "/RubberWhale_reference_result.flo");
ASSERT_FALSE(ref_flow.empty());
Mat src1 = imread(getDataDir() + "cv/optflow/RubberWhale2.png", IMREAD_COLOR);
ASSERT_FALSE(src.empty());
std::ifstream file((dir + "/RubberWhale_sparse_matches.txt").c_str());
float from_x, from_y, to_x, to_y;
vector<Point2f> from_points;
vector<Point2f> to_points;
while (file >> from_x >> from_y >> to_x >> to_y)
{
from_points.push_back(Point2f(from_x, from_y));
to_points.push_back(Point2f(to_x, to_y));
}
Mat res_flow;
Ptr<RICInterpolator> interpolator = createRICInterpolator();
interpolator->setK(32);
interpolator->setSuperpixelSize(15);
interpolator->setSuperpixelNNCnt(150);
interpolator->setSuperpixelRuler(15.f);
interpolator->setSuperpixelMode(ximgproc::SLIC);
interpolator->setAlpha(0.7f);
interpolator->setModelIter(4);
interpolator->setRefineModels(true);
interpolator->setMaxFlow(250.f);
interpolator->setUseVariationalRefinement(true);
interpolator->setUseGlobalSmootherFilter(true);
interpolator->setFGSLambda(500.f);
interpolator->setFGSSigma(1.5f);
interpolator->interpolate(src, from_points, src1, to_points, res_flow);
EXPECT_LE(cv::norm(res_flow, ref_flow, NORM_INF), MAX_DIF);
EXPECT_LE(cv::norm(res_flow, ref_flow, NORM_L1), MAX_MEAN_DIF*res_flow.total());
}
TEST_P(InterpolatorTest, MultiThreadReproducibility)
{
if (cv::getNumberOfCPUs() == 1)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment