mirror of
https://github.com/opencv/opencv.git
synced 2025-01-18 06:03:15 +08:00
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 Mat nextFrame();
|
||||
|
||||
// available after pre-pass, before it's empty
|
||||
std::vector<Mat> motions() const;
|
||||
|
||||
private:
|
||||
void resetImpl();
|
||||
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()
|
||||
{
|
||||
isPrePassDone_ = false;
|
||||
|
@ -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"));
|
||||
|
Loading…
Reference in New Issue
Block a user