Commit 7225f89e authored by Andrey Kamaev's avatar Andrey Kamaev

Revert opencv_videostab to the state of 2.4.2

parent e5437e54
...@@ -140,7 +140,6 @@ OCV_OPTION(WITH_V4L "Include Video 4 Linux support" ON ...@@ -140,7 +140,6 @@ OCV_OPTION(WITH_V4L "Include Video 4 Linux support" ON
OCV_OPTION(WITH_VIDEOINPUT "Build HighGUI with DirectShow support" ON IF WIN32 ) OCV_OPTION(WITH_VIDEOINPUT "Build HighGUI with DirectShow support" ON IF WIN32 )
OCV_OPTION(WITH_XIMEA "Include XIMEA cameras support" OFF IF (NOT ANDROID AND NOT APPLE) ) OCV_OPTION(WITH_XIMEA "Include XIMEA cameras support" OFF IF (NOT ANDROID AND NOT APPLE) )
OCV_OPTION(WITH_XINE "Include Xine support (GPL)" OFF IF (UNIX AND NOT APPLE AND NOT ANDROID) ) OCV_OPTION(WITH_XINE "Include Xine support (GPL)" OFF IF (UNIX AND NOT APPLE AND NOT ANDROID) )
OCV_OPTION(WITH_CLP "Include Clp support (EPL)" OFF)
OCV_OPTION(WITH_OPENCL "Include OpenCL Runtime support" OFF IF (NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_OPENCL "Include OpenCL Runtime support" OFF IF (NOT ANDROID AND NOT IOS) )
OCV_OPTION(WITH_OPENCLAMDFFT "Include AMD OpenCL FFT library support" OFF IF (NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_OPENCLAMDFFT "Include AMD OpenCL FFT library support" OFF IF (NOT ANDROID AND NOT IOS) )
OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" OFF IF (NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" OFF IF (NOT ANDROID AND NOT IOS) )
...@@ -763,7 +762,6 @@ endif(DEFINED WITH_CUDA) ...@@ -763,7 +762,6 @@ endif(DEFINED WITH_CUDA)
status(" Use OpenCL:" HAVE_OPENCL THEN YES ELSE NO) status(" Use OpenCL:" HAVE_OPENCL THEN YES ELSE NO)
status(" Use Eigen:" HAVE_EIGEN THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO) status(" Use Eigen:" HAVE_EIGEN THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO)
status(" Use Clp:" HAVE_CLP THEN YES ELSE NO)
if(HAVE_CUDA) if(HAVE_CUDA)
status("") status("")
......
...@@ -43,42 +43,3 @@ if(WITH_EIGEN) ...@@ -43,42 +43,3 @@ if(WITH_EIGEN)
set(HAVE_EIGEN 1) set(HAVE_EIGEN 1)
endif() endif()
endif(WITH_EIGEN) endif(WITH_EIGEN)
# --- Clp ---
# Ubuntu: sudo apt-get install coinor-libclp-dev coinor-libcoinutils-dev
ocv_clear_vars(HAVE_CLP)
if(WITH_CLP)
if(UNIX)
PKG_CHECK_MODULES(CLP clp)
if(CLP_FOUND)
set(HAVE_CLP TRUE)
if(NOT ${CLP_INCLUDE_DIRS} STREQUAL "")
ocv_include_directories(${CLP_INCLUDE_DIRS})
endif()
link_directories(${CLP_LIBRARY_DIRS})
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CLP_LIBRARIES})
endif()
endif()
if(NOT CLP_FOUND)
find_path(CLP_INCLUDE_PATH "coin"
PATHS "/usr/local/include" "/usr/include" "/opt/include"
DOC "The path to Clp headers")
if(CLP_INCLUDE_PATH)
ocv_include_directories(${CLP_INCLUDE_PATH} "${CLP_INCLUDE_PATH}/coin")
get_filename_component(_CLP_LIBRARY_DIR "${CLP_INCLUDE_PATH}/../lib" ABSOLUTE)
set(CLP_LIBRARY_DIR "${_CLP_LIBRARY_DIR}" CACHE PATH "Full path of Clp library directory")
link_directories(${CLP_LIBRARY_DIR})
if(UNIX)
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} Clp CoinUtils m)
else()
if(MINGW)
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} Clp CoinUtils)
else()
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} libClp libCoinUtils)
endif()
endif()
set(HAVE_CLP TRUE)
endif()
endif()
endif(WITH_CLP)
\ No newline at end of file
set(the_description "Video stabilization") set(the_description "Video stabilization")
ocv_define_module(videostab opencv_imgproc opencv_features2d opencv_video opencv_photo opencv_calib3d OPTIONAL opencv_gpu opencv_highgui) ocv_define_module(videostab opencv_imgproc opencv_features2d opencv_video opencv_photo opencv_calib3d opencv_highgui OPTIONAL opencv_gpu)
Fast Marching Method
====================
.. highlight:: cpp
The Fast Marching Method [T04]_ is used in of the video stabilization routines to do motion and color inpainting. The method is implemented is a flexible way and it's made public for other users.
videostab::FastMarchingMethod
-----------------------------
.. ocv:class:: videostab::FastMarchingMethod
Describes the Fast Marching Method implementation.
::
class CV_EXPORTS FastMarchingMethod
{
public:
FastMarchingMethod();
template <typename Inpaint>
Inpaint run(const Mat &mask, Inpaint inpaint);
Mat distanceMap() const;
};
videostab::FastMarchingMethod::FastMarchingMethod
-------------------------------------------------
Constructor.
.. ocv:function:: videostab::FastMarchingMethod::FastMarchingMethod()
videostab::FastMarchingMethod::run
----------------------------------
Template method that runs the Fast Marching Method.
.. ocv:function:: Inpaint FastMarchingMethod::run(const Mat &mask, Inpaint inpaint)
:param mask: Image mask. ``0`` value indicates that the pixel value must be inpainted, ``255`` indicates that the pixel value is known, other values aren't acceptable.
:param inpaint: Inpainting functor that overloads ``void operator ()(int x, int y)``.
:return: Inpainting functor.
videostab::FastMarchingMethod::distanceMap
------------------------------------------
.. ocv:function:: Mat videostab::FastMarchingMethod::distanceMap() const
:return: Distance map that's created during working of the method.
Global Motion Estimation
========================
.. highlight:: cpp
The video stabilization module contains a set of functions and classes for global motion estimation between point clouds or between images. In the last case features are extracted and matched internally. For the sake of convenience the motion estimation functions are wrapped into classes. Both the functions and the classes are available.
videostab::MotionModel
----------------------
.. ocv:class:: videostab::MotionModel
Describes motion model between two point clouds.
::
enum MotionModel
{
MM_TRANSLATION = 0,
MM_TRANSLATION_AND_SCALE = 1,
MM_ROTATION = 2,
MM_RIGID = 3,
MM_SIMILARITY = 4,
MM_AFFINE = 5,
MM_HOMOGRAPHY = 6,
MM_UNKNOWN = 7
};
videostab::RansacParams
-----------------------
.. ocv:class:: videostab::RansacParams
Describes RANSAC method parameters.
::
struct CV_EXPORTS RansacParams
{
int size; // subset size
float thresh; // max error to classify as inlier
float eps; // max outliers ratio
float prob; // probability of success
RansacParams() : size(0), thresh(0), eps(0), prob(0) {}
RansacParams(int size, float thresh, float eps, float prob);
int niters() const;
static RansacParams default2dMotion(MotionModel model);
};
videostab::RansacParams::RansacParams
-------------------------------------
.. ocv:function:: RansacParams::RansacParams()
:return: RANSAC method empty parameters object.
videostab::RansacParams::RansacParams
-------------------------------------
.. ocv:function:: RansacParams::RansacParams(int size, float thresh, float eps, float prob)
:param size: Subset size.
:param thresh: Maximum re-projection error value to classify as inlier.
:param eps: Maximum ratio of incorrect correspondences.
:param prob: Required success probability.
:return: RANSAC method parameters object.
videostab::RansacParams::niters
-------------------------------
.. ocv:function:: int RansacParams::niters() const
:return: Number of iterations that'll be performed by RANSAC method.
videostab::RansacParams::default2dMotion
----------------------------------------
.. ocv:function:: static RansacParams RansacParams::default2dMotion(MotionModel model)
:param model: Motion model. See :ocv:class:`videostab::MotionModel`.
:return: Default RANSAC method parameters for the given motion model.
videostab::estimateGlobalMotionLeastSquares
-------------------------------------------
Estimates best global motion between two 2D point clouds in the least-squares sense.
.. note:: Works in-place and changes input point arrays.
.. ocv:function:: Mat estimateGlobalMotionLeastSquares(InputOutputArray points0, InputOutputArray points1, int model = MM_AFFINE, float *rmse = 0)
:param points0: Source set of 2D points (``32F``).
:param points1: Destination set of 2D points (``32F``).
:param model: Motion model (up to ``MM_AFFINE``).
:param rmse: Final root-mean-square error.
:return: 3x3 2D transformation matrix (``32F``).
videostab::estimateGlobalMotionRansac
-------------------------------------
Estimates best global motion between two 2D point clouds robustly (using RANSAC method).
.. ocv:function:: Mat estimateGlobalMotionRansac(InputArray points0, InputArray points1, int model = MM_AFFINE, const RansacParams &params = RansacParams::default2dMotion(MM_AFFINE), float *rmse = 0, int *ninliers = 0)
:param points0: Source set of 2D points (``32F``).
:param points1: Destination set of 2D points (``32F``).
:param model: Motion model. See :ocv:class:`videostab::MotionModel`.
:param params: RANSAC method parameters. See :ocv:class:`videostab::RansacParams`.
:param rmse: Final root-mean-square error.
:param ninliers: Final number of inliers.
videostab::getMotion
--------------------
Computes motion between two frames assuming that all the intermediate motions are known.
.. ocv:function:: Mat getMotion(int from, int to, const std::vector<Mat> &motions)
:param from: Source frame index.
:param to: Destination frame index.
:param motions: Pair-wise motions. ``motions[i]`` denotes motion from the frame ``i`` to the frame ``i+1``
:return: Motion from the frame ``from`` to the frame ``to``.
videostab::MotionEstimatorBase
------------------------------
.. ocv:class:: videostab::MotionEstimatorBase
Base class for all global motion estimation methods.
::
class CV_EXPORTS MotionEstimatorBase
{
public:
virtual ~MotionEstimatorBase();
virtual void setMotionModel(MotionModel val);
virtual MotionModel motionModel() const;
virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0) = 0;
};
videostab::MotionEstimatorBase::setMotionModel
----------------------------------------------
Sets motion model.
.. ocv:function:: void MotionEstimatorBase::setMotionModel(MotionModel val)
:param val: Motion model. See :ocv:class:`videostab::MotionModel`.
videostab::MotionEstimatorBase::motionModel
----------------------------------------------
.. ocv:function:: MotionModel MotionEstimatorBase::motionModel() const
:return: Motion model. See :ocv:class:`videostab::MotionModel`.
videostab::MotionEstimatorBase::estimate
----------------------------------------
Estimates global motion between two 2D point clouds.
.. ocv:function:: Mat MotionEstimatorBase::estimate(InputArray points0, InputArray points1, bool *ok = 0)
:param points0: Source set of 2D points (``32F``).
:param points1: Destination set of 2D points (``32F``).
:param ok: Indicates whether motion was estimated successfully.
:return: 3x3 2D transformation matrix (``32F``).
videostab::MotionEstimatorRansacL2
----------------------------------
.. ocv:class:: videostab::MotionEstimatorRansacL2
Describes a robust RANSAC-based global 2D motion estimation method which minimizes L2 error.
::
class CV_EXPORTS MotionEstimatorRansacL2 : public MotionEstimatorBase
{
public:
MotionEstimatorRansacL2(MotionModel model = MM_AFFINE);
void setRansacParams(const RansacParams &val);
RansacParams ransacParams() const;
void setMinInlierRatio(float val);
float minInlierRatio() const;
virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0);
};
videostab::MotionEstimatorL1
----------------------------
.. ocv:class:: videostab::MotionEstimatorL1
Describes a global 2D motion estimation method which minimizes L1 error.
.. note:: To be able to use this method you must build OpenCV with CLP library support.
::
class CV_EXPORTS MotionEstimatorL1 : public MotionEstimatorBase
{
public:
MotionEstimatorL1(MotionModel model = MM_AFFINE);
virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0);
};
videostab::ImageMotionEstimatorBase
-----------------------------------
.. ocv:class:: videostab::ImageMotionEstimatorBase
Base class for global 2D motion estimation methods which take frames as input.
::
class CV_EXPORTS ImageMotionEstimatorBase
{
public:
virtual ~ImageMotionEstimatorBase();
virtual void setMotionModel(MotionModel val);
virtual MotionModel motionModel() const;
virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) = 0;
};
videostab::KeypointBasedMotionEstimator
---------------------------------------
.. ocv:class:: videostab::KeypointBasedMotionEstimator
Describes a global 2D motion estimation method which uses keypoints detection and optical flow for matching.
::
class CV_EXPORTS KeypointBasedMotionEstimator : public ImageMotionEstimatorBase
{
public:
KeypointBasedMotionEstimator(Ptr<MotionEstimatorBase> estimator);
virtual void setMotionModel(MotionModel val);
virtual MotionModel motionModel() const;
void setDetector(Ptr<FeatureDetector> val);
Ptr<FeatureDetector> detector() const;
void setOpticalFlowEstimator(Ptr<ISparseOptFlowEstimator> val);
Ptr<ISparseOptFlowEstimator> opticalFlowEstimator() const;
void setOutlierRejector(Ptr<IOutlierRejector> val);
Ptr<IOutlierRejector> outlierRejector() const;
virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0);
};
Introduction
============
The video stabilization module contains a set of functions and classes that can be used to solve the problem of video stabilization. There are a few methods implemented, most of them are descibed in the papers [OF06]_ and [G11]_. However, there are some extensions and deviations from the orginal paper methods.
References
----------
.. [OF06] Full-Frame Video Stabilization with Motion Inpainting. Matsushita, Y. Ofek, E. Ge, W. Tang, X. Shum, H.-Y., IEEE TRANSACTIONS ON PATTERN ANALYSIS AND MACHINE INTELLIGENCE, 2006
.. [G11] Auto-directed video stabilization with robust L1 optimal camera paths, M. Grundmann, V. Kwatra, I. Essa, Computer Vision and Pattern Recognition (CVPR), 2011
.. [T04] An Image Inpainting Technique Based on the Fast Marching Method, Alexandru Telea, Journal of graphics tools, 2004
******************************
videostab. Video Stabilization
******************************
.. toctree::
:maxdepth: 2
introduction
global_motion
fast_marching
...@@ -56,15 +56,13 @@ CV_EXPORTS float calcBlurriness(const Mat &frame); ...@@ -56,15 +56,13 @@ CV_EXPORTS float calcBlurriness(const Mat &frame);
class CV_EXPORTS DeblurerBase class CV_EXPORTS DeblurerBase
{ {
public: public:
DeblurerBase() : radius_(0), frames_(0), motions_(0), blurrinessRates_(0) {} DeblurerBase() : radius_(0), frames_(0), motions_(0) {}
virtual ~DeblurerBase() {} virtual ~DeblurerBase() {}
virtual void setRadius(int val) { radius_ = val; } virtual void setRadius(int val) { radius_ = val; }
virtual int radius() const { return radius_; } virtual int radius() const { return radius_; }
// data from stabilizer
virtual void setFrames(const std::vector<Mat> &val) { frames_ = &val; } virtual void setFrames(const std::vector<Mat> &val) { frames_ = &val; }
virtual const std::vector<Mat>& frames() const { return *frames_; } virtual const std::vector<Mat>& frames() const { return *frames_; }
...@@ -75,6 +73,7 @@ public: ...@@ -75,6 +73,7 @@ public:
virtual const std::vector<float>& blurrinessRates() const { return *blurrinessRates_; } virtual const std::vector<float>& blurrinessRates() const { return *blurrinessRates_; }
virtual void update() {} virtual void update() {}
virtual void deblur(int idx, Mat &frame) = 0; virtual void deblur(int idx, Mat &frame) = 0;
protected: protected:
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include "opencv2/core/core.hpp" #include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
namespace cv namespace cv
{ {
...@@ -75,13 +76,13 @@ public: ...@@ -75,13 +76,13 @@ public:
virtual void reset(); virtual void reset();
virtual Mat nextFrame(); virtual Mat nextFrame();
int width(); int frameCount() { return static_cast<int>(reader_.get(CV_CAP_PROP_FRAME_COUNT)); }
int height(); double fps() { return reader_.get(CV_CAP_PROP_FPS); }
int count();
double fps();
private: private:
Ptr<IFrameSource> impl; std::string path_;
bool volatileFrame_;
VideoCapture reader_;
}; };
} // namespace videostab } // namespace videostab
......
...@@ -44,192 +44,94 @@ ...@@ -44,192 +44,94 @@
#define __OPENCV_VIDEOSTAB_GLOBAL_MOTION_HPP__ #define __OPENCV_VIDEOSTAB_GLOBAL_MOTION_HPP__
#include <vector> #include <vector>
#include <string>
#include <fstream>
#include "opencv2/core/core.hpp" #include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp" #include "opencv2/features2d/features2d.hpp"
#include "opencv2/opencv_modules.hpp"
#include "opencv2/videostab/optical_flow.hpp" #include "opencv2/videostab/optical_flow.hpp"
#include "opencv2/videostab/motion_core.hpp"
#include "opencv2/videostab/outlier_rejection.hpp"
#ifdef HAVE_OPENCV_GPU
#include "opencv2/gpu/gpu.hpp"
#endif
namespace cv namespace cv
{ {
namespace videostab namespace videostab
{ {
CV_EXPORTS Mat estimateGlobalMotionLeastSquares( enum MotionModel
InputOutputArray points0, InputOutputArray points1, int model = MM_AFFINE,
float *rmse = 0);
CV_EXPORTS Mat estimateGlobalMotionRansac(
InputArray points0, InputArray points1, int model = MM_AFFINE,
const RansacParams &params = RansacParams::default2dMotion(MM_AFFINE),
float *rmse = 0, int *ninliers = 0);
class CV_EXPORTS MotionEstimatorBase
{ {
public: TRANSLATION = 0,
virtual ~MotionEstimatorBase() {} TRANSLATION_AND_SCALE = 1,
LINEAR_SIMILARITY = 2,
virtual void setMotionModel(MotionModel val) { motionModel_ = val; } AFFINE = 3
virtual MotionModel motionModel() const { return motionModel_; }
virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0) = 0;
protected:
MotionEstimatorBase(MotionModel model) { setMotionModel(model); }
private:
MotionModel motionModel_;
}; };
class CV_EXPORTS MotionEstimatorRansacL2 : public MotionEstimatorBase CV_EXPORTS Mat estimateGlobalMotionLeastSquares(
{ const std::vector<Point2f> &points0, const std::vector<Point2f> &points1,
public: int model = AFFINE, float *rmse = 0);
MotionEstimatorRansacL2(MotionModel model = MM_AFFINE);
void setRansacParams(const RansacParams &val) { ransacParams_ = val; }
RansacParams ransacParams() const { return ransacParams_; }
void setMinInlierRatio(float val) { minInlierRatio_ = val; }
float minInlierRatio() const { return minInlierRatio_; }
virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0);
private:
RansacParams ransacParams_;
float minInlierRatio_;
};
class CV_EXPORTS MotionEstimatorL1 : public MotionEstimatorBase struct CV_EXPORTS RansacParams
{ {
public: int size; // subset size
MotionEstimatorL1(MotionModel model = MM_AFFINE); float thresh; // max error to classify as inlier
float eps; // max outliers ratio
virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0); float prob; // probability of success
private: RansacParams(int _size, float _thresh, float _eps, float _prob)
std::vector<double> obj_, collb_, colub_; : size(_size), thresh(_thresh), eps(_eps), prob(_prob) {}
std::vector<double> elems_, rowlb_, rowub_;
std::vector<int> rows_, cols_; static RansacParams translationMotionStd() { return RansacParams(2, 0.5f, 0.5f, 0.99f); }
static RansacParams translationAndScale2dMotionStd() { return RansacParams(3, 0.5f, 0.5f, 0.99f); }
void set(int row, int col, double coef) static RansacParams linearSimilarityMotionStd() { return RansacParams(4, 0.5f, 0.5f, 0.99f); }
{ static RansacParams affine2dMotionStd() { return RansacParams(6, 0.5f, 0.5f, 0.99f); }
rows_.push_back(row);
cols_.push_back(col);
elems_.push_back(coef);
}
}; };
class CV_EXPORTS ImageMotionEstimatorBase CV_EXPORTS Mat estimateGlobalMotionRobust(
{ const std::vector<Point2f> &points0, const std::vector<Point2f> &points1,
public: int model = AFFINE, const RansacParams &params = RansacParams::affine2dMotionStd(),
virtual ~ImageMotionEstimatorBase() {} float *rmse = 0, int *ninliers = 0);
virtual void setMotionModel(MotionModel val) { motionModel_ = val; }
virtual MotionModel motionModel() const { return motionModel_; }
virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) = 0;
protected:
ImageMotionEstimatorBase(MotionModel model) { setMotionModel(model); }
private:
MotionModel motionModel_;
};
class CV_EXPORTS FromFileMotionReader : public ImageMotionEstimatorBase class CV_EXPORTS IGlobalMotionEstimator
{ {
public: public:
FromFileMotionReader(const std::string &path); virtual ~IGlobalMotionEstimator() {}
virtual Mat estimate(const Mat &frame0, const Mat &frame1) = 0;
virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0);
private:
std::ifstream file_;
}; };
class CV_EXPORTS ToFileMotionWriter : public ImageMotionEstimatorBase class CV_EXPORTS PyrLkRobustMotionEstimator : public IGlobalMotionEstimator
{ {
public: public:
ToFileMotionWriter(const std::string &path, Ptr<ImageMotionEstimatorBase> estimator); PyrLkRobustMotionEstimator();
virtual void setMotionModel(MotionModel val) { motionEstimator_->setMotionModel(val); } void setDetector(Ptr<FeatureDetector> val) { detector_ = val; }
virtual MotionModel motionModel() const { return motionEstimator_->motionModel(); } Ptr<FeatureDetector> detector() const { return detector_; }
virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0);
private:
std::ofstream file_;
Ptr<ImageMotionEstimatorBase> motionEstimator_;
};
class CV_EXPORTS KeypointBasedMotionEstimator : public ImageMotionEstimatorBase void setOptFlowEstimator(Ptr<ISparseOptFlowEstimator> val) { optFlowEstimator_ = val; }
{ Ptr<ISparseOptFlowEstimator> optFlowEstimator() const { return optFlowEstimator_; }
public:
KeypointBasedMotionEstimator(Ptr<MotionEstimatorBase> estimator);
virtual void setMotionModel(MotionModel val) { motionEstimator_->setMotionModel(val); } void setMotionModel(MotionModel val) { motionModel_ = val; }
virtual MotionModel motionModel() const { return motionEstimator_->motionModel(); } MotionModel motionModel() const { return motionModel_; }
void setDetector(Ptr<FeatureDetector> val) { detector_ = val; } void setRansacParams(const RansacParams &val) { ransacParams_ = val; }
Ptr<FeatureDetector> detector() const { return detector_; } RansacParams ransacParams() const { return ransacParams_; }
void setOpticalFlowEstimator(Ptr<ISparseOptFlowEstimator> val) { optFlowEstimator_ = val; } void setMaxRmse(float val) { maxRmse_ = val; }
Ptr<ISparseOptFlowEstimator> opticalFlowEstimator() const { return optFlowEstimator_; } float maxRmse() const { return maxRmse_; }
void setOutlierRejector(Ptr<IOutlierRejector> val) { outlierRejector_ = val; } void setMinInlierRatio(float val) { minInlierRatio_ = val; }
Ptr<IOutlierRejector> outlierRejector() const { return outlierRejector_; } float minInlierRatio() const { return minInlierRatio_; }
virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0); virtual Mat estimate(const Mat &frame0, const Mat &frame1);
private: private:
Ptr<MotionEstimatorBase> motionEstimator_;
Ptr<FeatureDetector> detector_; Ptr<FeatureDetector> detector_;
Ptr<ISparseOptFlowEstimator> optFlowEstimator_; Ptr<ISparseOptFlowEstimator> optFlowEstimator_;
Ptr<IOutlierRejector> outlierRejector_; MotionModel motionModel_;
RansacParams ransacParams_;
std::vector<uchar> status_; std::vector<uchar> status_;
std::vector<KeyPoint> keypointsPrev_; std::vector<KeyPoint> keypointsPrev_;
std::vector<Point2f> pointsPrev_, points_; std::vector<Point2f> pointsPrev_, points_;
std::vector<Point2f> pointsPrevGood_, pointsGood_; std::vector<Point2f> pointsPrevGood_, pointsGood_;
float maxRmse_;
float minInlierRatio_;
}; };
#ifdef HAVE_OPENCV_GPU CV_EXPORTS Mat getMotion(int from, int to, const Mat *motions, int size);
class CV_EXPORTS KeypointBasedMotionEstimatorGpu : public ImageMotionEstimatorBase
{
public:
KeypointBasedMotionEstimatorGpu(Ptr<MotionEstimatorBase> estimator);
virtual void setMotionModel(MotionModel val) { motionEstimator_->setMotionModel(val); }
virtual MotionModel motionModel() const { return motionEstimator_->motionModel(); }
void setOutlierRejector(Ptr<IOutlierRejector> val) { outlierRejector_ = val; }
Ptr<IOutlierRejector> outlierRejector() const { return outlierRejector_; }
virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0);
Mat estimate(const gpu::GpuMat &frame0, const gpu::GpuMat &frame1, bool *ok = 0);
private:
Ptr<MotionEstimatorBase> motionEstimator_;
gpu::GoodFeaturesToTrackDetector_GPU detector_;
SparsePyrLkOptFlowEstimatorGpu optFlowEstimator_;
Ptr<IOutlierRejector> outlierRejector_;
gpu::GpuMat frame0_, grayFrame0_, frame1_;
gpu::GpuMat pointsPrev_, points_;
gpu::GpuMat status_;
Mat hostPointsPrev_, hostPoints_;
std::vector<Point2f> hostPointsPrevTmp_, hostPointsTmp_;
std::vector<uchar> rejectionStatus_;
};
#endif
CV_EXPORTS Mat getMotion(int from, int to, const std::vector<Mat> &motions); CV_EXPORTS Mat getMotion(int from, int to, const std::vector<Mat> &motions);
......
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include "opencv2/core/core.hpp" #include "opencv2/core/core.hpp"
#include "opencv2/videostab/optical_flow.hpp" #include "opencv2/videostab/optical_flow.hpp"
#include "opencv2/videostab/fast_marching.hpp" #include "opencv2/videostab/fast_marching.hpp"
#include "opencv2/videostab/global_motion.hpp"
#include "opencv2/photo/photo.hpp" #include "opencv2/photo/photo.hpp"
namespace cv namespace cv
...@@ -59,7 +58,7 @@ class CV_EXPORTS InpainterBase ...@@ -59,7 +58,7 @@ class CV_EXPORTS InpainterBase
{ {
public: public:
InpainterBase() InpainterBase()
: radius_(0), motionModel_(MM_UNKNOWN), frames_(0), motions_(0), : radius_(0), frames_(0), motions_(0),
stabilizedFrames_(0), stabilizationMotions_(0) {} stabilizedFrames_(0), stabilizationMotions_(0) {}
virtual ~InpainterBase() {} virtual ~InpainterBase() {}
...@@ -67,14 +66,6 @@ public: ...@@ -67,14 +66,6 @@ public:
virtual void setRadius(int val) { radius_ = val; } virtual void setRadius(int val) { radius_ = val; }
virtual int radius() const { return radius_; } virtual int radius() const { return radius_; }
virtual void setMotionModel(MotionModel val) { motionModel_ = val; }
virtual MotionModel motionModel() const { return motionModel_; }
virtual void inpaint(int idx, Mat &frame, Mat &mask) = 0;
// data from stabilizer
virtual void setFrames(const std::vector<Mat> &val) { frames_ = &val; } virtual void setFrames(const std::vector<Mat> &val) { frames_ = &val; }
virtual const std::vector<Mat>& frames() const { return *frames_; } virtual const std::vector<Mat>& frames() const { return *frames_; }
...@@ -87,9 +78,12 @@ public: ...@@ -87,9 +78,12 @@ public:
virtual void setStabilizationMotions(const std::vector<Mat> &val) { stabilizationMotions_ = &val; } virtual void setStabilizationMotions(const std::vector<Mat> &val) { stabilizationMotions_ = &val; }
virtual const std::vector<Mat>& stabilizationMotions() const { return *stabilizationMotions_; } virtual const std::vector<Mat>& stabilizationMotions() const { return *stabilizationMotions_; }
virtual void update() {}
virtual void inpaint(int idx, Mat &frame, Mat &mask) = 0;
protected: protected:
int radius_; int radius_;
MotionModel motionModel_;
const std::vector<Mat> *frames_; const std::vector<Mat> *frames_;
const std::vector<Mat> *motions_; const std::vector<Mat> *motions_;
const std::vector<Mat> *stabilizedFrames_; const std::vector<Mat> *stabilizedFrames_;
...@@ -109,12 +103,13 @@ public: ...@@ -109,12 +103,13 @@ public:
bool empty() const { return inpainters_.empty(); } bool empty() const { return inpainters_.empty(); }
virtual void setRadius(int val); virtual void setRadius(int val);
virtual void setMotionModel(MotionModel val);
virtual void setFrames(const std::vector<Mat> &val); virtual void setFrames(const std::vector<Mat> &val);
virtual void setMotions(const std::vector<Mat> &val); virtual void setMotions(const std::vector<Mat> &val);
virtual void setStabilizedFrames(const std::vector<Mat> &val); virtual void setStabilizedFrames(const std::vector<Mat> &val);
virtual void setStabilizationMotions(const std::vector<Mat> &val); virtual void setStabilizationMotions(const std::vector<Mat> &val);
virtual void update();
virtual void inpaint(int idx, Mat &frame, Mat &mask); virtual void inpaint(int idx, Mat &frame, Mat &mask);
private: private:
...@@ -180,7 +175,8 @@ private: ...@@ -180,7 +175,8 @@ private:
class CV_EXPORTS ColorInpainter : public InpainterBase class CV_EXPORTS ColorInpainter : public InpainterBase
{ {
public: public:
ColorInpainter(int method = INPAINT_TELEA, double radius = 2.); ColorInpainter(int method = INPAINT_TELEA, double _radius = 2.)
: method_(method), radius_(_radius) {}
virtual void inpaint(int idx, Mat &frame, Mat &mask); virtual void inpaint(int idx, Mat &frame, Mat &mask);
...@@ -190,9 +186,6 @@ private: ...@@ -190,9 +186,6 @@ private:
Mat invMask_; Mat invMask_;
}; };
inline ColorInpainter::ColorInpainter(int _method, double _radius)
: method_(_method), radius_(_radius) {}
CV_EXPORTS void calcFlowMask( CV_EXPORTS void calcFlowMask(
const Mat &flowX, const Mat &flowY, const Mat &errors, float maxError, const Mat &flowX, const Mat &flowY, const Mat &errors, float maxError,
const Mat &mask0, const Mat &mask1, Mat &flowMask); const Mat &mask0, const Mat &mask1, Mat &flowMask);
......
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#ifndef __OPENCV_VIDEOSTAB_MOTION_CORE_HPP__
#define __OPENCV_VIDEOSTAB_MOTION_CORE_HPP__
#include <cmath>
#include "opencv2/core/core.hpp"
namespace cv
{
namespace videostab
{
enum MotionModel
{
MM_TRANSLATION = 0,
MM_TRANSLATION_AND_SCALE = 1,
MM_ROTATION = 2,
MM_RIGID = 3,
MM_SIMILARITY = 4,
MM_AFFINE = 5,
MM_HOMOGRAPHY = 6,
MM_UNKNOWN = 7
};
struct CV_EXPORTS RansacParams
{
int size; // subset size
float thresh; // max error to classify as inlier
float eps; // max outliers ratio
float prob; // probability of success
RansacParams() : size(0), thresh(0), eps(0), prob(0) {}
RansacParams(int size, float thresh, float eps, float prob);
int niters() const
{
return static_cast<int>(
std::ceil(std::log(1 - prob) / std::log(1 - std::pow(1 - eps, size))));
}
static RansacParams default2dMotion(MotionModel model)
{
CV_Assert(model < MM_UNKNOWN);
if (model == MM_TRANSLATION)
return RansacParams(1, 0.5f, 0.5f, 0.99f);
if (model == MM_TRANSLATION_AND_SCALE)
return RansacParams(2, 0.5f, 0.5f, 0.99f);
if (model == MM_ROTATION)
return RansacParams(1, 0.5f, 0.5f, 0.99f);
if (model == MM_RIGID)
return RansacParams(2, 0.5f, 0.5f, 0.99f);
if (model == MM_SIMILARITY)
return RansacParams(2, 0.5f, 0.5f, 0.99f);
if (model == MM_AFFINE)
return RansacParams(3, 0.5f, 0.5f, 0.99f);
return RansacParams(4, 0.5f, 0.5f, 0.99f);
}
};
inline RansacParams::RansacParams(int _size, float _thresh, float _eps, float _prob)
: size(_size), thresh(_thresh), eps(_eps), prob(_prob) {}
} // namespace videostab
} // namespace cv
#endif
...@@ -44,9 +44,7 @@ ...@@ -44,9 +44,7 @@
#define __OPENCV_VIDEOSTAB_MOTION_STABILIZING_HPP__ #define __OPENCV_VIDEOSTAB_MOTION_STABILIZING_HPP__
#include <vector> #include <vector>
#include <utility>
#include "opencv2/core/core.hpp" #include "opencv2/core/core.hpp"
#include "opencv2/videostab/global_motion.hpp"
namespace cv namespace cv
{ {
...@@ -56,109 +54,46 @@ namespace videostab ...@@ -56,109 +54,46 @@ namespace videostab
class CV_EXPORTS IMotionStabilizer class CV_EXPORTS IMotionStabilizer
{ {
public: public:
virtual void stabilize(const Mat *motions, int size, Mat *stabilizationMotions) const = 0;
#ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY #ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY
virtual ~IMotionStabilizer() {} virtual ~IMotionStabilizer() {}
#endif #endif
// assumes that [0, size-1) is in or equals to [range.first, range.second)
virtual void stabilize(
int size, const std::vector<Mat> &motions, std::pair<int,int> range,
Mat *stabilizationMotions) = 0;
};
class CV_EXPORTS MotionStabilizationPipeline : public IMotionStabilizer
{
public:
void pushBack(Ptr<IMotionStabilizer> stabilizer) { stabilizers_.push_back(stabilizer); }
bool empty() const { return stabilizers_.empty(); }
virtual void stabilize(
int size, const std::vector<Mat> &motions, std::pair<int,int> range,
Mat *stabilizationMotions);
private:
std::vector<Ptr<IMotionStabilizer> > stabilizers_;
}; };
class CV_EXPORTS MotionFilterBase : public IMotionStabilizer class CV_EXPORTS MotionFilterBase : public IMotionStabilizer
{ {
public: public:
MotionFilterBase() : radius_(0) {}
virtual ~MotionFilterBase() {} virtual ~MotionFilterBase() {}
virtual Mat stabilize( virtual void setRadius(int val) { radius_ = val; }
int idx, const std::vector<Mat> &motions, std::pair<int,int> range) = 0; virtual int radius() const { return radius_; }
virtual void stabilize( virtual void update() {}
int size, const std::vector<Mat> &motions, std::pair<int,int> range,
Mat *stabilizationMotions);
};
class CV_EXPORTS GaussianMotionFilter : public MotionFilterBase virtual Mat stabilize(int index, const Mat *motions, int size) const = 0;
{ virtual void stabilize(const Mat *motions, int size, Mat *stabilizationMotions) const;
public:
GaussianMotionFilter(int radius = 15, float stdev = -1.f);
void setParams(int radius, float stdev = -1.f);
int radius() const { return radius_; }
float stdev() const { return stdev_; }
virtual Mat stabilize( protected:
int idx, const std::vector<Mat> &motions, std::pair<int,int> range);
private:
int radius_; int radius_;
float stdev_;
std::vector<float> weight_;
}; };
inline GaussianMotionFilter::GaussianMotionFilter(int _radius, float _stdev) { setParams(_radius, _stdev); } class CV_EXPORTS GaussianMotionFilter : public MotionFilterBase
class CV_EXPORTS LpMotionStabilizer : public IMotionStabilizer
{ {
public: public:
LpMotionStabilizer(MotionModel model = MM_SIMILARITY); GaussianMotionFilter() : stdev_(-1.f) {}
void setMotionModel(MotionModel val) { model_ = val; }
MotionModel motionModel() const { return model_; }
void setFrameSize(Size val) { frameSize_ = val; } void setStdev(float val) { stdev_ = val; }
Size frameSize() const { return frameSize_; } float stdev() const { return stdev_; }
void setTrimRatio(float val) { trimRatio_ = val; }
float trimRatio() const { return trimRatio_; }
void setWeight1(float val) { w1_ = val; }
float weight1() const { return w1_; }
void setWeight2(float val) { w2_ = val; }
float weight2() const { return w2_; }
void setWeight3(float val) { w3_ = val; }
float weight3() const { return w3_; }
void setWeight4(float val) { w4_ = val; } virtual void update();
float weight4() const { return w4_; }
virtual void stabilize( virtual Mat stabilize(int index, const Mat *motions, int size) const;
int size, const std::vector<Mat> &motions, std::pair<int,int> range,
Mat *stabilizationMotions);
private: private:
MotionModel model_; float stdev_;
Size frameSize_; std::vector<float> weight_;
float trimRatio_;
float w1_, w2_, w3_, w4_;
std::vector<double> obj_, collb_, colub_;
std::vector<int> rows_, cols_;
std::vector<double> elems_, rowlb_, rowub_;
void set(int row, int col, double coef)
{
rows_.push_back(row);
cols_.push_back(col);
elems_.push_back(coef);
}
}; };
CV_EXPORTS Mat ensureInclusionConstraint(const Mat &M, Size size, float trimRatio); CV_EXPORTS Mat ensureInclusionConstraint(const Mat &M, Size size, float trimRatio);
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
#include "opencv2/opencv_modules.hpp" #include "opencv2/opencv_modules.hpp"
#ifdef HAVE_OPENCV_GPU #ifdef HAVE_OPENCV_GPU
#include "opencv2/gpu/gpu.hpp" # include "opencv2/gpu/gpu.hpp"
#endif #endif
namespace cv namespace cv
...@@ -78,12 +78,11 @@ class CV_EXPORTS PyrLkOptFlowEstimatorBase ...@@ -78,12 +78,11 @@ class CV_EXPORTS PyrLkOptFlowEstimatorBase
public: public:
PyrLkOptFlowEstimatorBase() { setWinSize(Size(21, 21)); setMaxLevel(3); } PyrLkOptFlowEstimatorBase() { setWinSize(Size(21, 21)); setMaxLevel(3); }
virtual void setWinSize(Size val) { winSize_ = val; } void setWinSize(Size val) { winSize_ = val; }
virtual Size winSize() const { return winSize_; } Size winSize() const { return winSize_; }
virtual void setMaxLevel(int val) { maxLevel_ = val; } void setMaxLevel(int val) { maxLevel_ = val; }
virtual int maxLevel() const { return maxLevel_; } int maxLevel() const { return maxLevel_; }
virtual ~PyrLkOptFlowEstimatorBase() {}
protected: protected:
Size winSize_; Size winSize_;
...@@ -100,27 +99,6 @@ public: ...@@ -100,27 +99,6 @@ public:
}; };
#ifdef HAVE_OPENCV_GPU #ifdef HAVE_OPENCV_GPU
class CV_EXPORTS SparsePyrLkOptFlowEstimatorGpu
: public PyrLkOptFlowEstimatorBase, public ISparseOptFlowEstimator
{
public:
SparsePyrLkOptFlowEstimatorGpu();
virtual void run(
InputArray frame0, InputArray frame1, InputArray points0, InputOutputArray points1,
OutputArray status, OutputArray errors);
void run(const gpu::GpuMat &frame0, const gpu::GpuMat &frame1, const gpu::GpuMat &points0, gpu::GpuMat &points1,
gpu::GpuMat &status, gpu::GpuMat &errors);
void run(const gpu::GpuMat &frame0, const gpu::GpuMat &frame1, const gpu::GpuMat &points0, gpu::GpuMat &points1,
gpu::GpuMat &status);
private:
gpu::PyrLKOpticalFlow optFlowEstimator_;
gpu::GpuMat frame0_, frame1_, points0_, points1_, status_, errors_;
};
class CV_EXPORTS DensePyrLkOptFlowEstimatorGpu class CV_EXPORTS DensePyrLkOptFlowEstimatorGpu
: public PyrLkOptFlowEstimatorBase, public IDenseOptFlowEstimator : public PyrLkOptFlowEstimatorBase, public IDenseOptFlowEstimator
{ {
...@@ -130,7 +108,6 @@ public: ...@@ -130,7 +108,6 @@ public:
virtual void run( virtual void run(
InputArray frame0, InputArray frame1, InputOutputArray flowX, InputOutputArray flowY, InputArray frame0, InputArray frame1, InputOutputArray flowX, InputOutputArray flowY,
OutputArray errors); OutputArray errors);
private: private:
gpu::PyrLKOpticalFlow optFlowEstimator_; gpu::PyrLKOpticalFlow optFlowEstimator_;
gpu::GpuMat frame0_, frame1_, flowX_, flowY_, errors_; gpu::GpuMat frame0_, frame1_, flowX_, flowY_, errors_;
......
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#ifndef __OPENCV_VIDEOSTAB_OUTLIER_REJECTION_HPP__
#define __OPENCV_VIDEOSTAB_OUTLIER_REJECTION_HPP__
#include <vector>
#include "opencv2/core/core.hpp"
#include "opencv2/videostab/motion_core.hpp"
namespace cv
{
namespace videostab
{
class CV_EXPORTS IOutlierRejector
{
public:
virtual ~IOutlierRejector() {}
virtual void process(
Size frameSize, InputArray points0, InputArray points1, OutputArray mask) = 0;
};
class CV_EXPORTS NullOutlierRejector : public IOutlierRejector
{
public:
virtual void process(
Size frameSize, InputArray points0, InputArray points1, OutputArray mask);
};
class CV_EXPORTS TranslationBasedLocalOutlierRejector : public IOutlierRejector
{
public:
TranslationBasedLocalOutlierRejector();
void setCellSize(Size val) { cellSize_ = val; }
Size cellSize() const { return cellSize_; }
void setRansacParams(RansacParams val) { ransacParams_ = val; }
RansacParams ransacParams() const { return ransacParams_; }
virtual void process(
Size frameSize, InputArray points0, InputArray points1, OutputArray mask);
private:
Size cellSize_;
RansacParams ransacParams_;
typedef std::vector<int> Cell;
std::vector<Cell> grid_;
};
} // namespace videostab
} // namespace cv
#endif
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#ifndef __OPENCV_VIDEOSTAB_RING_BUFFER_HPP__
#define __OPENCV_VIDEOSTAB_RING_BUFFER_HPP__
#include <vector>
#include "opencv2/imgproc/imgproc.hpp"
namespace cv
{
namespace videostab
{
template <typename T> inline T& at(int idx, std::vector<T> &items)
{
return items[cv::borderInterpolate(idx, static_cast<int>(items.size()), cv::BORDER_WRAP)];
}
template <typename T> inline const T& at(int idx, const std::vector<T> &items)
{
return items[cv::borderInterpolate(idx, static_cast<int>(items.size()), cv::BORDER_WRAP)];
}
} // namespace videostab
} // namespace cv
#endif
...@@ -44,7 +44,6 @@ ...@@ -44,7 +44,6 @@
#define __OPENCV_VIDEOSTAB_STABILIZER_HPP__ #define __OPENCV_VIDEOSTAB_STABILIZER_HPP__
#include <vector> #include <vector>
#include <ctime>
#include "opencv2/core/core.hpp" #include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/videostab/global_motion.hpp" #include "opencv2/videostab/global_motion.hpp"
...@@ -53,7 +52,6 @@ ...@@ -53,7 +52,6 @@
#include "opencv2/videostab/log.hpp" #include "opencv2/videostab/log.hpp"
#include "opencv2/videostab/inpainting.hpp" #include "opencv2/videostab/inpainting.hpp"
#include "opencv2/videostab/deblurring.hpp" #include "opencv2/videostab/deblurring.hpp"
#include "opencv2/videostab/wobble_suppression.hpp"
namespace cv namespace cv
{ {
...@@ -65,7 +63,7 @@ class CV_EXPORTS StabilizerBase ...@@ -65,7 +63,7 @@ class CV_EXPORTS StabilizerBase
public: public:
virtual ~StabilizerBase() {} virtual ~StabilizerBase() {}
void setLog(Ptr<ILog> ilog) { log_ = ilog; } void setLog(Ptr<ILog> _log) { log_ = _log; }
Ptr<ILog> log() const { return log_; } Ptr<ILog> log() const { return log_; }
void setRadius(int val) { radius_ = val; } void setRadius(int val) { radius_ = val; }
...@@ -74,8 +72,8 @@ public: ...@@ -74,8 +72,8 @@ public:
void setFrameSource(Ptr<IFrameSource> val) { frameSource_ = val; } void setFrameSource(Ptr<IFrameSource> val) { frameSource_ = val; }
Ptr<IFrameSource> frameSource() const { return frameSource_; } Ptr<IFrameSource> frameSource() const { return frameSource_; }
void setMotionEstimator(Ptr<ImageMotionEstimatorBase> val) { motionEstimator_ = val; } void setMotionEstimator(Ptr<IGlobalMotionEstimator> val) { motionEstimator_ = val; }
Ptr<ImageMotionEstimatorBase> motionEstimator() const { return motionEstimator_; } Ptr<IGlobalMotionEstimator> motionEstimator() const { return motionEstimator_; }
void setDeblurer(Ptr<DeblurerBase> val) { deblurer_ = val; } void setDeblurer(Ptr<DeblurerBase> val) { deblurer_ = val; }
Ptr<DeblurerBase> deblurrer() const { return deblurer_; } Ptr<DeblurerBase> deblurrer() const { return deblurer_; }
...@@ -95,19 +93,18 @@ public: ...@@ -95,19 +93,18 @@ public:
protected: protected:
StabilizerBase(); StabilizerBase();
void reset(); void setUp(int cacheSize, const Mat &frame);
Mat nextStabilizedFrame(); Mat nextStabilizedFrame();
bool doOneIteration(); bool doOneIteration();
virtual void setUp(const Mat &firstFrame); void stabilizeFrame(const Mat &stabilizationMotion);
virtual Mat estimateMotion() = 0;
virtual Mat estimateStabilizationMotion() = 0; virtual void setUp(Mat &firstFrame) = 0;
void stabilizeFrame(); virtual void stabilizeFrame() = 0;
virtual Mat postProcessFrame(const Mat &frame); virtual void estimateMotion() = 0;
void logProcessingTime();
Ptr<ILog> log_; Ptr<ILog> log_;
Ptr<IFrameSource> frameSource_; Ptr<IFrameSource> frameSource_;
Ptr<ImageMotionEstimatorBase> motionEstimator_; Ptr<IGlobalMotionEstimator> motionEstimator_;
Ptr<DeblurerBase> deblurer_; Ptr<DeblurerBase> deblurer_;
Ptr<InpainterBase> inpainter_; Ptr<InpainterBase> inpainter_;
int radius_; int radius_;
...@@ -123,14 +120,12 @@ protected: ...@@ -123,14 +120,12 @@ protected:
Mat preProcessedFrame_; Mat preProcessedFrame_;
bool doInpainting_; bool doInpainting_;
Mat inpaintingMask_; Mat inpaintingMask_;
Mat finalFrame_;
std::vector<Mat> frames_; std::vector<Mat> frames_;
std::vector<Mat> motions_; // motions_[i] is the motion from i-th to i+1-th frame std::vector<Mat> motions_; // motions_[i] is the motion from i-th to i+1-th frame
std::vector<float> blurrinessRates_; std::vector<float> blurrinessRates_;
std::vector<Mat> stabilizedFrames_; std::vector<Mat> stabilizedFrames_;
std::vector<Mat> stabilizedMasks_; std::vector<Mat> stabilizedMasks_;
std::vector<Mat> stabilizationMotions_; std::vector<Mat> stabilizationMotions_;
clock_t processingStartTime_;
}; };
class CV_EXPORTS OnePassStabilizer : public StabilizerBase, public IFrameSource class CV_EXPORTS OnePassStabilizer : public StabilizerBase, public IFrameSource
...@@ -141,14 +136,15 @@ public: ...@@ -141,14 +136,15 @@ public:
void setMotionFilter(Ptr<MotionFilterBase> val) { motionFilter_ = val; } void setMotionFilter(Ptr<MotionFilterBase> val) { motionFilter_ = val; }
Ptr<MotionFilterBase> motionFilter() const { return motionFilter_; } Ptr<MotionFilterBase> motionFilter() const { return motionFilter_; }
virtual void reset(); virtual void reset() { resetImpl(); }
virtual Mat nextFrame() { return nextStabilizedFrame(); } virtual Mat nextFrame() { return nextStabilizedFrame(); }
private: private:
virtual void setUp(const Mat &firstFrame); void resetImpl();
virtual Mat estimateMotion();
virtual Mat estimateStabilizationMotion(); virtual void setUp(Mat &firstFrame);
virtual Mat postProcessFrame(const Mat &frame); virtual void estimateMotion();
virtual void stabilizeFrame();
Ptr<MotionFilterBase> motionFilter_; Ptr<MotionFilterBase> motionFilter_;
}; };
...@@ -159,34 +155,30 @@ public: ...@@ -159,34 +155,30 @@ public:
TwoPassStabilizer(); TwoPassStabilizer();
void setMotionStabilizer(Ptr<IMotionStabilizer> val) { motionStabilizer_ = val; } void setMotionStabilizer(Ptr<IMotionStabilizer> val) { motionStabilizer_ = val; }
Ptr<IMotionStabilizer> motionStabilizer() const { return motionStabilizer_; } Ptr<IMotionStabilizer> motionStabilizer() const { return motionStabilizer_; }
void setWobbleSuppressor(Ptr<WobbleSuppressorBase> val) { wobbleSuppressor_ = val; }
Ptr<WobbleSuppressorBase> wobbleSuppressor() const { return wobbleSuppressor_; }
void setEstimateTrimRatio(bool val) { mustEstTrimRatio_ = val; } void setEstimateTrimRatio(bool val) { mustEstTrimRatio_ = val; }
bool mustEstimateTrimaRatio() const { return mustEstTrimRatio_; } bool mustEstimateTrimaRatio() const { return mustEstTrimRatio_; }
virtual void reset(); virtual void reset() { resetImpl(); }
virtual Mat nextFrame(); virtual Mat nextFrame();
// available after pre-pass, before it's empty
std::vector<Mat> motions() const;
private: private:
void resetImpl();
void runPrePassIfNecessary(); void runPrePassIfNecessary();
virtual void setUp(const Mat &firstFrame); virtual void setUp(Mat &firstFrame);
virtual Mat estimateMotion(); virtual void estimateMotion() { /* do nothing as motion was estimation in pre-pass */ }
virtual Mat estimateStabilizationMotion(); virtual void stabilizeFrame();
virtual Mat postProcessFrame(const Mat &frame);
Ptr<IMotionStabilizer> motionStabilizer_; Ptr<IMotionStabilizer> motionStabilizer_;
Ptr<WobbleSuppressorBase> wobbleSuppressor_;
bool mustEstTrimRatio_; bool mustEstTrimRatio_;
int frameCount_; int frameCount_;
bool isPrePassDone_; bool isPrePassDone_;
bool doWobbleSuppression_;
std::vector<Mat> motions2_;
Mat suppressedFrame_;
}; };
} // namespace videostab } // namespace videostab
......
...@@ -40,16 +40,9 @@ ...@@ -40,16 +40,9 @@
// //
//M*/ //M*/
// REFERENCES
// 1. "Full-Frame Video Stabilization with Motion Inpainting"
// Yasuyuki Matsushita, Eyal Ofek, Weina Ge, Xiaoou Tang, Senior Member, and Heung-Yeung Shum
// 2. "Auto-Directed Video Stabilization with Robust L1 Optimal Camera Paths"
// Matthias Grundmann, Vivek Kwatra, Irfan Essa
#ifndef __OPENCV_VIDEOSTAB_HPP__ #ifndef __OPENCV_VIDEOSTAB_HPP__
#define __OPENCV_VIDEOSTAB_HPP__ #define __OPENCV_VIDEOSTAB_HPP__
#include "opencv2/videostab/stabilizer.hpp" #include "opencv2/videostab/stabilizer.hpp"
#include "opencv2/videostab/ring_buffer.hpp"
#endif #endif
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#ifndef __OPENCV_VIDEOSTAB_WOBBLE_SUPPRESSION_HPP__
#define __OPENCV_VIDEOSTAB_WOBBLE_SUPPRESSION_HPP__
#include <vector>
#include "opencv2/core/core.hpp"
#include "opencv2/videostab/global_motion.hpp"
#include "opencv2/videostab/log.hpp"
#ifdef HAVE_OPENCV_GPU
#include "opencv2/gpu/gpu.hpp"
#endif
namespace cv
{
namespace videostab
{
class CV_EXPORTS WobbleSuppressorBase
{
public:
WobbleSuppressorBase();
virtual ~WobbleSuppressorBase() {}
void setMotionEstimator(Ptr<ImageMotionEstimatorBase> val) { motionEstimator_ = val; }
Ptr<ImageMotionEstimatorBase> motionEstimator() const { return motionEstimator_; }
virtual void suppress(int idx, const Mat &frame, Mat &result) = 0;
// data from stabilizer
virtual void setFrameCount(int val) { frameCount_ = val; }
virtual int frameCount() const { return frameCount_; }
virtual void setMotions(const std::vector<Mat> &val) { motions_ = &val; }
virtual const std::vector<Mat>& motions() const { return *motions_; }
virtual void setMotions2(const std::vector<Mat> &val) { motions2_ = &val; }
virtual const std::vector<Mat>& motions2() const { return *motions2_; }
virtual void setStabilizationMotions(const std::vector<Mat> &val) { stabilizationMotions_ = &val; }
virtual const std::vector<Mat>& stabilizationMotions() const { return *stabilizationMotions_; }
protected:
Ptr<ImageMotionEstimatorBase> motionEstimator_;
int frameCount_;
const std::vector<Mat> *motions_;
const std::vector<Mat> *motions2_;
const std::vector<Mat> *stabilizationMotions_;
};
class CV_EXPORTS NullWobbleSuppressor : public WobbleSuppressorBase
{
public:
virtual void suppress(int idx, const Mat &frame, Mat &result);
};
class CV_EXPORTS MoreAccurateMotionWobbleSuppressorBase : public WobbleSuppressorBase
{
public:
virtual void setPeriod(int val) { period_ = val; }
virtual int period() const { return period_; }
protected:
MoreAccurateMotionWobbleSuppressorBase() { setPeriod(30); }
int period_;
};
class CV_EXPORTS MoreAccurateMotionWobbleSuppressor : public MoreAccurateMotionWobbleSuppressorBase
{
public:
virtual void suppress(int idx, const Mat &frame, Mat &result);
private:
Mat_<float> mapx_, mapy_;
};
#ifdef HAVE_OPENCV_GPU
class CV_EXPORTS MoreAccurateMotionWobbleSuppressorGpu : public MoreAccurateMotionWobbleSuppressorBase
{
public:
void suppress(int idx, const gpu::GpuMat &frame, gpu::GpuMat &result);
virtual void suppress(int idx, const Mat &frame, Mat &result);
private:
gpu::GpuMat frameDevice_, resultDevice_;
gpu::GpuMat mapx_, mapy_;
};
#endif
} // namespace videostab
} // namespace cv
#endif
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#ifndef __OPENCV_VIDEOSTAB_CLP_HPP__
#define __OPENCV_VIDEOSTAB_CLP_HPP__
#ifdef HAVE_CLP
# undef PACKAGE
# undef PACKAGE_BUGREPORT
# undef PACKAGE_NAME
# undef PACKAGE_STRING
# undef PACKAGE_TARNAME
# undef PACKAGE_VERSION
# undef VERSION
# define COIN_BIG_INDEX 0
# define DEBUG_COIN 0
# define PRESOLVE_DEBUG 0
# define PRESOLVE_CONSISTENCY 0
# include "ClpSimplex.hpp"
# include "ClpPresolve.hpp"
# include "ClpPrimalColumnSteepest.hpp"
# include "ClpDualRowSteepest.hpp"
# define INF 1e10
#endif
// Clp replaces min and max with ?: globally, we can't use std::min and std::max in case
// when HAVE_CLP is true. We create the defines by ourselves when HAVE_CLP == 0.
#ifndef min
#define min(a,b) std::min(a,b)
#endif
#ifndef max
#define max(a,b) std::max(a,b)
#endif
#endif
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
#include "precomp.hpp" #include "precomp.hpp"
#include "opencv2/videostab/deblurring.hpp" #include "opencv2/videostab/deblurring.hpp"
#include "opencv2/videostab/global_motion.hpp" #include "opencv2/videostab/global_motion.hpp"
#include "opencv2/videostab/ring_buffer.hpp"
using namespace std; using namespace std;
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "precomp.hpp" #include "precomp.hpp"
#include "opencv2/videostab/fast_marching.hpp" #include "opencv2/videostab/fast_marching.hpp"
#include "opencv2/videostab/ring_buffer.hpp"
using namespace std; using namespace std;
......
...@@ -42,12 +42,6 @@ ...@@ -42,12 +42,6 @@
#include "precomp.hpp" #include "precomp.hpp"
#include "opencv2/videostab/frame_source.hpp" #include "opencv2/videostab/frame_source.hpp"
#include "opencv2/videostab/ring_buffer.hpp"
#include "opencv2/opencv_modules.hpp"
#ifdef HAVE_OPENCV_HIGHGUI
# include "opencv2/highgui/highgui.hpp"
#endif
using namespace std; using namespace std;
...@@ -56,67 +50,25 @@ namespace cv ...@@ -56,67 +50,25 @@ namespace cv
namespace videostab namespace videostab
{ {
namespace { VideoFileSource::VideoFileSource(const string &path, bool volatileFrame)
: path_(path), volatileFrame_(volatileFrame) { reset(); }
class VideoFileSourceImpl : public IFrameSource
{
public:
VideoFileSourceImpl(const std::string &path, bool volatileFrame)
: path_(path), volatileFrame_(volatileFrame) { reset(); }
virtual void reset()
{
#ifdef HAVE_OPENCV_HIGHGUI
vc.release();
vc.open(path_);
if (!vc.isOpened())
throw runtime_error("can't open file: " + path_);
#else
CV_Error(CV_StsNotImplemented, "OpenCV has been compiled without video I/O support");
#endif
}
virtual Mat nextFrame()
{
Mat frame;
#ifdef HAVE_OPENCV_HIGHGUI
vc >> frame;
#endif
return volatileFrame_ ? frame : frame.clone();
}
#ifdef HAVE_OPENCV_HIGHGUI
int width() {return static_cast<int>(vc.get(CV_CAP_PROP_FRAME_WIDTH));}
int height() {return static_cast<int>(vc.get(CV_CAP_PROP_FRAME_HEIGHT));}
int count() {return static_cast<int>(vc.get(CV_CAP_PROP_FRAME_COUNT));}
double fps() {return vc.get(CV_CAP_PROP_FPS);}
#else
int width() {return 0;}
int height() {return 0;}
int count() {return 0;}
double fps() {return 0;}
#endif
private:
std::string path_;
bool volatileFrame_;
#ifdef HAVE_OPENCV_HIGHGUI
VideoCapture vc;
#endif
};
}//namespace
VideoFileSource::VideoFileSource(const string &path, bool volatileFrame) void VideoFileSource::reset()
: impl(new VideoFileSourceImpl(path, volatileFrame)) {} {
reader_.release();
reader_.open(path_);
if (!reader_.isOpened())
throw runtime_error("can't open file: " + path_);
}
void VideoFileSource::reset() { impl->reset(); }
Mat VideoFileSource::nextFrame() { return impl->nextFrame(); }
int VideoFileSource::width() { return ((VideoFileSourceImpl*)impl.obj)->width(); } Mat VideoFileSource::nextFrame()
int VideoFileSource::height() { return ((VideoFileSourceImpl*)impl.obj)->height(); } {
int VideoFileSource::count() { return ((VideoFileSourceImpl*)impl.obj)->count(); } Mat frame;
double VideoFileSource::fps() { return ((VideoFileSourceImpl*)impl.obj)->fps(); } reader_ >> frame;
return volatileFrame_ ? frame : frame.clone();
}
} // namespace videostab } // namespace videostab
} // namespace cv } // namespace cv
This diff is collapsed.
...@@ -45,8 +45,6 @@ ...@@ -45,8 +45,6 @@
#include "opencv2/videostab/inpainting.hpp" #include "opencv2/videostab/inpainting.hpp"
#include "opencv2/videostab/global_motion.hpp" #include "opencv2/videostab/global_motion.hpp"
#include "opencv2/videostab/fast_marching.hpp" #include "opencv2/videostab/fast_marching.hpp"
#include "opencv2/videostab/ring_buffer.hpp"
#include "opencv2/opencv_modules.hpp"
using namespace std; using namespace std;
...@@ -71,14 +69,6 @@ void InpaintingPipeline::setFrames(const vector<Mat> &val) ...@@ -71,14 +69,6 @@ void InpaintingPipeline::setFrames(const vector<Mat> &val)
} }
void InpaintingPipeline::setMotionModel(MotionModel val)
{
for (size_t i = 0; i < inpainters_.size(); ++i)
inpainters_[i]->setMotionModel(val);
InpainterBase::setMotionModel(val);
}
void InpaintingPipeline::setMotions(const vector<Mat> &val) void InpaintingPipeline::setMotions(const vector<Mat> &val)
{ {
for (size_t i = 0; i < inpainters_.size(); ++i) for (size_t i = 0; i < inpainters_.size(); ++i)
...@@ -103,6 +93,14 @@ void InpaintingPipeline::setStabilizationMotions(const vector<Mat> &val) ...@@ -103,6 +93,14 @@ void InpaintingPipeline::setStabilizationMotions(const vector<Mat> &val)
} }
void InpaintingPipeline::update()
{
for (size_t i = 0; i < inpainters_.size(); ++i)
inpainters_[i]->update();
InpainterBase::update();
}
void InpaintingPipeline::inpaint(int idx, Mat &frame, Mat &mask) void InpaintingPipeline::inpaint(int idx, Mat &frame, Mat &mask)
{ {
for (size_t i = 0; i < inpainters_.size(); ++i) for (size_t i = 0; i < inpainters_.size(); ++i)
...@@ -130,9 +128,9 @@ void ConsistentMosaicInpainter::inpaint(int idx, Mat &frame, Mat &mask) ...@@ -130,9 +128,9 @@ void ConsistentMosaicInpainter::inpaint(int idx, Mat &frame, Mat &mask)
CV_Assert(mask.size() == frame.size() && mask.type() == CV_8U); CV_Assert(mask.size() == frame.size() && mask.type() == CV_8U);
Mat invS = at(idx, *stabilizationMotions_).inv(); Mat invS = at(idx, *stabilizationMotions_).inv();
vector<Mat_<float> > vmotions(2*radius_ + 1); vector<Mat_<float> > _motions(2*radius_ + 1);
for (int i = -radius_; i <= radius_; ++i) for (int i = -radius_; i <= radius_; ++i)
vmotions[radius_ + i] = getMotion(idx, idx + i, *motions_) * invS; _motions[radius_ + i] = getMotion(idx, idx + i, *motions_) * invS;
int n; int n;
float mean, var; float mean, var;
...@@ -154,7 +152,7 @@ void ConsistentMosaicInpainter::inpaint(int idx, Mat &frame, Mat &mask) ...@@ -154,7 +152,7 @@ void ConsistentMosaicInpainter::inpaint(int idx, Mat &frame, Mat &mask)
for (int i = -radius_; i <= radius_; ++i) for (int i = -radius_; i <= radius_; ++i)
{ {
const Mat_<Point3_<uchar> > &framei = at(idx + i, *frames_); const Mat_<Point3_<uchar> > &framei = at(idx + i, *frames_);
const Mat_<float> &Mi = vmotions[radius_ + i]; const Mat_<float> &Mi = _motions[radius_ + i];
int xi = cvRound(Mi(0,0)*x + Mi(0,1)*y + Mi(0,2)); int xi = cvRound(Mi(0,0)*x + Mi(0,1)*y + Mi(0,2));
int yi = cvRound(Mi(1,0)*x + Mi(1,1)*y + Mi(1,2)); int yi = cvRound(Mi(1,0)*x + Mi(1,1)*y + Mi(1,2));
if (xi >= 0 && xi < framei.cols && yi >= 0 && yi < framei.rows) if (xi >= 0 && xi < framei.cols && yi >= 0 && yi < framei.rows)
...@@ -339,12 +337,12 @@ MotionInpainter::MotionInpainter() ...@@ -339,12 +337,12 @@ MotionInpainter::MotionInpainter()
void MotionInpainter::inpaint(int idx, Mat &frame, Mat &mask) void MotionInpainter::inpaint(int idx, Mat &frame, Mat &mask)
{ {
priority_queue<pair<float,int> > neighbors; priority_queue<pair<float,int> > neighbors;
vector<Mat> vmotions(2*radius_ + 1); vector<Mat> _motions(2*radius_ + 1);
for (int i = -radius_; i <= radius_; ++i) for (int i = -radius_; i <= radius_; ++i)
{ {
Mat motion0to1 = getMotion(idx, idx + i, *motions_) * at(idx, *stabilizationMotions_).inv(); Mat motion0to1 = getMotion(idx, idx + i, *motions_) * at(idx, *stabilizationMotions_).inv();
vmotions[radius_ + i] = motion0to1; _motions[radius_ + i] = motion0to1;
if (i != 0) if (i != 0)
{ {
...@@ -370,36 +368,19 @@ void MotionInpainter::inpaint(int idx, Mat &frame, Mat &mask) ...@@ -370,36 +368,19 @@ void MotionInpainter::inpaint(int idx, Mat &frame, Mat &mask)
int neighbor = neighbors.top().second; int neighbor = neighbors.top().second;
neighbors.pop(); neighbors.pop();
Mat motion1to0 = vmotions[radius_ + neighbor - idx].inv(); Mat motion1to0 = _motions[radius_ + neighbor - idx].inv();
// warp frame
frame1_ = at(neighbor, *frames_); frame1_ = at(neighbor, *frames_);
warpAffine(
if (motionModel_ != MM_HOMOGRAPHY) frame1_, transformedFrame1_, motion1to0(Rect(0,0,3,2)), frame1_.size(),
warpAffine( INTER_LINEAR, borderMode_);
frame1_, transformedFrame1_, motion1to0(Rect(0,0,3,2)), frame1_.size(),
INTER_LINEAR, borderMode_);
else
warpPerspective(
frame1_, transformedFrame1_, motion1to0, frame1_.size(), INTER_LINEAR,
borderMode_);
cvtColor(transformedFrame1_, transformedGrayFrame1_, CV_BGR2GRAY); cvtColor(transformedFrame1_, transformedGrayFrame1_, CV_BGR2GRAY);
// warp mask warpAffine(
mask1_, transformedMask1_, motion1to0(Rect(0,0,3,2)), mask1_.size(),
if (motionModel_ != MM_HOMOGRAPHY) INTER_NEAREST);
warpAffine(
mask1_, transformedMask1_, motion1to0(Rect(0,0,3,2)), mask1_.size(),
INTER_NEAREST);
else
warpPerspective(mask1_, transformedMask1_, motion1to0, mask1_.size(), INTER_NEAREST);
erode(transformedMask1_, transformedMask1_, Mat()); erode(transformedMask1_, transformedMask1_, Mat());
// update flow
optFlowEstimator_->run(grayFrame_, transformedGrayFrame1_, flowX_, flowY_, flowErrors_); optFlowEstimator_->run(grayFrame_, transformedGrayFrame1_, flowX_, flowY_, flowErrors_);
calcFlowMask( calcFlowMask(
...@@ -521,6 +502,7 @@ void completeFrameAccordingToFlow( ...@@ -521,6 +502,7 @@ void completeFrameAccordingToFlow(
Mat_<uchar> flowMask_(flowMask), mask1_(mask1), mask0_(mask0); Mat_<uchar> flowMask_(flowMask), mask1_(mask1), mask0_(mask0);
Mat_<float> flowX_(flowX), flowY_(flowY); Mat_<float> flowX_(flowX), flowY_(flowY);
//int count = 0;
for (int y0 = 0; y0 < frame0.rows; ++y0) for (int y0 = 0; y0 < frame0.rows; ++y0)
{ {
for (int x0 = 0; x0 < frame0.cols; ++x0) for (int x0 = 0; x0 < frame0.cols; ++x0)
...@@ -535,10 +517,12 @@ void completeFrameAccordingToFlow( ...@@ -535,10 +517,12 @@ void completeFrameAccordingToFlow(
{ {
frame0.at<Point3_<uchar> >(y0,x0) = frame1.at<Point3_<uchar> >(y1,x1); frame0.at<Point3_<uchar> >(y0,x0) = frame1.at<Point3_<uchar> >(y1,x1);
mask0_(y0,x0) = 255; mask0_(y0,x0) = 255;
//count++;
} }
} }
} }
} }
//cout << count << endl;
} }
} // namespace videostab } // namespace videostab
......
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
#include "precomp.hpp" #include "precomp.hpp"
#include "opencv2/video/video.hpp" #include "opencv2/video/video.hpp"
#include "opencv2/videostab/optical_flow.hpp" #include "opencv2/videostab/optical_flow.hpp"
#include "opencv2/videostab/ring_buffer.hpp"
using namespace std; using namespace std;
...@@ -61,53 +60,6 @@ void SparsePyrLkOptFlowEstimator::run( ...@@ -61,53 +60,6 @@ void SparsePyrLkOptFlowEstimator::run(
#ifdef HAVE_OPENCV_GPU #ifdef HAVE_OPENCV_GPU
SparsePyrLkOptFlowEstimatorGpu::SparsePyrLkOptFlowEstimatorGpu()
{
CV_Assert(gpu::getCudaEnabledDeviceCount() > 0);
}
void SparsePyrLkOptFlowEstimatorGpu::run(
InputArray frame0, InputArray frame1, InputArray points0, InputOutputArray points1,
OutputArray status, OutputArray errors)
{
frame0_.upload(frame0.getMat());
frame1_.upload(frame1.getMat());
points0_.upload(points0.getMat());
if (errors.needed())
{
run(frame0_, frame1_, points0_, points1_, status_, errors_);
errors_.download(errors.getMatRef());
}
else
run(frame0_, frame1_, points0_, points1_, status_);
points1_.download(points1.getMatRef());
status_.download(status.getMatRef());
}
void SparsePyrLkOptFlowEstimatorGpu::run(
const gpu::GpuMat &frame0, const gpu::GpuMat &frame1, const gpu::GpuMat &points0,
gpu::GpuMat &points1, gpu::GpuMat &status, gpu::GpuMat &errors)
{
optFlowEstimator_.winSize = winSize_;
optFlowEstimator_.maxLevel = maxLevel_;
optFlowEstimator_.sparse(frame0, frame1, points0, points1, status, &errors);
}
void SparsePyrLkOptFlowEstimatorGpu::run(
const gpu::GpuMat &frame0, const gpu::GpuMat &frame1, const gpu::GpuMat &points0,
gpu::GpuMat &points1, gpu::GpuMat &status)
{
optFlowEstimator_.winSize = winSize_;
optFlowEstimator_.maxLevel = maxLevel_;
optFlowEstimator_.sparse(frame0, frame1, points0, points1, status);
}
DensePyrLkOptFlowEstimatorGpu::DensePyrLkOptFlowEstimatorGpu() DensePyrLkOptFlowEstimatorGpu::DensePyrLkOptFlowEstimatorGpu()
{ {
CV_Assert(gpu::getCudaEnabledDeviceCount() > 0); CV_Assert(gpu::getCudaEnabledDeviceCount() > 0);
...@@ -123,7 +75,6 @@ void DensePyrLkOptFlowEstimatorGpu::run( ...@@ -123,7 +75,6 @@ void DensePyrLkOptFlowEstimatorGpu::run(
optFlowEstimator_.winSize = winSize_; optFlowEstimator_.winSize = winSize_;
optFlowEstimator_.maxLevel = maxLevel_; optFlowEstimator_.maxLevel = maxLevel_;
if (errors.needed()) if (errors.needed())
{ {
optFlowEstimator_.dense(frame0_, frame1_, flowX_, flowY_, &errors_); optFlowEstimator_.dense(frame0_, frame1_, flowX_, flowY_, &errors_);
...@@ -135,7 +86,8 @@ void DensePyrLkOptFlowEstimatorGpu::run( ...@@ -135,7 +86,8 @@ void DensePyrLkOptFlowEstimatorGpu::run(
flowX_.download(flowX.getMatRef()); flowX_.download(flowX.getMatRef());
flowY_.download(flowY.getMatRef()); flowY_.download(flowY.getMatRef());
} }
#endif // HAVE_OPENCV_GPU #endif
} // namespace videostab } // namespace videostab
} // namespace cv } // namespace cv
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#include "precomp.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/videostab/outlier_rejection.hpp"
using namespace std;
namespace cv
{
namespace videostab
{
void NullOutlierRejector::process(
Size /*frameSize*/, InputArray points0, InputArray points1, OutputArray mask)
{
CV_Assert(points0.type() == points1.type());
CV_Assert(points0.getMat().checkVector(2) == points1.getMat().checkVector(2));
int npoints = points0.getMat().checkVector(2);
mask.create(1, npoints, CV_8U);
Mat mask_ = mask.getMat();
mask_.setTo(1);
}
TranslationBasedLocalOutlierRejector::TranslationBasedLocalOutlierRejector()
{
setCellSize(Size(50, 50));
setRansacParams(RansacParams::default2dMotion(MM_TRANSLATION));
}
void TranslationBasedLocalOutlierRejector::process(
Size frameSize, InputArray points0, InputArray points1, OutputArray mask)
{
CV_Assert(points0.type() == points1.type());
CV_Assert(points0.getMat().checkVector(2) == points1.getMat().checkVector(2));
int npoints = points0.getMat().checkVector(2);
const Point2f* points0_ = points0.getMat().ptr<Point2f>();
const Point2f* points1_ = points1.getMat().ptr<Point2f>();
mask.create(1, npoints, CV_8U);
uchar* mask_ = mask.getMat().ptr<uchar>();
Size ncells((frameSize.width + cellSize_.width - 1) / cellSize_.width,
(frameSize.height + cellSize_.height - 1) / cellSize_.height);
int cx, cy;
// fill grid cells
grid_.assign(ncells.area(), Cell());
for (int i = 0; i < npoints; ++i)
{
cx = std::min(cvRound(points0_[i].x / cellSize_.width), ncells.width - 1);
cy = std::min(cvRound(points0_[i].y / cellSize_.height), ncells.height - 1);
grid_[cy * ncells.width + cx].push_back(i);
}
// process each cell
RNG rng(0);
int niters = ransacParams_.niters();
int ninliers, ninliersMax;
vector<int> inliers;
float dx, dy, dxBest, dyBest;
float x1, y1;
int idx;
for (size_t ci = 0; ci < grid_.size(); ++ci)
{
// estimate translation model at the current cell using RANSAC
const Cell &cell = grid_[ci];
ninliersMax = 0;
dxBest = dyBest = 0.f;
// find the best hypothesis
if (!cell.empty())
{
for (int iter = 0; iter < niters; ++iter)
{
idx = cell[static_cast<unsigned>(rng) % cell.size()];
dx = points1_[idx].x - points0_[idx].x;
dy = points1_[idx].y - points0_[idx].y;
ninliers = 0;
for (size_t i = 0; i < cell.size(); ++i)
{
x1 = points0_[cell[i]].x + dx;
y1 = points0_[cell[i]].y + dy;
if (sqr(x1 - points1_[cell[i]].x) + sqr(y1 - points1_[cell[i]].y) <
sqr(ransacParams_.thresh))
{
ninliers++;
}
}
if (ninliers > ninliersMax)
{
ninliersMax = ninliers;
dxBest = dx;
dyBest = dy;
}
}
}
// get the best hypothesis inliers
ninliers = 0;
inliers.resize(ninliersMax);
for (size_t i = 0; i < cell.size(); ++i)
{
x1 = points0_[cell[i]].x + dxBest;
y1 = points0_[cell[i]].y + dyBest;
if (sqr(x1 - points1_[cell[i]].x) + sqr(y1 - points1_[cell[i]].y) <
sqr(ransacParams_.thresh))
{
inliers[ninliers++] = cell[i];
}
}
// refine the best hypothesis
dxBest = dyBest = 0.f;
for (size_t i = 0; i < inliers.size(); ++i)
{
dxBest += points1_[inliers[i]].x - points0_[inliers[i]].x;
dyBest += points1_[inliers[i]].y - points0_[inliers[i]].y;
}
if (!inliers.empty())
{
dxBest /= inliers.size();
dyBest /= inliers.size();
}
// set mask elements for refined model inliers
for (size_t i = 0; i < cell.size(); ++i)
{
x1 = points0_[cell[i]].x + dxBest;
y1 = points0_[cell[i]].y + dyBest;
if (sqr(x1 - points1_[cell[i]].x) + sqr(y1 - points1_[cell[i]].y) <
sqr(ransacParams_.thresh))
{
mask_[cell[i]] = 1;
}
else
{
mask_[cell[i]] = 0;
}
}
}
}
} // namespace videostab
} // namespace cv
...@@ -44,20 +44,15 @@ ...@@ -44,20 +44,15 @@
#define __OPENCV_PRECOMP_HPP__ #define __OPENCV_PRECOMP_HPP__
#ifdef HAVE_CVCONFIG_H #ifdef HAVE_CVCONFIG_H
#include "cvconfig.h" #include "cvconfig.h"
#endif #endif
#include <stdexcept> #include <stdexcept>
#include <iostream> #include <iostream>
#include <ctime>
#include <algorithm>
#include "opencv2/core/core.hpp" #include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/video.hpp" #include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp" #include "opencv2/features2d/features2d.hpp"
#include "opencv2/calib3d/calib3d.hpp"
// some aux. functions
inline float sqr(float x) { return x * x; } inline float sqr(float x) { return x * x; }
...@@ -66,5 +61,25 @@ inline float intensity(const cv::Point3_<uchar> &bgr) ...@@ -66,5 +61,25 @@ inline float intensity(const cv::Point3_<uchar> &bgr)
return 0.3f*bgr.x + 0.59f*bgr.y + 0.11f*bgr.z; return 0.3f*bgr.x + 0.59f*bgr.y + 0.11f*bgr.z;
} }
template <typename T> inline T& at(int index, T *items, int size)
{
return items[cv::borderInterpolate(index, size, cv::BORDER_WRAP)];
}
template <typename T> inline const T& at(int index, const T *items, int size)
{
return items[cv::borderInterpolate(index, size, cv::BORDER_WRAP)];
}
template <typename T> inline T& at(int index, std::vector<T> &items)
{
return at(index, &items[0], static_cast<int>(items.size()));
}
template <typename T> inline const T& at(int index, const std::vector<T> &items)
{
return items[cv::borderInterpolate(index, static_cast<int>(items.size()), cv::BORDER_WRAP)];
}
#endif #endif
This diff is collapsed.
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// 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
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 the Intel Corporation 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.
//
//M*/
#include "precomp.hpp"
#include "opencv2/videostab/wobble_suppression.hpp"
#include "opencv2/videostab/ring_buffer.hpp"
using namespace std;
namespace cv
{
namespace videostab
{
WobbleSuppressorBase::WobbleSuppressorBase() : motions_(0), stabilizationMotions_(0)
{
setMotionEstimator(new KeypointBasedMotionEstimator(new MotionEstimatorRansacL2(MM_HOMOGRAPHY)));
}
void NullWobbleSuppressor::suppress(int /*idx*/, const Mat &frame, Mat &result)
{
result = frame;
}
void MoreAccurateMotionWobbleSuppressor::suppress(int idx, const Mat &frame, Mat &result)
{
CV_Assert(motions_ && stabilizationMotions_);
if (idx % period_ == 0)
{
result = frame;
return;
}
int k1 = idx / period_ * period_;
int k2 = std::min(k1 + period_, frameCount_ - 1);
Mat S1 = (*stabilizationMotions_)[idx];
Mat_<float> ML = S1 * getMotion(k1, idx, *motions2_) * getMotion(k1, idx, *motions_).inv() * S1.inv();
Mat_<float> MR = S1 * getMotion(idx, k2, *motions2_).inv() * getMotion(idx, k2, *motions_) * S1.inv();
mapx_.create(frame.size());
mapy_.create(frame.size());
float xl, yl, zl, wl;
float xr, yr, zr, wr;
for (int y = 0; y < frame.rows; ++y)
{
for (int x = 0; x < frame.cols; ++x)
{
xl = ML(0,0)*x + ML(0,1)*y + ML(0,2);
yl = ML(1,0)*x + ML(1,1)*y + ML(1,2);
zl = ML(2,0)*x + ML(2,1)*y + ML(2,2);
xl /= zl; yl /= zl;
wl = float(idx - k1);
xr = MR(0,0)*x + MR(0,1)*y + MR(0,2);
yr = MR(1,0)*x + MR(1,1)*y + MR(1,2);
zr = MR(2,0)*x + MR(2,1)*y + MR(2,2);
xr /= zr; yr /= zr;
wr = float(k2 - idx);
mapx_(y,x) = (wr * xl + wl * xr) / (wl + wr);
mapy_(y,x) = (wr * yl + wl * yr) / (wl + wr);
}
}
if (result.data == frame.data)
result = Mat(frame.size(), frame.type());
remap(frame, result, mapx_, mapy_, INTER_LINEAR, BORDER_REPLICATE);
}
#ifdef HAVE_OPENCV_GPU
void MoreAccurateMotionWobbleSuppressorGpu::suppress(int idx, const gpu::GpuMat &frame, gpu::GpuMat &result)
{
CV_Assert(motions_ && stabilizationMotions_);
if (idx % period_ == 0)
{
result = frame;
return;
}
int k1 = idx / period_ * period_;
int k2 = std::min(k1 + period_, frameCount_ - 1);
Mat S1 = (*stabilizationMotions_)[idx];
Mat ML = S1 * getMotion(k1, idx, *motions2_) * getMotion(k1, idx, *motions_).inv() * S1.inv();
Mat MR = S1 * getMotion(idx, k2, *motions2_).inv() * getMotion(idx, k2, *motions_) * S1.inv();
gpu::calcWobbleSuppressionMaps(k1, idx, k2, frame.size(), ML, MR, mapx_, mapy_);
if (result.data == frame.data)
result = gpu::GpuMat(frame.size(), frame.type());
gpu::remap(frame, result, mapx_, mapy_, INTER_LINEAR, BORDER_REPLICATE);
}
void MoreAccurateMotionWobbleSuppressorGpu::suppress(int idx, const Mat &frame, Mat &result)
{
frameDevice_.upload(frame);
suppress(idx, frameDevice_, resultDevice_);
resultDevice_.download(result);
}
#endif
} // namespace videostab
} // namespace cv
This diff is collapsed.
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