From: Alexey Spizhevoy Date: Thu, 19 Apr 2012 09:29:13 +0000 (+0000) Subject: Added timing for main steps (videostab) X-Git-Tag: accepted/2.0/20130307.220821~364^2~903 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f42eea1029276b30f3c32fb60827fc7575e399a9;p=profile%2Fivi%2Fopencv.git Added timing for main steps (videostab) --- diff --git a/modules/videostab/include/opencv2/videostab/stabilizer.hpp b/modules/videostab/include/opencv2/videostab/stabilizer.hpp index a14fbb6..3d46620 100644 --- a/modules/videostab/include/opencv2/videostab/stabilizer.hpp +++ b/modules/videostab/include/opencv2/videostab/stabilizer.hpp @@ -44,6 +44,7 @@ #define __OPENCV_VIDEOSTAB_STABILIZER_HPP__ #include +#include #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 log_; Ptr frameSource_; @@ -128,6 +130,7 @@ protected: std::vector stabilizedFrames_; std::vector stabilizedMasks_; std::vector stabilizationMotions_; + clock_t processingStartTime_; }; class CV_EXPORTS OnePassStabilizer : public StabilizerBase, public IFrameSource diff --git a/modules/videostab/src/stabilizer.cpp b/modules/videostab/src/stabilizer.cpp index 43b9528..d619d85 100644 --- a/modules/videostab/src/stabilizer.cpp +++ b/modules/videostab/src/stabilizer.cpp @@ -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(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 &motions, const vector &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_ 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_ 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_ 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(wobbleSuppressor_); doWobbleSuppression_ = dynamic_cast(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(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_ 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_ 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_ 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(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(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(elapsedTime) / CLOCKS_PER_SEC); } } diff --git a/samples/cpp/videostab.cpp b/samples/cpp/videostab.cpp index 07acbd9..320a9d2 100644 --- a/samples/cpp/videostab.cpp +++ b/samples/cpp/videostab.cpp @@ -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(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"; }