From: Alexey Spizhevoy Date: Tue, 10 Apr 2012 10:33:19 +0000 (+0000) Subject: Minor fixes and updates in videostab module and sample X-Git-Tag: accepted/2.0/20130307.220821~364^2~934 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b549900fe190cd083778ae000206ffc360f91074;p=profile%2Fivi%2Fopencv.git Minor fixes and updates in videostab module and sample --- diff --git a/modules/videostab/include/opencv2/videostab/global_motion.hpp b/modules/videostab/include/opencv2/videostab/global_motion.hpp index 0089d71..bac16cf 100644 --- a/modules/videostab/include/opencv2/videostab/global_motion.hpp +++ b/modules/videostab/include/opencv2/videostab/global_motion.hpp @@ -101,7 +101,7 @@ public: virtual void setMotionModel(MotionModel val) { motionModel_ = val; } virtual MotionModel motionModel() const { return motionModel_; } - virtual Mat estimate(const Mat &frame0, const Mat &frame1) = 0; + virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) = 0; protected: MotionModel motionModel_; @@ -111,7 +111,7 @@ class CV_EXPORTS FromFileMotionReader : public GlobalMotionEstimatorBase { public: FromFileMotionReader(const std::string &path); - virtual Mat estimate(const Mat &frame0, const Mat &frame1); + virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0); private: std::ifstream file_; @@ -121,7 +121,7 @@ class CV_EXPORTS ToFileMotionWriter : public GlobalMotionEstimatorBase { public: ToFileMotionWriter(const std::string &path, Ptr estimator); - virtual Mat estimate(const Mat &frame0, const Mat &frame1); + virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0); private: std::ofstream file_; @@ -148,7 +148,7 @@ public: void setMinInlierRatio(float val) { minInlierRatio_ = val; } float minInlierRatio() const { return minInlierRatio_; } - virtual Mat estimate(const Mat &frame0, const Mat &frame1); + virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0); private: Ptr detector_; diff --git a/modules/videostab/src/global_motion.cpp b/modules/videostab/src/global_motion.cpp index eb0a47d..d8173c6 100644 --- a/modules/videostab/src/global_motion.cpp +++ b/modules/videostab/src/global_motion.cpp @@ -295,12 +295,14 @@ FromFileMotionReader::FromFileMotionReader(const string &path) } -Mat FromFileMotionReader::estimate(const Mat &/*frame0*/, const Mat &/*frame1*/) +Mat FromFileMotionReader::estimate(const Mat &/*frame0*/, const Mat &/*frame1*/, bool *ok) { Mat_ M(3, 3); + bool ok_; 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); + >> M(2,0) >> M(2,1) >> M(2,2) >> ok_; + if (ok) *ok = ok_; return M; } @@ -313,12 +315,14 @@ ToFileMotionWriter::ToFileMotionWriter(const string &path, Ptr M = estimator_->estimate(frame0, frame1); + bool ok_; + Mat_ M = estimator_->estimate(frame0, frame1, &ok_); 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; + << M(2,0) << " " << M(2,1) << " " << M(2,2) << " " << ok_ << endl; + if (ok) *ok = ok_; return M; } @@ -343,7 +347,7 @@ PyrLkRobustMotionEstimator::PyrLkRobustMotionEstimator(MotionModel model) } -Mat PyrLkRobustMotionEstimator::estimate(const Mat &frame0, const Mat &frame1) +Mat PyrLkRobustMotionEstimator::estimate(const Mat &frame0, const Mat &frame1, bool *ok) { detector_->detect(frame0, keypointsPrev_); @@ -402,8 +406,12 @@ Mat PyrLkRobustMotionEstimator::estimate(const Mat &frame0, const Mat &frame1) rmse = sqrt(rmse / static_cast(ninliers)); } + if (ok) *ok = true; if (rmse > maxRmse_ || static_cast(ninliers) / pointsGood_.size() < minInlierRatio_) + { M = Mat::eye(3, 3, CV_32F); + if (ok) *ok = false; + } return M; } diff --git a/modules/videostab/src/stabilizer.cpp b/modules/videostab/src/stabilizer.cpp index 728fae6..f7d8311 100644 --- a/modules/videostab/src/stabilizer.cpp +++ b/modules/videostab/src/stabilizer.cpp @@ -338,6 +338,7 @@ void TwoPassStabilizer::runPrePassIfNecessary() WobbleSuppressorBase *wobbleSuppressor = static_cast(wobbleSuppressor_); doWobbleSuppression_ = dynamic_cast(wobbleSuppressor) == 0; + bool okEst; while (!(frame = frameSource_->nextFrame()).empty()) { if (frameCount_ > 0) @@ -345,8 +346,11 @@ void TwoPassStabilizer::runPrePassIfNecessary() motions_.push_back(motionEstimator_->estimate(prevFrame, frame)); if (doWobbleSuppression_) { - motions2_.push_back( - wobbleSuppressor_->motionEstimator()->estimate(prevFrame, frame)); + Mat M = wobbleSuppressor_->motionEstimator()->estimate(prevFrame, frame, &okEst); + if (okEst) + motions2_.push_back(M); + else + motions2_.push_back(motions_.back()); } } else diff --git a/samples/cpp/videostab.cpp b/samples/cpp/videostab.cpp index b1e03ca..68c33ea 100644 --- a/samples/cpp/videostab.cpp +++ b/samples/cpp/videostab.cpp @@ -68,10 +68,9 @@ void printHelp() " -m, --model=(transl|transl_and_scale|linear_sim|affine|homography)\n" " Set motion model. The default is affine.\n" " --outlier-ratio=\n" - " Outliers ratio in motion estimation. The default is 0.5.\n" + " Motion estimation outlier ratio hypothesis. The default is 0.5." " --min-inlier-ratio=\n" - " Minimum inlier ratio to decide if estimated motion is OK. The default is 0.1,\n" - " but you may want to increase it.\n\n" + " Minimum inlier ratio to decide if estimated motion is OK. The default is 0.1.\n\n" " -sm, --save-motions=(|no)\n" " Save estimated motions into file. The default is no.\n" " -lm, --load-motions=(|no)\n" @@ -113,6 +112,10 @@ void printHelp() " --ws-model=(transl|transl_and_scale|linear_sim|affine|homography)\n" " Set wobble suppression motion model (must have more DOF than motion \n" " estimation model). The default is homography.\n" + " --ws-min-inlier-ratio=\n" + " Minimum inlier ratio to decide if estimated motion is OK. The default is 0.1.\n" + " --ws-outlier-ratio=\n" + " Motion estimation outlier ratio hypothesis. The default is 0.5.\n" " -sm2, --save-motions2=(|no)\n" " Save motions estimated for wobble suppression. The default is no.\n" " -lm2, --load-motions2=(|no)\n" @@ -157,6 +160,8 @@ int main(int argc, const char **argv) "{ ws | wobble-suppress | no | }" "{ | ws-period | 30 | }" "{ | ws-model | homography | }" + "{ | ws-min-inlier-ratio | 0.1 | }" + "{ | ws-outlier-ratio | 0.5 | }" "{ sm2 | save-motions2 | no | }" "{ lm2 | load-motions2 | no | }" "{ o | output | stabilized.avi | }" @@ -192,24 +197,41 @@ int main(int argc, const char **argv) MoreAccurateMotionWobbleSuppressor *ws = new MoreAccurateMotionWobbleSuppressor(); twoPassStabilizer->setWobbleSuppressor(ws); ws->setPeriod(argi("ws-period")); + + PyrLkRobustMotionEstimator *est = 0; + if (arg("ws-model") == "transl") - ws->setMotionEstimator(new PyrLkRobustMotionEstimator(TRANSLATION)); + est = new PyrLkRobustMotionEstimator(TRANSLATION); else if (arg("ws-model") == "transl_and_scale") - ws->setMotionEstimator(new PyrLkRobustMotionEstimator(TRANSLATION_AND_SCALE)); + est = new PyrLkRobustMotionEstimator(TRANSLATION_AND_SCALE); else if (arg("ws-model") == "linear_sim") - ws->setMotionEstimator(new PyrLkRobustMotionEstimator(LINEAR_SIMILARITY)); + est = new PyrLkRobustMotionEstimator(LINEAR_SIMILARITY); else if (arg("ws-model") == "affine") - ws->setMotionEstimator(new PyrLkRobustMotionEstimator(AFFINE)); + est = new PyrLkRobustMotionEstimator(AFFINE); else if (arg("ws-model") == "homography") - ws->setMotionEstimator(new PyrLkRobustMotionEstimator(HOMOGRAPHY)); + est = new PyrLkRobustMotionEstimator(HOMOGRAPHY); else + { + delete est; throw runtime_error("unknown wobble suppression motion model: " + arg("ws-model")); + } + + RansacParams ransac = est->ransacParams(); + ransac.eps = argf("ws-outlier-ratio"); + est->setRansacParams(ransac); + est->setMinInlierRatio(argf("ws-min-inlier-ratio")); + ws->setMotionEstimator(est); + + MotionModel model = est->motionModel(); if (arg("load-motions2") != "no") + { ws->setMotionEstimator(new FromFileMotionReader(arg("load-motions2"))); + ws->motionEstimator()->setMotionModel(model); + } if (arg("save-motions2") != "no") { - Ptr est = ws->motionEstimator(); - ws->setMotionEstimator(new ToFileMotionWriter(arg("save-motions2"), est)); + ws->setMotionEstimator(new ToFileMotionWriter(arg("save-motions2"), ws->motionEstimator())); + ws->motionEstimator()->setMotionModel(model); } } } @@ -233,6 +255,7 @@ int main(int argc, const char **argv) stabilizer->setFrameSource(source); PyrLkRobustMotionEstimator *est = 0; + if (arg("model") == "transl") est = new PyrLkRobustMotionEstimator(TRANSLATION); else if (arg("model") == "transl_and_scale") @@ -248,24 +271,22 @@ int main(int argc, const char **argv) delete est; throw runtime_error("unknown motion model: " + arg("model")); } + RansacParams ransac = est->ransacParams(); ransac.eps = argf("outlier-ratio"); est->setRansacParams(ransac); est->setMinInlierRatio(argf("min-inlier-ratio")); stabilizer->setMotionEstimator(est); + MotionModel model = stabilizer->motionEstimator()->motionModel(); if (arg("load-motions") != "no") { - MotionModel model = stabilizer->motionEstimator()->motionModel(); stabilizer->setMotionEstimator(new FromFileMotionReader(arg("load-motions"))); stabilizer->motionEstimator()->setMotionModel(model); } - if (arg("save-motions") != "no") { - MotionModel model = stabilizer->motionEstimator()->motionModel(); - stabilizer->setMotionEstimator( - new ToFileMotionWriter(arg("save-motions"), stabilizer->motionEstimator())); + stabilizer->setMotionEstimator(new ToFileMotionWriter(arg("save-motions"), stabilizer->motionEstimator())); stabilizer->motionEstimator()->setMotionModel(model); }