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
|
class CV_EXPORTS DeblurerBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DeblurerBase() : radius_(0), frames_(0), motions_(0) {}
|
DeblurerBase() : radius_(0), frames_(0), motions_(0), blurrinessRates_(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_; }
|
||||||
|
|
||||||
|
virtual void deblur(int idx, Mat &frame) = 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_; }
|
||||||
|
|
||||||
@@ -72,8 +77,6 @@ public:
|
|||||||
virtual void setBlurrinessRates(const std::vector<float> &val) { blurrinessRates_ = &val; }
|
virtual void setBlurrinessRates(const std::vector<float> &val) { blurrinessRates_ = &val; }
|
||||||
virtual const std::vector<float>& blurrinessRates() const { return *blurrinessRates_; }
|
virtual const std::vector<float>& blurrinessRates() const { return *blurrinessRates_; }
|
||||||
|
|
||||||
virtual void deblur(int idx, Mat &frame) = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int radius_;
|
int radius_;
|
||||||
const std::vector<Mat> *frames_;
|
const std::vector<Mat> *frames_;
|
||||||
|
@@ -44,6 +44,8 @@
|
|||||||
#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/videostab/optical_flow.hpp"
|
#include "opencv2/videostab/optical_flow.hpp"
|
||||||
@@ -105,13 +107,25 @@ protected:
|
|||||||
MotionModel motionModel_;
|
MotionModel motionModel_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CV_EXPORTS EyeMotionEstimator : public GlobalMotionEstimatorBase
|
class CV_EXPORTS FromFileMotionReader : public GlobalMotionEstimatorBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual Mat estimate(const Mat &/*frame0*/, const Mat &/*frame1*/)
|
FromFileMotionReader(const std::string &path);
|
||||||
{
|
virtual Mat estimate(const Mat &frame0, const Mat &frame1);
|
||||||
return Mat::eye(3, 3, CV_32F);
|
|
||||||
}
|
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
|
class CV_EXPORTS PyrLkRobustMotionEstimator : public GlobalMotionEstimatorBase
|
||||||
|
@@ -59,7 +59,7 @@ class CV_EXPORTS InpainterBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InpainterBase()
|
InpainterBase()
|
||||||
: radius_(0), frames_(0), motions_(0),
|
: radius_(0), motionModel_(UNKNOWN), frames_(0), motions_(0),
|
||||||
stabilizedFrames_(0), stabilizationMotions_(0) {}
|
stabilizedFrames_(0), stabilizationMotions_(0) {}
|
||||||
|
|
||||||
virtual ~InpainterBase() {}
|
virtual ~InpainterBase() {}
|
||||||
@@ -70,6 +70,11 @@ public:
|
|||||||
virtual void setMotionModel(MotionModel val) { motionModel_ = val; }
|
virtual void setMotionModel(MotionModel val) { motionModel_ = val; }
|
||||||
virtual MotionModel motionModel() const { return motionModel_; }
|
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_; }
|
||||||
|
|
||||||
@@ -82,8 +87,6 @@ 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 inpaint(int idx, Mat &frame, Mat &mask) = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int radius_;
|
int radius_;
|
||||||
MotionModel motionModel_;
|
MotionModel motionModel_;
|
||||||
|
@@ -184,6 +184,8 @@ private:
|
|||||||
|
|
||||||
int frameCount_;
|
int frameCount_;
|
||||||
bool isPrePassDone_;
|
bool isPrePassDone_;
|
||||||
|
bool doWobbleSuppression_;
|
||||||
|
std::vector<Mat> motions2_;
|
||||||
Mat suppressedFrame_;
|
Mat suppressedFrame_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -46,6 +46,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "opencv2/core/core.hpp"
|
#include "opencv2/core/core.hpp"
|
||||||
#include "opencv2/videostab/global_motion.hpp"
|
#include "opencv2/videostab/global_motion.hpp"
|
||||||
|
#include "opencv2/videostab/log.hpp"
|
||||||
|
|
||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
@@ -55,33 +56,48 @@ namespace videostab
|
|||||||
class CV_EXPORTS WobbleSuppressorBase
|
class CV_EXPORTS WobbleSuppressorBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
WobbleSuppressorBase();
|
||||||
|
|
||||||
virtual ~WobbleSuppressorBase() {}
|
virtual ~WobbleSuppressorBase() {}
|
||||||
|
|
||||||
virtual void setFrames(const std::vector<Mat> &val) { frames_ = &val; }
|
void setMotionEstimator(Ptr<GlobalMotionEstimatorBase> val) { motionEstimator_ = val; }
|
||||||
virtual const std::vector<Mat>& frames() const { return *frames_; }
|
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 void setMotions(const std::vector<Mat> &val) { motions_ = &val; }
|
||||||
virtual const std::vector<Mat>& motions() const { return *motions_; }
|
virtual const std::vector<Mat>& motions() const { return *motions_; }
|
||||||
|
|
||||||
virtual void setStabilizedFrames(const std::vector<Mat> &val) { stabilizedFrames_ = &val; }
|
virtual void setMotions2(const std::vector<Mat> &val) { motions2_ = &val; }
|
||||||
virtual const std::vector<Mat>& stabilizedFrames() const { return *stabilizedFrames_; }
|
virtual const std::vector<Mat>& motions2() const { return *motions2_; }
|
||||||
|
|
||||||
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 suppress(int idx, Mat &frame) = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const std::vector<Mat> *frames_;
|
Ptr<GlobalMotionEstimatorBase> motionEstimator_;
|
||||||
|
int frameCount_;
|
||||||
const std::vector<Mat> *motions_;
|
const std::vector<Mat> *motions_;
|
||||||
const std::vector<Mat> *stabilizedFrames_;
|
const std::vector<Mat> *motions2_;
|
||||||
const std::vector<Mat> *stabilizationMotions_;
|
const std::vector<Mat> *stabilizationMotions_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CV_EXPORTS NullWobbleSuppressor : public WobbleSuppressorBase
|
class CV_EXPORTS NullWobbleSuppressor : public WobbleSuppressorBase
|
||||||
{
|
{
|
||||||
public:
|
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
|
} // 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()
|
PyrLkRobustMotionEstimator::PyrLkRobustMotionEstimator()
|
||||||
: ransacParams_(RansacParams::affine2dMotionStd())
|
: ransacParams_(RansacParams::affine2dMotionStd())
|
||||||
{
|
{
|
||||||
|
@@ -53,7 +53,7 @@ namespace videostab
|
|||||||
|
|
||||||
StabilizerBase::StabilizerBase()
|
StabilizerBase::StabilizerBase()
|
||||||
{
|
{
|
||||||
setLog(new NullLog());
|
setLog(new LogToStdout());
|
||||||
setFrameSource(new NullFrameSource());
|
setFrameSource(new NullFrameSource());
|
||||||
setMotionEstimator(new PyrLkRobustMotionEstimator());
|
setMotionEstimator(new PyrLkRobustMotionEstimator());
|
||||||
setDeblurer(new NullDeblurer());
|
setDeblurer(new NullDeblurer());
|
||||||
@@ -304,6 +304,8 @@ void TwoPassStabilizer::reset()
|
|||||||
StabilizerBase::reset();
|
StabilizerBase::reset();
|
||||||
frameCount_ = 0;
|
frameCount_ = 0;
|
||||||
isPrePassDone_ = false;
|
isPrePassDone_ = false;
|
||||||
|
doWobbleSuppression_ = false;
|
||||||
|
motions2_.clear();
|
||||||
suppressedFrame_ = Mat();
|
suppressedFrame_ = Mat();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,10 +335,20 @@ void TwoPassStabilizer::runPrePassIfNecessary()
|
|||||||
|
|
||||||
Mat prevFrame, frame;
|
Mat prevFrame, frame;
|
||||||
|
|
||||||
|
WobbleSuppressorBase *wobbleSuppressor = static_cast<WobbleSuppressorBase*>(wobbleSuppressor_);
|
||||||
|
doWobbleSuppression_ = dynamic_cast<NullWobbleSuppressor*>(wobbleSuppressor) == 0;
|
||||||
|
|
||||||
while (!(frame = frameSource_->nextFrame()).empty())
|
while (!(frame = frameSource_->nextFrame()).empty())
|
||||||
{
|
{
|
||||||
if (frameCount_ > 0)
|
if (frameCount_ > 0)
|
||||||
|
{
|
||||||
motions_.push_back(motionEstimator_->estimate(prevFrame, frame));
|
motions_.push_back(motionEstimator_->estimate(prevFrame, frame));
|
||||||
|
if (doWobbleSuppression_)
|
||||||
|
{
|
||||||
|
motions2_.push_back(
|
||||||
|
wobbleSuppressor_->motionEstimator()->estimate(prevFrame, frame));
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
frameSize_ = frame.size();
|
frameSize_ = frame.size();
|
||||||
@@ -386,10 +398,15 @@ void TwoPassStabilizer::setUp(const Mat &firstFrame)
|
|||||||
for (int i = -radius_; i <= 0; ++i)
|
for (int i = -radius_; i <= 0; ++i)
|
||||||
at(i, frames_) = firstFrame;
|
at(i, frames_) = firstFrame;
|
||||||
|
|
||||||
wobbleSuppressor_->setFrames(frames_);
|
WobbleSuppressorBase *wobbleSuppressor = static_cast<WobbleSuppressorBase*>(wobbleSuppressor_);
|
||||||
wobbleSuppressor_->setMotions(motions_);
|
doWobbleSuppression_ = dynamic_cast<NullWobbleSuppressor*>(wobbleSuppressor) == 0;
|
||||||
wobbleSuppressor_->setStabilizedFrames(stabilizedFrames_);
|
if (doWobbleSuppression_)
|
||||||
wobbleSuppressor_->setStabilizationMotions(stabilizationMotions_);
|
{
|
||||||
|
wobbleSuppressor_->setFrameCount(frameCount_);
|
||||||
|
wobbleSuppressor_->setMotions(motions_);
|
||||||
|
wobbleSuppressor_->setMotions2(motions2_);
|
||||||
|
wobbleSuppressor_->setStabilizationMotions(stabilizationMotions_);
|
||||||
|
}
|
||||||
|
|
||||||
StabilizerBase::setUp(firstFrame);
|
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_);
|
return StabilizerBase::postProcessFrame(suppressedFrame_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -51,9 +51,30 @@ namespace cv
|
|||||||
namespace videostab
|
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
|
} // namespace videostab
|
||||||
|
@@ -29,43 +29,6 @@ void run();
|
|||||||
void saveMotionsIfNecessary();
|
void saveMotionsIfNecessary();
|
||||||
void printHelp();
|
void printHelp();
|
||||||
|
|
||||||
class GlobalMotionReader : public GlobalMotionEstimatorBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GlobalMotionReader(string path)
|
|
||||||
{
|
|
||||||
ifstream f(path.c_str());
|
|
||||||
if (!f.is_open())
|
|
||||||
throw runtime_error("can't open motions file: " + path);
|
|
||||||
int size; f >> size;
|
|
||||||
motions_.resize(size);
|
|
||||||
for (int i = 0; i < size; ++i)
|
|
||||||
{
|
|
||||||
Mat_<float> M(3, 3);
|
|
||||||
for (int l = 0; l < 3; ++l)
|
|
||||||
for (int s = 0; s < 3; ++s)
|
|
||||||
f >> M(l,s);
|
|
||||||
motions_[i] = M;
|
|
||||||
}
|
|
||||||
pos_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Mat estimate(const Mat &/*frame0*/, const Mat &/*frame1*/)
|
|
||||||
{
|
|
||||||
if (pos_ >= motions_.size())
|
|
||||||
{
|
|
||||||
stringstream text;
|
|
||||||
text << "can't load motion between frames " << pos_ << " and " << pos_+1;
|
|
||||||
throw runtime_error(text.str());
|
|
||||||
}
|
|
||||||
return motions_[pos_++];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
vector<Mat> motions_;
|
|
||||||
size_t pos_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
@@ -76,8 +39,6 @@ void run()
|
|||||||
while (!(stabilizedFrame = stabilizedFrames->nextFrame()).empty())
|
while (!(stabilizedFrame = stabilizedFrames->nextFrame()).empty())
|
||||||
{
|
{
|
||||||
nframes++;
|
nframes++;
|
||||||
if (!saveMotionsPath.empty())
|
|
||||||
saveMotionsIfNecessary();
|
|
||||||
if (!outputPath.empty())
|
if (!outputPath.empty())
|
||||||
{
|
{
|
||||||
if (!writer.isOpened())
|
if (!writer.isOpened())
|
||||||
@@ -99,33 +60,6 @@ void run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void saveMotionsIfNecessary()
|
|
||||||
{
|
|
||||||
static bool areMotionsSaved = false;
|
|
||||||
if (!areMotionsSaved)
|
|
||||||
{
|
|
||||||
IFrameSource *frameSource = static_cast<IFrameSource*>(stabilizedFrames);
|
|
||||||
TwoPassStabilizer *twoPassStabilizer = dynamic_cast<TwoPassStabilizer*>(frameSource);
|
|
||||||
if (twoPassStabilizer)
|
|
||||||
{
|
|
||||||
ofstream f(saveMotionsPath.c_str());
|
|
||||||
const vector<Mat> &motions = twoPassStabilizer->motions();
|
|
||||||
f << motions.size() << endl;
|
|
||||||
for (size_t i = 0; i < motions.size(); ++i)
|
|
||||||
{
|
|
||||||
Mat_<float> M = motions[i];
|
|
||||||
for (int l = 0, k = 0; l < 3; ++l)
|
|
||||||
for (int s = 0; s < 3; ++s, ++k)
|
|
||||||
f << M(l,s) << " ";
|
|
||||||
f << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
areMotionsSaved = true;
|
|
||||||
cout << "motions are saved";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void printHelp()
|
void printHelp()
|
||||||
{
|
{
|
||||||
cout << "OpenCV video stabilizer.\n"
|
cout << "OpenCV video stabilizer.\n"
|
||||||
@@ -173,6 +107,8 @@ void printHelp()
|
|||||||
" --color-inpaint-radius=<float_number>\n"
|
" --color-inpaint-radius=<float_number>\n"
|
||||||
" Set color inpainting radius (for ns and telea options only).\n"
|
" Set color inpainting radius (for ns and telea options only).\n"
|
||||||
" The default is 2.0\n\n"
|
" The default is 2.0\n\n"
|
||||||
|
" --wobble-suppress=(yes|no)\n"
|
||||||
|
" Perform wobble suppression. The default is no.\n\n"
|
||||||
" -o, --output=(no|<file_path>)\n"
|
" -o, --output=(no|<file_path>)\n"
|
||||||
" Set output file path explicitely. The default is stabilized.avi.\n"
|
" Set output file path explicitely. The default is stabilized.avi.\n"
|
||||||
" --fps=(<int_number>|auto)\n"
|
" --fps=(<int_number>|auto)\n"
|
||||||
@@ -210,6 +146,7 @@ int main(int argc, const char **argv)
|
|||||||
"{ | dist-thresh | 5.0 | }"
|
"{ | dist-thresh | 5.0 | }"
|
||||||
"{ | color-inpaint | no | }"
|
"{ | color-inpaint | no | }"
|
||||||
"{ | color-inpaint-radius | 2 | }"
|
"{ | color-inpaint-radius | 2 | }"
|
||||||
|
"{ | wobble-suppress | no | }"
|
||||||
"{ o | output | stabilized.avi | }"
|
"{ o | output | stabilized.avi | }"
|
||||||
"{ | fps | auto | }"
|
"{ | fps | auto | }"
|
||||||
"{ q | quiet | false | }"
|
"{ q | quiet | false | }"
|
||||||
@@ -226,7 +163,9 @@ int main(int argc, const char **argv)
|
|||||||
|
|
||||||
StabilizerBase *stabilizer;
|
StabilizerBase *stabilizer;
|
||||||
|
|
||||||
bool isTwoPass = arg("est-trim") == "yes" || arg("save-motions") != "no";
|
bool isTwoPass =
|
||||||
|
arg("est-trim") == "yes" || arg("wobble-suppress") == "yes";
|
||||||
|
|
||||||
if (isTwoPass)
|
if (isTwoPass)
|
||||||
{
|
{
|
||||||
TwoPassStabilizer *twoPassStabilizer = new TwoPassStabilizer();
|
TwoPassStabilizer *twoPassStabilizer = new TwoPassStabilizer();
|
||||||
@@ -236,6 +175,19 @@ int main(int argc, const char **argv)
|
|||||||
twoPassStabilizer->setMotionStabilizer(new GaussianMotionFilter(argi("radius")));
|
twoPassStabilizer->setMotionStabilizer(new GaussianMotionFilter(argi("radius")));
|
||||||
else
|
else
|
||||||
twoPassStabilizer->setMotionStabilizer(new GaussianMotionFilter(argi("radius"), argf("stdev")));
|
twoPassStabilizer->setMotionStabilizer(new GaussianMotionFilter(argi("radius"), argf("stdev")));
|
||||||
|
if (arg("wobble-suppress") == "yes")
|
||||||
|
{
|
||||||
|
twoPassStabilizer->setWobbleSuppressor(new MoreAccurateMotionWobbleSuppressor());
|
||||||
|
if (arg("load-motions") != "no")
|
||||||
|
twoPassStabilizer->wobbleSuppressor()->setMotionEstimator(
|
||||||
|
new FromFileMotionReader("motions2." + arg("load-motions")));
|
||||||
|
if (arg("save-motions") != "no")
|
||||||
|
{
|
||||||
|
Ptr<GlobalMotionEstimatorBase> est = twoPassStabilizer->wobbleSuppressor()->motionEstimator();
|
||||||
|
twoPassStabilizer->wobbleSuppressor()->setMotionEstimator(
|
||||||
|
new ToFileMotionWriter("motions2." + arg("save-motions"), est));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -289,10 +241,11 @@ int main(int argc, const char **argv)
|
|||||||
stabilizer->setMotionEstimator(est_);
|
stabilizer->setMotionEstimator(est_);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
stabilizer->setMotionEstimator(new GlobalMotionReader(arg("load-motions")));
|
stabilizer->setMotionEstimator(new FromFileMotionReader("motions." + arg("load-motions")));
|
||||||
|
|
||||||
if (arg("save-motions") != "no")
|
if (arg("save-motions") != "no")
|
||||||
saveMotionsPath = arg("save-motions");
|
stabilizer->setMotionEstimator(
|
||||||
|
new ToFileMotionWriter("motions." + arg("save-motions"), stabilizer->motionEstimator()));
|
||||||
|
|
||||||
stabilizer->setRadius(argi("radius"));
|
stabilizer->setRadius(argi("radius"));
|
||||||
if (arg("deblur") == "yes")
|
if (arg("deblur") == "yes")
|
||||||
@@ -342,9 +295,7 @@ int main(int argc, const char **argv)
|
|||||||
{
|
{
|
||||||
inpainters->setRadius(argi("radius"));
|
inpainters->setRadius(argi("radius"));
|
||||||
stabilizer->setInpainter(inpainters_);
|
stabilizer->setInpainter(inpainters_);
|
||||||
}
|
}
|
||||||
|
|
||||||
stabilizer->setLog(new LogToStdout());
|
|
||||||
|
|
||||||
if (arg("output") != "no")
|
if (arg("output") != "no")
|
||||||
outputPath = arg("output");
|
outputPath = arg("output");
|
||||||
|
Reference in New Issue
Block a user