Added load and save motion args into videostab sample
This commit is contained in:
parent
e64c08d5d9
commit
45fd8a6a63
@ -163,6 +163,9 @@ public:
|
|||||||
virtual void reset() { resetImpl(); }
|
virtual void reset() { resetImpl(); }
|
||||||
virtual Mat nextFrame();
|
virtual Mat nextFrame();
|
||||||
|
|
||||||
|
// available after pre-pass, before it's empty
|
||||||
|
std::vector<Mat> motions() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resetImpl();
|
void resetImpl();
|
||||||
void runPrePassIfNecessary();
|
void runPrePassIfNecessary();
|
||||||
|
@ -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()
|
void TwoPassStabilizer::resetImpl()
|
||||||
{
|
{
|
||||||
isPrePassDone_ = false;
|
isPrePassDone_ = false;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "opencv2/core/core.hpp"
|
#include "opencv2/core/core.hpp"
|
||||||
@ -12,14 +13,54 @@ using namespace std;
|
|||||||
using namespace cv;
|
using namespace cv;
|
||||||
using namespace cv::videostab;
|
using namespace cv::videostab;
|
||||||
|
|
||||||
|
|
||||||
Ptr<IFrameSource> stabilizedFrames;
|
Ptr<IFrameSource> stabilizedFrames;
|
||||||
|
string saveMotionsPath;
|
||||||
double outputFps;
|
double outputFps;
|
||||||
string outputPath;
|
string outputPath;
|
||||||
bool quietMode;
|
bool quietMode;
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
void saveMotionsIfNecessary();
|
||||||
void printHelp();
|
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()
|
void run()
|
||||||
{
|
{
|
||||||
VideoWriter writer;
|
VideoWriter writer;
|
||||||
@ -27,6 +68,8 @@ void run()
|
|||||||
|
|
||||||
while (!(stabilizedFrame = stabilizedFrames->nextFrame()).empty())
|
while (!(stabilizedFrame = stabilizedFrames->nextFrame()).empty())
|
||||||
{
|
{
|
||||||
|
if (!saveMotionsPath.empty())
|
||||||
|
saveMotionsIfNecessary();
|
||||||
if (!outputPath.empty())
|
if (!outputPath.empty())
|
||||||
{
|
{
|
||||||
if (!writer.isOpened())
|
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()
|
void printHelp()
|
||||||
{
|
{
|
||||||
cout << "OpenCV video stabilizer.\n"
|
cout << "OpenCV video stabilizer.\n"
|
||||||
@ -58,6 +128,10 @@ void printHelp()
|
|||||||
" --min-inlier-ratio=<float_number>\n"
|
" --min-inlier-ratio=<float_number>\n"
|
||||||
" Minimum inlier ratio to decide if estimated motion is OK. The default is 0.1,\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"
|
" 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"
|
" -r, --radius=<int_number>\n"
|
||||||
" Set smoothing radius. The default is 15.\n"
|
" Set smoothing radius. The default is 15.\n"
|
||||||
" --stdev=<float_number>\n"
|
" --stdev=<float_number>\n"
|
||||||
@ -108,6 +182,8 @@ int main(int argc, const char **argv)
|
|||||||
"{ m | model | | }"
|
"{ m | model | | }"
|
||||||
"{ | min-inlier-ratio | | }"
|
"{ | min-inlier-ratio | | }"
|
||||||
"{ | outlier-ratio | | }"
|
"{ | outlier-ratio | | }"
|
||||||
|
"{ | save-motions | | }"
|
||||||
|
"{ | load-motions | | }"
|
||||||
"{ r | radius | | }"
|
"{ r | radius | | }"
|
||||||
"{ | stdev | | }"
|
"{ | stdev | | }"
|
||||||
"{ | deblur | | }"
|
"{ | deblur | | }"
|
||||||
@ -145,7 +221,12 @@ int main(int argc, const char **argv)
|
|||||||
motionFilter->setStdev(cmd.get<float>("stdev"));
|
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)
|
if (isTwoPass)
|
||||||
{
|
{
|
||||||
@ -182,18 +263,17 @@ int main(int argc, const char **argv)
|
|||||||
motionEstimator->setMotionModel(AFFINE);
|
motionEstimator->setMotionModel(AFFINE);
|
||||||
else if (!cmd.get<string>("model").empty())
|
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())
|
if (!cmd.get<string>("outlier-ratio").empty())
|
||||||
{
|
{
|
||||||
RansacParams ransacParams = motionEstimator->ransacParams();
|
RansacParams ransacParams = motionEstimator->ransacParams();
|
||||||
ransacParams.eps = cmd.get<float>("outlier-ratio");
|
ransacParams.eps = cmd.get<float>("outlier-ratio");
|
||||||
motionEstimator->setRansacParams(ransacParams);
|
motionEstimator->setRansacParams(ransacParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cmd.get<string>("min-inlier-ratio").empty())
|
if (!cmd.get<string>("min-inlier-ratio").empty())
|
||||||
motionEstimator->setMinInlierRatio(cmd.get<float>("min-inlier-ratio"));
|
motionEstimator->setMinInlierRatio(cmd.get<float>("min-inlier-ratio"));
|
||||||
|
|
||||||
stabilizer->setMotionEstimator(motionEstimator);
|
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())
|
if (!cmd.get<string>("radius").empty())
|
||||||
stabilizer->setRadius(cmd.get<int>("radius"));
|
stabilizer->setRadius(cmd.get<int>("radius"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user