Added load and save motion args into videostab sample

This commit is contained in:
Alexey Spizhevoy 2012-03-22 09:30:28 +00:00
parent e64c08d5d9
commit 45fd8a6a63
3 changed files with 98 additions and 5 deletions

View File

@ -163,6 +163,9 @@ public:
virtual void reset() { resetImpl(); }
virtual Mat nextFrame();
// available after pre-pass, before it's empty
std::vector<Mat> motions() const;
private:
void resetImpl();
void runPrePassIfNecessary();

View File

@ -278,6 +278,16 @@ Mat TwoPassStabilizer::nextFrame()
}
vector<Mat> TwoPassStabilizer::motions() const
{
if (frameCount_ == 0)
return vector<Mat>();
vector<Mat> res(frameCount_ - 1);
copy(motions_.begin(), motions_.begin() + frameCount_ - 1, res.begin());
return res;
}
void TwoPassStabilizer::resetImpl()
{
isPrePassDone_ = false;

View File

@ -1,5 +1,6 @@
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include "opencv2/core/core.hpp"
@ -12,14 +13,54 @@ using namespace std;
using namespace cv;
using namespace cv::videostab;
Ptr<IFrameSource> stabilizedFrames;
string saveMotionsPath;
double outputFps;
string outputPath;
bool quietMode;
void run();
void saveMotionsIfNecessary();
void printHelp();
class GlobalMotionReader : public IGlobalMotionEstimator
{
public:
GlobalMotionReader(string path)
{
ifstream f(path.c_str());
if (!f.is_open())
throw runtime_error("can't open motions file: " + path);
int size; f >> size;
motions_.resize(size);
for (int i = 0; i < size; ++i)
{
Mat_<float> M(3, 3);
for (int l = 0; l < 3; ++l)
for (int s = 0; s < 3; ++s)
f >> M(l,s);
motions_[i] = M;
}
pos_ = 0;
}
virtual Mat estimate(const Mat &/*frame0*/, const Mat &/*frame1*/)
{
if (pos_ >= motions_.size())
{
stringstream text;
text << "can't load motion between frames " << pos_ << " and " << pos_+1;
throw runtime_error(text.str());
}
return motions_[pos_++];
}
private:
vector<Mat> motions_;
size_t pos_;
};
void run()
{
VideoWriter writer;
@ -27,6 +68,8 @@ void run()
while (!(stabilizedFrame = stabilizedFrames->nextFrame()).empty())
{
if (!saveMotionsPath.empty())
saveMotionsIfNecessary();
if (!outputPath.empty())
{
if (!writer.isOpened())
@ -46,6 +89,33 @@ void run()
}
void saveMotionsIfNecessary()
{
static bool areMotionsSaved = false;
if (!areMotionsSaved)
{
IFrameSource *frameSource = static_cast<IFrameSource*>(stabilizedFrames);
TwoPassStabilizer *twoPassStabilizer = dynamic_cast<TwoPassStabilizer*>(frameSource);
if (twoPassStabilizer)
{
ofstream f(saveMotionsPath.c_str());
const vector<Mat> &motions = twoPassStabilizer->motions();
f << motions.size() << endl;
for (size_t i = 0; i < motions.size(); ++i)
{
Mat_<float> M = motions[i];
for (int l = 0, k = 0; l < 3; ++l)
for (int s = 0; s < 3; ++s, ++k)
f << M(l,s) << " ";
f << endl;
}
}
areMotionsSaved = true;
cout << "motions are saved";
}
}
void printHelp()
{
cout << "OpenCV video stabilizer.\n"
@ -58,6 +128,10 @@ void printHelp()
" --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"
" --save-motions=<file_path>\n"
" Save estimated motions into file.\n"
" --load-motions=<file_path>\n"
" Load motions from file.\n\n"
" -r, --radius=<int_number>\n"
" Set smoothing radius. The default is 15.\n"
" --stdev=<float_number>\n"
@ -108,6 +182,8 @@ int main(int argc, const char **argv)
"{ m | model | | }"
"{ | min-inlier-ratio | | }"
"{ | outlier-ratio | | }"
"{ | save-motions | | }"
"{ | load-motions | | }"
"{ r | radius | | }"
"{ | stdev | | }"
"{ | deblur | | }"
@ -145,7 +221,12 @@ int main(int argc, const char **argv)
motionFilter->setStdev(cmd.get<float>("stdev"));
}
bool isTwoPass = cmd.get<string>("est-trim") == "yes";
if (!cmd.get<string>("save-motions").empty())
saveMotionsPath = cmd.get<string>("save-motions");
bool isTwoPass =
cmd.get<string>("est-trim") == "yes" ||
!cmd.get<string>("save-motions").empty();
if (isTwoPass)
{
@ -181,19 +262,18 @@ int main(int argc, const char **argv)
else if (cmd.get<string>("model") == "affine")
motionEstimator->setMotionModel(AFFINE);
else if (!cmd.get<string>("model").empty())
throw runtime_error("unknow motion mode: " + cmd.get<string>("model"));
throw runtime_error("unknow motion mode: " + cmd.get<string>("model"));
if (!cmd.get<string>("outlier-ratio").empty())
{
RansacParams ransacParams = motionEstimator->ransacParams();
ransacParams.eps = cmd.get<float>("outlier-ratio");
motionEstimator->setRansacParams(ransacParams);
}
if (!cmd.get<string>("min-inlier-ratio").empty())
motionEstimator->setMinInlierRatio(cmd.get<float>("min-inlier-ratio"));
stabilizer->setMotionEstimator(motionEstimator);
if (!cmd.get<string>("load-motions").empty())
stabilizer->setMotionEstimator(new GlobalMotionReader(cmd.get<string>("load-motions")));
if (!cmd.get<string>("radius").empty())
stabilizer->setRadius(cmd.get<int>("radius"));