Added timing for main steps (videostab)
authorAlexey Spizhevoy <no@email>
Thu, 19 Apr 2012 09:29:13 +0000 (09:29 +0000)
committerAlexey Spizhevoy <no@email>
Thu, 19 Apr 2012 09:29:13 +0000 (09:29 +0000)
modules/videostab/include/opencv2/videostab/stabilizer.hpp
modules/videostab/src/stabilizer.cpp
samples/cpp/videostab.cpp

index a14fbb6..3d46620 100644 (file)
@@ -44,6 +44,7 @@
 #define __OPENCV_VIDEOSTAB_STABILIZER_HPP__
 
 #include <vector>
+#include <ctime>
 #include "opencv2/core/core.hpp"
 #include "opencv2/imgproc/imgproc.hpp"
 #include "opencv2/videostab/global_motion.hpp"
@@ -102,6 +103,7 @@ protected:
     virtual Mat estimateStabilizationMotion() = 0;
     void stabilizeFrame();
     virtual Mat postProcessFrame(const Mat &frame);
+    void logProcessingTime();
 
     Ptr<ILog> log_;
     Ptr<IFrameSource> frameSource_;
@@ -128,6 +130,7 @@ protected:
     std::vector<Mat> stabilizedFrames_;
     std::vector<Mat> stabilizedMasks_;
     std::vector<Mat> stabilizationMotions_;
+    clock_t processingStartTime_;
 };
 
 class CV_EXPORTS OnePassStabilizer : public StabilizerBase, public IFrameSource
index 43b9528..d619d85 100644 (file)
@@ -44,6 +44,9 @@
 #include "opencv2/videostab/stabilizer.hpp"
 #include "opencv2/videostab/ring_buffer.hpp"
 
+// for debug purposes
+#define SAVE_MOTIONS 0
+
 using namespace std;
 
 namespace cv
@@ -81,6 +84,7 @@ void StabilizerBase::reset()
     stabilizedFrames_.clear();
     stabilizedMasks_.clear();
     stabilizationMotions_.clear();
+    processingStartTime_ = 0;
 }
 
 
@@ -88,15 +92,21 @@ Mat StabilizerBase::nextStabilizedFrame()
 {
     // check if we've processed all frames already
     if (curStabilizedPos_ == curPos_ && curStabilizedPos_ != -1)
+    {
+        logProcessingTime();
         return Mat();
+    }
 
     bool processed;
     do processed = doOneIteration();
     while (processed && curStabilizedPos_ == -1);
 
-    // check if frame source is empty
+    // check if the frame source is empty
     if (curStabilizedPos_ == -1)
+    {
+        logProcessingTime();
         return Mat();
+    }
 
     return postProcessFrame(at(curStabilizedPos_, stabilizedFrames_));
 }
@@ -173,6 +183,7 @@ void StabilizerBase::setUp(const Mat &firstFrame)
     }
 
     log_->print("processing frames");
+    processingStartTime_ = clock();
 }
 
 
@@ -234,6 +245,13 @@ Mat StabilizerBase::postProcessFrame(const Mat &frame)
 }
 
 
+void StabilizerBase::logProcessingTime()
+{
+    clock_t elapsedTime = clock() - processingStartTime_;
+    log_->print("\nprocessing time: %.3f sec\n", static_cast<double>(elapsedTime) / CLOCKS_PER_SEC);
+}
+
+
 OnePassStabilizer::OnePassStabilizer()
 {
     setMotionFilter(new GaussianMotionFilter());
@@ -317,22 +335,55 @@ Mat TwoPassStabilizer::nextFrame()
 }
 
 
-void TwoPassStabilizer::runPrePassIfNecessary()
+#if SAVE_MOTIONS
+static void saveMotions(
+        int frameCount, const vector<Mat> &motions, const vector<Mat> &stabilizationMotions)
 {
-    if (!isPrePassDone_)
+    ofstream fm("log_motions.csv");
+    for (int i = 0; i < frameCount - 1; ++i)
     {
-        clock_t startTime = clock();
-        log_->print("first pass: estimating motions");
+        Mat_<float> M = at(i, motions);
+        fm << 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;
+    }
+    ofstream fo("log_orig.csv");
+    for (int i = 0; i < frameCount; ++i)
+    {
+        Mat_<float> M = getMotion(0, i, motions);
+        fo << 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;
+    }
+    ofstream fs("log_stab.csv");
+    for (int i = 0; i < frameCount; ++i)
+    {
+        Mat_<float> M = stabilizationMotions[i] * getMotion(0, i, motions);
+        fs << 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;
+    }
+}
+#endif
 
-        Mat prevFrame, frame;
+
+void TwoPassStabilizer::runPrePassIfNecessary()
+{
+    if (!isPrePassDone_)
+    {        
+        // check if we must do wobble suppression
 
         WobbleSuppressorBase *wobbleSuppressor = static_cast<WobbleSuppressorBase*>(wobbleSuppressor_);
         doWobbleSuppression_ = dynamic_cast<NullWobbleSuppressor*>(wobbleSuppressor) == 0;
 
-        bool ok = true, ok2 = true;
-
         // estimate motions
 
+        clock_t startTime = clock();
+        log_->print("first pass: estimating motions");
+
+        Mat prevFrame, frame;
+        bool ok = true, ok2 = true;
+
         while (!(frame = frameSource_->nextFrame()).empty())
         {
             if (frameCount_ > 0)
@@ -366,44 +417,26 @@ void TwoPassStabilizer::runPrePassIfNecessary()
             frameCount_++;
         }
 
+        clock_t elapsedTime = clock() - startTime;
+        log_->print("\nmotion estimation time: %.3f sec\n",
+                    static_cast<double>(elapsedTime) / CLOCKS_PER_SEC);
+
         // add aux. motions
 
         for (int i = 0; i < radius_; ++i)
             motions_.push_back(Mat::eye(3, 3, CV_32F));
-        log_->print("\n");
 
         // stabilize
 
+        startTime = clock();
+
         stabilizationMotions_.resize(frameCount_);
         motionStabilizer_->stabilize(
             frameCount_, motions_, make_pair(0, frameCount_ - 1), &stabilizationMotions_[0]);
 
-        // save motions
-
-        /*ofstream fm("log_motions.csv");
-        for (int i = 0; i < frameCount_ - 1; ++i)
-        {
-            Mat_<float> M = at(i, motions_);
-            fm << 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;
-        }
-        ofstream fo("log_orig.csv");
-        for (int i = 0; i < frameCount_; ++i)
-        {
-            Mat_<float> M = getMotion(0, i, motions_);
-            fo << 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;
-        }
-        ofstream fs("log_stab.csv");
-        for (int i = 0; i < frameCount_; ++i)
-        {
-            Mat_<float> M = stabilizationMotions_[i] * getMotion(0, i, motions_);
-            fs << 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;
-        }*/
+        elapsedTime = clock() - startTime;
+        log_->print("motion stabilization time: %.3f sec\n",
+                    static_cast<double>(elapsedTime) / CLOCKS_PER_SEC);
 
         // estimate optimal trim ratio if necessary
 
@@ -418,11 +451,12 @@ void TwoPassStabilizer::runPrePassIfNecessary()
             log_->print("estimated trim ratio: %f\n", static_cast<double>(trimRatio_));
         }
 
+#if SAVE_MOTIONS
+        saveMotions(frameCount_, motions_, stabilizationMotions_);
+#endif
+
         isPrePassDone_ = true;
         frameSource_->reset();
-
-        clock_t elapsedTime = clock() - startTime;
-        log_->print("first pass time: %.3f sec\n", static_cast<double>(elapsedTime) / CLOCKS_PER_SEC);
     }
 }
 
index 07acbd9..320a9d2 100644 (file)
@@ -37,26 +37,30 @@ void run()
     Mat stabilizedFrame;
     int nframes = 0;
 
+    // for each stabilized frame
     while (!(stabilizedFrame = stabilizedFrames->nextFrame()).empty())
     {
         nframes++;
+
+        // init writer (once) and save stabilized frame
         if (!outputPath.empty())
         {
             if (!writer.isOpened())
-                writer.open(outputPath, CV_FOURCC('X','V','I','D'), outputFps, stabilizedFrame.size());
+                writer.open(outputPath, CV_FOURCC('X','V','I','D'),
+                            outputFps, stabilizedFrame.size());
             writer << stabilizedFrame;
         }
+
+        // show stabilized frame
         if (!quietMode)
         {
             imshow("stabilizedFrame", stabilizedFrame);
             char key = static_cast<char>(waitKey(3));
-            if (key == 27)
-                break;
+            if (key == 27) { cout << endl; break; }
         }
     }
 
-    cout << endl
-         << "processed frames: " << nframes << endl
+    cout << "processed frames: " << nframes << endl
          << "finished\n";
 }