Skip to content

Commit 85678dc

Browse files
committed
Addded an option to visualize features used for image stabilization
1 parent fd2ca91 commit 85678dc

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

modules/videostab/include/opencv2/videostab/global_motion.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,13 @@ class CV_EXPORTS ImageMotionEstimatorBase
182182

183183
virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) = 0;
184184

185+
void setFeatureVisualizationCallback(std::function<void(Mat)> featureVisualizationCallback) {
186+
featureVisualizationCallback_ = std::bind(featureVisualizationCallback, std::placeholders::_1);
187+
};
188+
185189
protected:
186190
ImageMotionEstimatorBase(MotionModel model) { setMotionModel(model); }
191+
std::function<void(Mat)> featureVisualizationCallback_;
187192

188193
private:
189194
MotionModel motionModel_;

modules/videostab/samples/videostab.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ void printHelp()
166166
" Set output file path explicitly. The default is stabilized.avi.\n"
167167
" --fps=(<float_number>|auto)\n"
168168
" Set output video FPS explicitly. By default the source FPS is used (auto).\n"
169+
" --vo=, --vis-output=(no|<file_path>)\n"
170+
" Set visualization output file path. The default is no.\n"
169171
" -q, --quiet\n"
170172
" Don't show output video frames.\n\n"
171173
" -h, --help\n"
@@ -335,6 +337,7 @@ int main(int argc, const char **argv)
335337
"{ gpu | no | }"
336338
"{ o output | stabilized.avi | }"
337339
"{ fps | auto | }"
340+
"{ vo vis-output | no | }"
338341
"{ q quiet | | }"
339342
"{ h help | | }";
340343
CommandLineParser cmd(argc, argv, keys);
@@ -464,6 +467,26 @@ int main(int argc, const char **argv)
464467
// cast stabilizer to simple frame source interface to read stabilized frames
465468
stabilizedFrames.reset(dynamic_cast<IFrameSource*>(stabilizer));
466469

470+
// visWriter and visOutputPath must not be defined inside the if statement
471+
VideoWriter visWriter;
472+
string visOutputPath;
473+
if (arg("vis-output") != "no")
474+
{
475+
visOutputPath = arg("vis-output");
476+
std::function<void(Mat)> featureVisualizationCallback = [&visWriter, &visOutputPath](Mat featureVisualization){
477+
// init visWriter (once) and save visualization frame
478+
if (!featureVisualization.empty()) {
479+
if (!visWriter.isOpened())
480+
visWriter.open(visOutputPath, VideoWriter::fourcc('X','V','I','D'),
481+
outputFps, featureVisualization.size());
482+
visWriter << featureVisualization;
483+
}
484+
};
485+
// must be called before
486+
// "stabilizer->setMotionEstimator(makePtr<ToFileMotionWriter>(arg("save-motions"), stabilizer->motionEstimator()));"
487+
stabilizer->motionEstimator()->setFeatureVisualizationCallback(featureVisualizationCallback);
488+
}
489+
467490
MotionModel model = stabilizer->motionEstimator()->motionModel();
468491
if (arg("load-motions") != "no")
469492
{

modules/videostab/src/global_motion.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,8 +727,12 @@ Mat KeypointBasedMotionEstimator::estimate(InputArray frame0, InputArray frame1,
727727
// find keypoints
728728
detector_->detect(frame0, keypointsPrev_);
729729
if (keypointsPrev_.empty())
730+
{
731+
if (featureVisualizationCallback_)
732+
featureVisualizationCallback_(Mat());
730733
return Mat::eye(3, 3, CV_32F);
731-
734+
}
735+
732736
// extract points from keypoints
733737
pointsPrev_.resize(keypointsPrev_.size());
734738
for (size_t i = 0; i < keypointsPrev_.size(); ++i)
@@ -777,6 +781,23 @@ Mat KeypointBasedMotionEstimator::estimate(InputArray frame0, InputArray frame1,
777781
}
778782
}
779783

784+
if (featureVisualizationCallback_) {
785+
Mat featureVisualizationPrev;
786+
drawKeypoints(frame0, keypointsPrev_, featureVisualizationPrev,
787+
Scalar(0, 0, 255), DrawMatchesFlags::DEFAULT);
788+
789+
std::vector<KeyPoint> keypointsPrevGood;
790+
keypointsPrevGood.reserve(pointsPrevGood_.size());
791+
792+
for( size_t i = 0; i < pointsPrevGood_.size(); ++i) {
793+
keypointsPrevGood.push_back(KeyPoint(pointsPrevGood_[i], 1.f));
794+
}
795+
drawKeypoints(frame0, keypointsPrevGood, featureVisualizationPrev,
796+
Scalar(0, 255, 0), DrawMatchesFlags::DRAW_OVER_OUTIMG);
797+
798+
featureVisualizationCallback_(featureVisualizationPrev);
799+
}
800+
780801
// estimate motion
781802
return motionEstimator_->estimate(pointsPrevGood_, pointsGood_, ok);
782803
}

0 commit comments

Comments
 (0)