Minor fixes and updates in videostab module and sample
authorAlexey Spizhevoy <no@email>
Tue, 10 Apr 2012 10:33:19 +0000 (10:33 +0000)
committerAlexey Spizhevoy <no@email>
Tue, 10 Apr 2012 10:33:19 +0000 (10:33 +0000)
modules/videostab/include/opencv2/videostab/global_motion.hpp
modules/videostab/src/global_motion.cpp
modules/videostab/src/stabilizer.cpp
samples/cpp/videostab.cpp

index 0089d71..bac16cf 100644 (file)
@@ -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<GlobalMotionEstimatorBase> 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<FeatureDetector> detector_;
index eb0a47d..d8173c6 100644 (file)
@@ -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_<float> 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<GlobalMotionEstim
 }
 
 
-Mat ToFileMotionWriter::estimate(const Mat &frame0, const Mat &frame1)
+Mat ToFileMotionWriter::estimate(const Mat &frame0, const Mat &frame1, bool *ok)
 {
-    Mat_<float> M = estimator_->estimate(frame0, frame1);
+    bool ok_;
+    Mat_<float> 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<float>(ninliers));
     }
 
+    if (ok) *ok = true;
     if (rmse > maxRmse_ || static_cast<float>(ninliers) / pointsGood_.size() < minInlierRatio_)
+    {
         M = Mat::eye(3, 3, CV_32F);
+        if (ok) *ok = false;
+    }
 
     return M;
 }
index 728fae6..f7d8311 100644 (file)
@@ -338,6 +338,7 @@ void TwoPassStabilizer::runPrePassIfNecessary()
         WobbleSuppressorBase *wobbleSuppressor = static_cast<WobbleSuppressorBase*>(wobbleSuppressor_);
         doWobbleSuppression_ = dynamic_cast<NullWobbleSuppressor*>(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
index b1e03ca..68c33ea 100644 (file)
@@ -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=<float_number>\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=<float_number>\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=(<file_path>|no)\n"
             "      Save estimated motions into file. The default is no.\n"
             "  -lm, --load-motions=(<file_path>|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=<float_number>\n"
+            "      Minimum inlier ratio to decide if estimated motion is OK. The default is 0.1.\n"
+            "  --ws-outlier-ratio=<float_number>\n"
+            "      Motion estimation outlier ratio hypothesis. The default is 0.5.\n"
             "  -sm2, --save-motions2=(<file_path>|no)\n"
             "      Save motions estimated for wobble suppression. The default is no.\n"
             "  -lm2, --load-motions2=(<file_path>|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<GlobalMotionEstimatorBase> 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);
         }