mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 08:13:04 +04:00
Refactored videostab module. Added MoreAccurateMotionWobbleSuppressor class
This commit is contained in:
@@ -56,13 +56,18 @@ CV_EXPORTS float calcBlurriness(const Mat &frame);
|
||||
class CV_EXPORTS DeblurerBase
|
||||
{
|
||||
public:
|
||||
DeblurerBase() : radius_(0), frames_(0), motions_(0) {}
|
||||
DeblurerBase() : radius_(0), frames_(0), motions_(0), blurrinessRates_(0) {}
|
||||
|
||||
virtual ~DeblurerBase() {}
|
||||
|
||||
virtual void setRadius(int val) { radius_ = val; }
|
||||
virtual int radius() const { return radius_; }
|
||||
|
||||
virtual void deblur(int idx, Mat &frame) = 0;
|
||||
|
||||
|
||||
// data from stabilizer
|
||||
|
||||
virtual void setFrames(const std::vector<Mat> &val) { frames_ = &val; }
|
||||
virtual const std::vector<Mat>& frames() const { return *frames_; }
|
||||
|
||||
@@ -72,8 +77,6 @@ public:
|
||||
virtual void setBlurrinessRates(const std::vector<float> &val) { blurrinessRates_ = &val; }
|
||||
virtual const std::vector<float>& blurrinessRates() const { return *blurrinessRates_; }
|
||||
|
||||
virtual void deblur(int idx, Mat &frame) = 0;
|
||||
|
||||
protected:
|
||||
int radius_;
|
||||
const std::vector<Mat> *frames_;
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#define __OPENCV_VIDEOSTAB_GLOBAL_MOTION_HPP__
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "opencv2/videostab/optical_flow.hpp"
|
||||
@@ -105,13 +107,25 @@ protected:
|
||||
MotionModel motionModel_;
|
||||
};
|
||||
|
||||
class CV_EXPORTS EyeMotionEstimator : public GlobalMotionEstimatorBase
|
||||
class CV_EXPORTS FromFileMotionReader : public GlobalMotionEstimatorBase
|
||||
{
|
||||
public:
|
||||
virtual Mat estimate(const Mat &/*frame0*/, const Mat &/*frame1*/)
|
||||
{
|
||||
return Mat::eye(3, 3, CV_32F);
|
||||
}
|
||||
FromFileMotionReader(const std::string &path);
|
||||
virtual Mat estimate(const Mat &frame0, const Mat &frame1);
|
||||
|
||||
private:
|
||||
std::ifstream file_;
|
||||
};
|
||||
|
||||
class CV_EXPORTS ToFileMotionWriter : public GlobalMotionEstimatorBase
|
||||
{
|
||||
public:
|
||||
ToFileMotionWriter(const std::string &path, Ptr<GlobalMotionEstimatorBase> estimator);
|
||||
virtual Mat estimate(const Mat &frame0, const Mat &frame1);
|
||||
|
||||
private:
|
||||
std::ofstream file_;
|
||||
Ptr<GlobalMotionEstimatorBase> estimator_;
|
||||
};
|
||||
|
||||
class CV_EXPORTS PyrLkRobustMotionEstimator : public GlobalMotionEstimatorBase
|
||||
|
||||
@@ -59,7 +59,7 @@ class CV_EXPORTS InpainterBase
|
||||
{
|
||||
public:
|
||||
InpainterBase()
|
||||
: radius_(0), frames_(0), motions_(0),
|
||||
: radius_(0), motionModel_(UNKNOWN), frames_(0), motions_(0),
|
||||
stabilizedFrames_(0), stabilizationMotions_(0) {}
|
||||
|
||||
virtual ~InpainterBase() {}
|
||||
@@ -70,6 +70,11 @@ public:
|
||||
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 const std::vector<Mat>& frames() const { return *frames_; }
|
||||
|
||||
@@ -82,8 +87,6 @@ public:
|
||||
virtual void setStabilizationMotions(const std::vector<Mat> &val) { stabilizationMotions_ = &val; }
|
||||
virtual const std::vector<Mat>& stabilizationMotions() const { return *stabilizationMotions_; }
|
||||
|
||||
virtual void inpaint(int idx, Mat &frame, Mat &mask) = 0;
|
||||
|
||||
protected:
|
||||
int radius_;
|
||||
MotionModel motionModel_;
|
||||
|
||||
@@ -184,6 +184,8 @@ private:
|
||||
|
||||
int frameCount_;
|
||||
bool isPrePassDone_;
|
||||
bool doWobbleSuppression_;
|
||||
std::vector<Mat> motions2_;
|
||||
Mat suppressedFrame_;
|
||||
};
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <vector>
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/videostab/global_motion.hpp"
|
||||
#include "opencv2/videostab/log.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
@@ -55,33 +56,48 @@ namespace videostab
|
||||
class CV_EXPORTS WobbleSuppressorBase
|
||||
{
|
||||
public:
|
||||
WobbleSuppressorBase();
|
||||
|
||||
virtual ~WobbleSuppressorBase() {}
|
||||
|
||||
virtual void setFrames(const std::vector<Mat> &val) { frames_ = &val; }
|
||||
virtual const std::vector<Mat>& frames() const { return *frames_; }
|
||||
void setMotionEstimator(Ptr<GlobalMotionEstimatorBase> val) { motionEstimator_ = val; }
|
||||
Ptr<GlobalMotionEstimatorBase> 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 setStabilizedFrames(const std::vector<Mat> &val) { stabilizedFrames_ = &val; }
|
||||
virtual const std::vector<Mat>& stabilizedFrames() const { return *stabilizedFrames_; }
|
||||
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_; }
|
||||
|
||||
virtual void suppress(int idx, Mat &frame) = 0;
|
||||
|
||||
protected:
|
||||
const std::vector<Mat> *frames_;
|
||||
Ptr<GlobalMotionEstimatorBase> motionEstimator_;
|
||||
int frameCount_;
|
||||
const std::vector<Mat> *motions_;
|
||||
const std::vector<Mat> *stabilizedFrames_;
|
||||
const std::vector<Mat> *motions2_;
|
||||
const std::vector<Mat> *stabilizationMotions_;
|
||||
};
|
||||
|
||||
class CV_EXPORTS NullWobbleSuppressor : public WobbleSuppressorBase
|
||||
{
|
||||
public:
|
||||
virtual void suppress(int idx, Mat &result);
|
||||
virtual void suppress(int idx, const Mat &frame, Mat &result);
|
||||
};
|
||||
|
||||
class CV_EXPORTS MoreAccurateMotionWobbleSuppressor : public WobbleSuppressorBase
|
||||
{
|
||||
public:
|
||||
virtual void suppress(int idx, const Mat &frame, Mat &result);
|
||||
};
|
||||
|
||||
} // namespace videostab
|
||||
|
||||
@@ -288,6 +288,41 @@ Mat estimateGlobalMotionRobust(
|
||||
}
|
||||
|
||||
|
||||
FromFileMotionReader::FromFileMotionReader(const string &path)
|
||||
{
|
||||
file_.open(path.c_str());
|
||||
CV_Assert(file_.is_open());
|
||||
}
|
||||
|
||||
|
||||
Mat FromFileMotionReader::estimate(const Mat &/*frame0*/, const Mat &/*frame1*/)
|
||||
{
|
||||
Mat_<float> M(3, 3);
|
||||
file_ >> M(0,0) >> M(0,1) >> M(0,2)
|
||||
>> M(1,0) >> M(1,1) >> M(1,2)
|
||||
>> M(2,0) >> M(2,1) >> M(2,2);
|
||||
return M;
|
||||
}
|
||||
|
||||
|
||||
ToFileMotionWriter::ToFileMotionWriter(const string &path, Ptr<GlobalMotionEstimatorBase> estimator)
|
||||
{
|
||||
file_.open(path.c_str());
|
||||
CV_Assert(file_.is_open());
|
||||
estimator_ = estimator;
|
||||
}
|
||||
|
||||
|
||||
Mat ToFileMotionWriter::estimate(const Mat &frame0, const Mat &frame1)
|
||||
{
|
||||
Mat_<float> M = estimator_->estimate(frame0, frame1);
|
||||
file_ << M(0,0) << " " << M(0,1) << " " << M(0,2) << " "
|
||||
<< M(1,0) << " " << M(1,1) << " " << M(1,2) << " "
|
||||
<< M(2,0) << " " << M(2,1) << " " << M(2,2) << endl;
|
||||
return M;
|
||||
}
|
||||
|
||||
|
||||
PyrLkRobustMotionEstimator::PyrLkRobustMotionEstimator()
|
||||
: ransacParams_(RansacParams::affine2dMotionStd())
|
||||
{
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace videostab
|
||||
|
||||
StabilizerBase::StabilizerBase()
|
||||
{
|
||||
setLog(new NullLog());
|
||||
setLog(new LogToStdout());
|
||||
setFrameSource(new NullFrameSource());
|
||||
setMotionEstimator(new PyrLkRobustMotionEstimator());
|
||||
setDeblurer(new NullDeblurer());
|
||||
@@ -304,6 +304,8 @@ void TwoPassStabilizer::reset()
|
||||
StabilizerBase::reset();
|
||||
frameCount_ = 0;
|
||||
isPrePassDone_ = false;
|
||||
doWobbleSuppression_ = false;
|
||||
motions2_.clear();
|
||||
suppressedFrame_ = Mat();
|
||||
}
|
||||
|
||||
@@ -333,10 +335,20 @@ void TwoPassStabilizer::runPrePassIfNecessary()
|
||||
|
||||
Mat prevFrame, frame;
|
||||
|
||||
WobbleSuppressorBase *wobbleSuppressor = static_cast<WobbleSuppressorBase*>(wobbleSuppressor_);
|
||||
doWobbleSuppression_ = dynamic_cast<NullWobbleSuppressor*>(wobbleSuppressor) == 0;
|
||||
|
||||
while (!(frame = frameSource_->nextFrame()).empty())
|
||||
{
|
||||
if (frameCount_ > 0)
|
||||
{
|
||||
motions_.push_back(motionEstimator_->estimate(prevFrame, frame));
|
||||
if (doWobbleSuppression_)
|
||||
{
|
||||
motions2_.push_back(
|
||||
wobbleSuppressor_->motionEstimator()->estimate(prevFrame, frame));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
frameSize_ = frame.size();
|
||||
@@ -386,10 +398,15 @@ void TwoPassStabilizer::setUp(const Mat &firstFrame)
|
||||
for (int i = -radius_; i <= 0; ++i)
|
||||
at(i, frames_) = firstFrame;
|
||||
|
||||
wobbleSuppressor_->setFrames(frames_);
|
||||
wobbleSuppressor_->setMotions(motions_);
|
||||
wobbleSuppressor_->setStabilizedFrames(stabilizedFrames_);
|
||||
wobbleSuppressor_->setStabilizationMotions(stabilizationMotions_);
|
||||
WobbleSuppressorBase *wobbleSuppressor = static_cast<WobbleSuppressorBase*>(wobbleSuppressor_);
|
||||
doWobbleSuppression_ = dynamic_cast<NullWobbleSuppressor*>(wobbleSuppressor) == 0;
|
||||
if (doWobbleSuppression_)
|
||||
{
|
||||
wobbleSuppressor_->setFrameCount(frameCount_);
|
||||
wobbleSuppressor_->setMotions(motions_);
|
||||
wobbleSuppressor_->setMotions2(motions2_);
|
||||
wobbleSuppressor_->setStabilizationMotions(stabilizationMotions_);
|
||||
}
|
||||
|
||||
StabilizerBase::setUp(firstFrame);
|
||||
}
|
||||
@@ -407,9 +424,9 @@ Mat TwoPassStabilizer::estimateStabilizationMotion()
|
||||
}
|
||||
|
||||
|
||||
Mat TwoPassStabilizer::postProcessFrame(const Mat &/*frame*/)
|
||||
Mat TwoPassStabilizer::postProcessFrame(const Mat &frame)
|
||||
{
|
||||
wobbleSuppressor_->suppress(curStabilizedPos_, suppressedFrame_);
|
||||
wobbleSuppressor_->suppress(curStabilizedPos_, frame, suppressedFrame_);
|
||||
return StabilizerBase::postProcessFrame(suppressedFrame_);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,9 +51,30 @@ namespace cv
|
||||
namespace videostab
|
||||
{
|
||||
|
||||
void NullWobbleSuppressor::suppress(int idx, Mat &result)
|
||||
WobbleSuppressorBase::WobbleSuppressorBase()
|
||||
: motions_(0), stabilizationMotions_(0)
|
||||
{
|
||||
result = at(idx, *stabilizedFrames_);
|
||||
PyrLkRobustMotionEstimator *est = new PyrLkRobustMotionEstimator();
|
||||
est->setMotionModel(HOMOGRAPHY);
|
||||
est->setRansacParams(RansacParams::homography2dMotionStd());
|
||||
setMotionEstimator(est);
|
||||
}
|
||||
|
||||
|
||||
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_);
|
||||
|
||||
// TODO implement
|
||||
CV_Error(CV_StsNotImplemented, "MoreAccurateMotionWobbleSuppressor");
|
||||
|
||||
result = frame;
|
||||
}
|
||||
|
||||
} // namespace videostab
|
||||
|
||||
Reference in New Issue
Block a user