Commit 56b5e6d8 authored by Alexey Spizhevoy's avatar Alexey Spizhevoy

Updated videostab module

parent abbfa848
...@@ -76,7 +76,9 @@ public: ...@@ -76,7 +76,9 @@ public:
virtual void reset(); virtual void reset();
virtual Mat nextFrame(); virtual Mat nextFrame();
int frameCount() { return static_cast<int>(reader_.get(CV_CAP_PROP_FRAME_COUNT)); } int width() { return static_cast<int>(reader_.get(CV_CAP_PROP_FRAME_WIDTH)); }
int height() { return static_cast<int>(reader_.get(CV_CAP_PROP_FRAME_HEIGHT)); }
int count() { return static_cast<int>(reader_.get(CV_CAP_PROP_FRAME_COUNT)); }
double fps() { return reader_.get(CV_CAP_PROP_FPS); } double fps() { return reader_.get(CV_CAP_PROP_FPS); }
private: private:
......
...@@ -54,46 +54,31 @@ namespace videostab ...@@ -54,46 +54,31 @@ namespace videostab
class CV_EXPORTS IMotionStabilizer class CV_EXPORTS IMotionStabilizer
{ {
public: public:
virtual ~IMotionStabilizer() {}
virtual void stabilize(const Mat *motions, int size, Mat *stabilizationMotions) const = 0; virtual void stabilize(const Mat *motions, int size, Mat *stabilizationMotions) const = 0;
}; };
class CV_EXPORTS MotionFilterBase : public IMotionStabilizer class CV_EXPORTS MotionFilterBase : public IMotionStabilizer
{ {
public: public:
MotionFilterBase() : radius_(0) {}
virtual ~MotionFilterBase() {} virtual ~MotionFilterBase() {}
virtual void setRadius(int val) { radius_ = val; }
virtual int radius() const { return radius_; }
virtual void update() {}
virtual Mat stabilize(int index, const Mat *motions, int size) const = 0; virtual Mat stabilize(int index, const Mat *motions, int size) const = 0;
virtual void stabilize(const Mat *motions, int size, Mat *stabilizationMotions) const; virtual void stabilize(const Mat *motions, int size, Mat *stabilizationMotions) const;
protected:
int radius_;
}; };
class CV_EXPORTS GaussianMotionFilter : public MotionFilterBase class CV_EXPORTS GaussianMotionFilter : public MotionFilterBase
{ {
public: public:
GaussianMotionFilter() : stdev_(-1.f) {} GaussianMotionFilter(int radius = 15, float stdev = -1.f) { setParams(radius, stdev); }
GaussianMotionFilter(int radius, float stdev = -1.f)
{
setRadius(radius);
setStdev(stdev);
update();
}
void setStdev(float val) { stdev_ = val; } void setParams(int radius, float stdev = -1.f);
int radius() const { return radius_; }
float stdev() const { return stdev_; } float stdev() const { return stdev_; }
virtual void update();
virtual Mat stabilize(int index, const Mat *motions, int size) const; virtual Mat stabilize(int index, const Mat *motions, int size) const;
private: private:
int radius_;
float stdev_; float stdev_;
std::vector<float> weight_; std::vector<float> weight_;
}; };
......
...@@ -136,12 +136,10 @@ public: ...@@ -136,12 +136,10 @@ 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() { resetImpl(); } virtual void reset();
virtual Mat nextFrame() { return nextStabilizedFrame(); } virtual Mat nextFrame() { return nextStabilizedFrame(); }
private: private:
void resetImpl();
virtual void setUp(Mat &firstFrame); virtual void setUp(Mat &firstFrame);
virtual void estimateMotion(); virtual void estimateMotion();
virtual void stabilizeFrame(); virtual void stabilizeFrame();
......
...@@ -58,13 +58,15 @@ void MotionFilterBase::stabilize(const Mat *motions, int size, Mat *stabilizatio ...@@ -58,13 +58,15 @@ void MotionFilterBase::stabilize(const Mat *motions, int size, Mat *stabilizatio
} }
void GaussianMotionFilter::update() void GaussianMotionFilter::setParams(int radius, float stdev)
{ {
float sigma = stdev_ > 0.f ? stdev_ : sqrt(static_cast<float>(radius_)); radius_ = radius;
stdev_ = stdev > 0.f ? stdev : sqrt(static_cast<float>(radius_));
float sum = 0; float sum = 0;
weight_.resize(2*radius_ + 1); weight_.resize(2*radius_ + 1);
for (int i = -radius_; i <= radius_; ++i) for (int i = -radius_; i <= radius_; ++i)
sum += weight_[radius_ + i] = std::exp(-i*i/(sigma*sigma)); sum += weight_[radius_ + i] = std::exp(-i*i/(stdev_*stdev_));
for (int i = -radius_; i <= radius_; ++i) for (int i = -radius_; i <= radius_; ++i)
weight_[radius_ + i] /= sum; weight_[radius_ + i] /= sum;
} }
......
...@@ -199,11 +199,11 @@ void StabilizerBase::stabilizeFrame(const Mat &stabilizationMotion) ...@@ -199,11 +199,11 @@ void StabilizerBase::stabilizeFrame(const Mat &stabilizationMotion)
OnePassStabilizer::OnePassStabilizer() OnePassStabilizer::OnePassStabilizer()
{ {
setMotionFilter(new GaussianMotionFilter()); setMotionFilter(new GaussianMotionFilter());
resetImpl(); reset();
} }
void OnePassStabilizer::resetImpl() void OnePassStabilizer::reset()
{ {
curPos_ = -1; curPos_ = -1;
curStabilizedPos_ = -1; curStabilizedPos_ = -1;
...@@ -238,8 +238,6 @@ void OnePassStabilizer::setUp(Mat &firstFrame) ...@@ -238,8 +238,6 @@ void OnePassStabilizer::setUp(Mat &firstFrame)
at(0, frames_) = firstFrame; at(0, frames_) = firstFrame;
motionFilter_->update();
StabilizerBase::setUp(cacheSize, firstFrame); StabilizerBase::setUp(cacheSize, firstFrame);
} }
...@@ -327,11 +325,6 @@ void TwoPassStabilizer::runPrePassIfNecessary() ...@@ -327,11 +325,6 @@ void TwoPassStabilizer::runPrePassIfNecessary()
motions_.push_back(Mat::eye(3, 3, CV_32F)); motions_.push_back(Mat::eye(3, 3, CV_32F));
log_->print("\n"); log_->print("\n");
IMotionStabilizer *motionStabilizer = static_cast<IMotionStabilizer*>(motionStabilizer_);
MotionFilterBase *motionFilterBase = dynamic_cast<MotionFilterBase*>(motionStabilizer);
if (motionFilterBase)
motionFilterBase->update();
stabilizationMotions_.resize(frameCount_); stabilizationMotions_.resize(frameCount_);
motionStabilizer_->stabilize(&motions_[0], frameCount_, &stabilizationMotions_[0]); motionStabilizer_->stabilize(&motions_[0], frameCount_, &stabilizationMotions_[0]);
......
...@@ -148,7 +148,7 @@ void printHelp() ...@@ -148,7 +148,7 @@ void printHelp()
" --deblur-sens=<float_number>\n" " --deblur-sens=<float_number>\n"
" Set deblurring sensitivity (from 0 to +inf). The default is 0.1.\n\n" " Set deblurring sensitivity (from 0 to +inf). The default is 0.1.\n\n"
" -t, --trim-ratio=<float_number>\n" " -t, --trim-ratio=<float_number>\n"
" Set trimming ratio (from 0 to 0.5). The default is 0.0.\n" " Set trimming ratio (from 0 to 0.5). The default is 0.1.\n"
" --est-trim=(yes|no)\n" " --est-trim=(yes|no)\n"
" Estimate trim ratio automatically. The default is yes (that leads to two passes,\n" " Estimate trim ratio automatically. The default is yes (that leads to two passes,\n"
" you can turn it off if you want to use one pass only).\n" " you can turn it off if you want to use one pass only).\n"
...@@ -197,7 +197,7 @@ int main(int argc, const char **argv) ...@@ -197,7 +197,7 @@ int main(int argc, const char **argv)
"{ | deblur | no | }" "{ | deblur | no | }"
"{ | deblur-sens | 0.1 | }" "{ | deblur-sens | 0.1 | }"
"{ | est-trim | yes | }" "{ | est-trim | yes | }"
"{ t | trim-ratio | 0.0 | }" "{ t | trim-ratio | 0.1 | }"
"{ | incl-constr | no | }" "{ | incl-constr | no | }"
"{ | border-mode | replicate | }" "{ | border-mode | replicate | }"
"{ | mosaic | no | }" "{ | mosaic | no | }"
...@@ -248,7 +248,7 @@ int main(int argc, const char **argv) ...@@ -248,7 +248,7 @@ int main(int argc, const char **argv)
if (inputPath.empty()) throw runtime_error("specify video file path"); if (inputPath.empty()) throw runtime_error("specify video file path");
VideoFileSource *source = new VideoFileSource(inputPath); VideoFileSource *source = new VideoFileSource(inputPath);
cout << "frame count: " << source->frameCount() << endl; cout << "frame count: " << source->count() << endl;
if (arg("fps") == "auto") outputFps = source->fps(); else outputFps = argd("fps"); if (arg("fps") == "auto") outputFps = source->fps(); else outputFps = argd("fps");
stabilizer->setFrameSource(source); stabilizer->setFrameSource(source);
......
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