Added timing for main steps (videostab)
This commit is contained in:
parent
ada63d1800
commit
f42eea1029
@ -44,6 +44,7 @@
|
|||||||
#define __OPENCV_VIDEOSTAB_STABILIZER_HPP__
|
#define __OPENCV_VIDEOSTAB_STABILIZER_HPP__
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <ctime>
|
||||||
#include "opencv2/core/core.hpp"
|
#include "opencv2/core/core.hpp"
|
||||||
#include "opencv2/imgproc/imgproc.hpp"
|
#include "opencv2/imgproc/imgproc.hpp"
|
||||||
#include "opencv2/videostab/global_motion.hpp"
|
#include "opencv2/videostab/global_motion.hpp"
|
||||||
@ -102,6 +103,7 @@ protected:
|
|||||||
virtual Mat estimateStabilizationMotion() = 0;
|
virtual Mat estimateStabilizationMotion() = 0;
|
||||||
void stabilizeFrame();
|
void stabilizeFrame();
|
||||||
virtual Mat postProcessFrame(const Mat &frame);
|
virtual Mat postProcessFrame(const Mat &frame);
|
||||||
|
void logProcessingTime();
|
||||||
|
|
||||||
Ptr<ILog> log_;
|
Ptr<ILog> log_;
|
||||||
Ptr<IFrameSource> frameSource_;
|
Ptr<IFrameSource> frameSource_;
|
||||||
@ -128,6 +130,7 @@ protected:
|
|||||||
std::vector<Mat> stabilizedFrames_;
|
std::vector<Mat> stabilizedFrames_;
|
||||||
std::vector<Mat> stabilizedMasks_;
|
std::vector<Mat> stabilizedMasks_;
|
||||||
std::vector<Mat> stabilizationMotions_;
|
std::vector<Mat> stabilizationMotions_;
|
||||||
|
clock_t processingStartTime_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CV_EXPORTS OnePassStabilizer : public StabilizerBase, public IFrameSource
|
class CV_EXPORTS OnePassStabilizer : public StabilizerBase, public IFrameSource
|
||||||
|
@ -44,6 +44,9 @@
|
|||||||
#include "opencv2/videostab/stabilizer.hpp"
|
#include "opencv2/videostab/stabilizer.hpp"
|
||||||
#include "opencv2/videostab/ring_buffer.hpp"
|
#include "opencv2/videostab/ring_buffer.hpp"
|
||||||
|
|
||||||
|
// for debug purposes
|
||||||
|
#define SAVE_MOTIONS 0
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace cv
|
namespace cv
|
||||||
@ -81,6 +84,7 @@ void StabilizerBase::reset()
|
|||||||
stabilizedFrames_.clear();
|
stabilizedFrames_.clear();
|
||||||
stabilizedMasks_.clear();
|
stabilizedMasks_.clear();
|
||||||
stabilizationMotions_.clear();
|
stabilizationMotions_.clear();
|
||||||
|
processingStartTime_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -88,15 +92,21 @@ Mat StabilizerBase::nextStabilizedFrame()
|
|||||||
{
|
{
|
||||||
// check if we've processed all frames already
|
// check if we've processed all frames already
|
||||||
if (curStabilizedPos_ == curPos_ && curStabilizedPos_ != -1)
|
if (curStabilizedPos_ == curPos_ && curStabilizedPos_ != -1)
|
||||||
|
{
|
||||||
|
logProcessingTime();
|
||||||
return Mat();
|
return Mat();
|
||||||
|
}
|
||||||
|
|
||||||
bool processed;
|
bool processed;
|
||||||
do processed = doOneIteration();
|
do processed = doOneIteration();
|
||||||
while (processed && curStabilizedPos_ == -1);
|
while (processed && curStabilizedPos_ == -1);
|
||||||
|
|
||||||
// check if frame source is empty
|
// check if the frame source is empty
|
||||||
if (curStabilizedPos_ == -1)
|
if (curStabilizedPos_ == -1)
|
||||||
|
{
|
||||||
|
logProcessingTime();
|
||||||
return Mat();
|
return Mat();
|
||||||
|
}
|
||||||
|
|
||||||
return postProcessFrame(at(curStabilizedPos_, stabilizedFrames_));
|
return postProcessFrame(at(curStabilizedPos_, stabilizedFrames_));
|
||||||
}
|
}
|
||||||
@ -173,6 +183,7 @@ void StabilizerBase::setUp(const Mat &firstFrame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
log_->print("processing frames");
|
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()
|
OnePassStabilizer::OnePassStabilizer()
|
||||||
{
|
{
|
||||||
setMotionFilter(new GaussianMotionFilter());
|
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()
|
void TwoPassStabilizer::runPrePassIfNecessary()
|
||||||
{
|
{
|
||||||
if (!isPrePassDone_)
|
if (!isPrePassDone_)
|
||||||
{
|
{
|
||||||
clock_t startTime = clock();
|
// check if we must do wobble suppression
|
||||||
log_->print("first pass: estimating motions");
|
|
||||||
|
|
||||||
Mat prevFrame, frame;
|
|
||||||
|
|
||||||
WobbleSuppressorBase *wobbleSuppressor = static_cast<WobbleSuppressorBase*>(wobbleSuppressor_);
|
WobbleSuppressorBase *wobbleSuppressor = static_cast<WobbleSuppressorBase*>(wobbleSuppressor_);
|
||||||
doWobbleSuppression_ = dynamic_cast<NullWobbleSuppressor*>(wobbleSuppressor) == 0;
|
doWobbleSuppression_ = dynamic_cast<NullWobbleSuppressor*>(wobbleSuppressor) == 0;
|
||||||
|
|
||||||
bool ok = true, ok2 = true;
|
|
||||||
|
|
||||||
// estimate motions
|
// 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())
|
while (!(frame = frameSource_->nextFrame()).empty())
|
||||||
{
|
{
|
||||||
if (frameCount_ > 0)
|
if (frameCount_ > 0)
|
||||||
@ -366,44 +417,26 @@ void TwoPassStabilizer::runPrePassIfNecessary()
|
|||||||
frameCount_++;
|
frameCount_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clock_t elapsedTime = clock() - startTime;
|
||||||
|
log_->print("\nmotion estimation time: %.3f sec\n",
|
||||||
|
static_cast<double>(elapsedTime) / CLOCKS_PER_SEC);
|
||||||
|
|
||||||
// add aux. motions
|
// add aux. motions
|
||||||
|
|
||||||
for (int i = 0; i < radius_; ++i)
|
for (int i = 0; i < radius_; ++i)
|
||||||
motions_.push_back(Mat::eye(3, 3, CV_32F));
|
motions_.push_back(Mat::eye(3, 3, CV_32F));
|
||||||
log_->print("\n");
|
|
||||||
|
|
||||||
// stabilize
|
// stabilize
|
||||||
|
|
||||||
|
startTime = clock();
|
||||||
|
|
||||||
stabilizationMotions_.resize(frameCount_);
|
stabilizationMotions_.resize(frameCount_);
|
||||||
motionStabilizer_->stabilize(
|
motionStabilizer_->stabilize(
|
||||||
frameCount_, motions_, make_pair(0, frameCount_ - 1), &stabilizationMotions_[0]);
|
frameCount_, motions_, make_pair(0, frameCount_ - 1), &stabilizationMotions_[0]);
|
||||||
|
|
||||||
// save motions
|
elapsedTime = clock() - startTime;
|
||||||
|
log_->print("motion stabilization time: %.3f sec\n",
|
||||||
/*ofstream fm("log_motions.csv");
|
static_cast<double>(elapsedTime) / CLOCKS_PER_SEC);
|
||||||
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;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// estimate optimal trim ratio if necessary
|
// estimate optimal trim ratio if necessary
|
||||||
|
|
||||||
@ -418,11 +451,12 @@ void TwoPassStabilizer::runPrePassIfNecessary()
|
|||||||
log_->print("estimated trim ratio: %f\n", static_cast<double>(trimRatio_));
|
log_->print("estimated trim ratio: %f\n", static_cast<double>(trimRatio_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SAVE_MOTIONS
|
||||||
|
saveMotions(frameCount_, motions_, stabilizationMotions_);
|
||||||
|
#endif
|
||||||
|
|
||||||
isPrePassDone_ = true;
|
isPrePassDone_ = true;
|
||||||
frameSource_->reset();
|
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;
|
Mat stabilizedFrame;
|
||||||
int nframes = 0;
|
int nframes = 0;
|
||||||
|
|
||||||
|
// for each stabilized frame
|
||||||
while (!(stabilizedFrame = stabilizedFrames->nextFrame()).empty())
|
while (!(stabilizedFrame = stabilizedFrames->nextFrame()).empty())
|
||||||
{
|
{
|
||||||
nframes++;
|
nframes++;
|
||||||
|
|
||||||
|
// init writer (once) and save stabilized frame
|
||||||
if (!outputPath.empty())
|
if (!outputPath.empty())
|
||||||
{
|
{
|
||||||
if (!writer.isOpened())
|
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;
|
writer << stabilizedFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// show stabilized frame
|
||||||
if (!quietMode)
|
if (!quietMode)
|
||||||
{
|
{
|
||||||
imshow("stabilizedFrame", stabilizedFrame);
|
imshow("stabilizedFrame", stabilizedFrame);
|
||||||
char key = static_cast<char>(waitKey(3));
|
char key = static_cast<char>(waitKey(3));
|
||||||
if (key == 27)
|
if (key == 27) { cout << endl; break; }
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << endl
|
cout << "processed frames: " << nframes << endl
|
||||||
<< "processed frames: " << nframes << endl
|
|
||||||
<< "finished\n";
|
<< "finished\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user