Added timing for main steps (videostab)
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if SAVE_MOTIONS
 | 
			
		||||
static void saveMotions(
 | 
			
		||||
        int frameCount, const vector<Mat> &motions, const vector<Mat> &stabilizationMotions)
 | 
			
		||||
{
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void TwoPassStabilizer::runPrePassIfNecessary()
 | 
			
		||||
{
 | 
			
		||||
    if (!isPrePassDone_)
 | 
			
		||||
    {
 | 
			
		||||
        clock_t startTime = clock();
 | 
			
		||||
        log_->print("first pass: estimating motions");
 | 
			
		||||
 | 
			
		||||
        Mat prevFrame, frame;
 | 
			
		||||
    {        
 | 
			
		||||
        // 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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user