Commit 996c6e7a authored by Alexander Alekhin's avatar Alexander Alekhin

Merge pull request #2052 from SBCV:feature_mask

parents 64eba174 ff0167b9
...@@ -86,6 +86,28 @@ private: ...@@ -86,6 +86,28 @@ private:
Ptr<IFrameSource> impl; Ptr<IFrameSource> impl;
}; };
class MaskFrameSource : public IFrameSource
{
public:
MaskFrameSource(const Ptr<IFrameSource>& source): impl(source) {};
virtual void reset() CV_OVERRIDE { impl->reset(); }
virtual Mat nextFrame() CV_OVERRIDE {
Mat nextFrame = impl->nextFrame();
maskCallback_(nextFrame);
return nextFrame;
}
void setMaskCallback(std::function<void(Mat&)> MaskCallback)
{
maskCallback_ = std::bind(MaskCallback, std::placeholders::_1);
};
private:
Ptr<IFrameSource> impl;
std::function<void(Mat&)> maskCallback_;
};
//! @} //! @}
} // namespace videostab } // namespace videostab
......
...@@ -180,6 +180,12 @@ public: ...@@ -180,6 +180,12 @@ public:
virtual void setMotionModel(MotionModel val) { motionModel_ = val; } virtual void setMotionModel(MotionModel val) { motionModel_ = val; }
virtual MotionModel motionModel() const { return motionModel_; } virtual MotionModel motionModel() const { return motionModel_; }
virtual void setFrameMask(InputArray mask)
{
if (!mask.empty())
CV_Error(Error::StsNotImplemented, "Mask support is not implemented.");
}
virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) = 0; virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) = 0;
protected: protected:
...@@ -208,6 +214,8 @@ public: ...@@ -208,6 +214,8 @@ public:
virtual void setMotionModel(MotionModel val) CV_OVERRIDE { motionEstimator_->setMotionModel(val); } virtual void setMotionModel(MotionModel val) CV_OVERRIDE { motionEstimator_->setMotionModel(val); }
virtual MotionModel motionModel() const CV_OVERRIDE { return motionEstimator_->motionModel(); } virtual MotionModel motionModel() const CV_OVERRIDE { return motionEstimator_->motionModel(); }
virtual void setFrameMask(InputArray mask) CV_OVERRIDE { motionEstimator_->setFrameMask(mask); }
virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) CV_OVERRIDE; virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) CV_OVERRIDE;
private: private:
...@@ -235,6 +243,8 @@ public: ...@@ -235,6 +243,8 @@ public:
void setOutlierRejector(Ptr<IOutlierRejector> val) { outlierRejector_ = val; } void setOutlierRejector(Ptr<IOutlierRejector> val) { outlierRejector_ = val; }
Ptr<IOutlierRejector> outlierRejector() const { return outlierRejector_; } Ptr<IOutlierRejector> outlierRejector() const { return outlierRejector_; }
virtual void setFrameMask(InputArray mask) CV_OVERRIDE { mask_ = mask.getMat(); }
virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) CV_OVERRIDE; virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) CV_OVERRIDE;
Mat estimate(InputArray frame0, InputArray frame1, bool *ok = 0); Mat estimate(InputArray frame0, InputArray frame1, bool *ok = 0);
...@@ -243,6 +253,7 @@ private: ...@@ -243,6 +253,7 @@ private:
Ptr<FeatureDetector> detector_; Ptr<FeatureDetector> detector_;
Ptr<ISparseOptFlowEstimator> optFlowEstimator_; Ptr<ISparseOptFlowEstimator> optFlowEstimator_;
Ptr<IOutlierRejector> outlierRejector_; Ptr<IOutlierRejector> outlierRejector_;
Mat mask_;
std::vector<uchar> status_; std::vector<uchar> status_;
std::vector<KeyPoint> keypointsPrev_; std::vector<KeyPoint> keypointsPrev_;
...@@ -263,6 +274,8 @@ public: ...@@ -263,6 +274,8 @@ public:
void setOutlierRejector(Ptr<IOutlierRejector> val) { outlierRejector_ = val; } void setOutlierRejector(Ptr<IOutlierRejector> val) { outlierRejector_ = val; }
Ptr<IOutlierRejector> outlierRejector() const { return outlierRejector_; } Ptr<IOutlierRejector> outlierRejector() const { return outlierRejector_; }
virtual void setFrameMask(InputArray mask) CV_OVERRIDE { mask_ = mask.getMat(); }
virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) CV_OVERRIDE; virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) CV_OVERRIDE;
Mat estimate(const cuda::GpuMat &frame0, const cuda::GpuMat &frame1, bool *ok = 0); Mat estimate(const cuda::GpuMat &frame0, const cuda::GpuMat &frame1, bool *ok = 0);
...@@ -271,6 +284,7 @@ private: ...@@ -271,6 +284,7 @@ private:
Ptr<cuda::CornersDetector> detector_; Ptr<cuda::CornersDetector> detector_;
SparsePyrLkOptFlowEstimatorGpu optFlowEstimator_; SparsePyrLkOptFlowEstimatorGpu optFlowEstimator_;
Ptr<IOutlierRejector> outlierRejector_; Ptr<IOutlierRejector> outlierRejector_;
GpuMat mask_;
cuda::GpuMat frame0_, grayFrame0_, frame1_; cuda::GpuMat frame0_, grayFrame0_, frame1_;
cuda::GpuMat pointsPrev_, points_; cuda::GpuMat pointsPrev_, points_;
......
...@@ -77,6 +77,9 @@ public: ...@@ -77,6 +77,9 @@ public:
void setFrameSource(Ptr<IFrameSource> val) { frameSource_ = val; } void setFrameSource(Ptr<IFrameSource> val) { frameSource_ = val; }
Ptr<IFrameSource> frameSource() const { return frameSource_; } Ptr<IFrameSource> frameSource() const { return frameSource_; }
void setMaskSource(const Ptr<IFrameSource>& val) { maskSource_ = val; }
Ptr<IFrameSource> maskSource() const { return maskSource_; }
void setMotionEstimator(Ptr<ImageMotionEstimatorBase> val) { motionEstimator_ = val; } void setMotionEstimator(Ptr<ImageMotionEstimatorBase> val) { motionEstimator_ = val; }
Ptr<ImageMotionEstimatorBase> motionEstimator() const { return motionEstimator_; } Ptr<ImageMotionEstimatorBase> motionEstimator() const { return motionEstimator_; }
...@@ -110,6 +113,7 @@ protected: ...@@ -110,6 +113,7 @@ protected:
Ptr<ILog> log_; Ptr<ILog> log_;
Ptr<IFrameSource> frameSource_; Ptr<IFrameSource> frameSource_;
Ptr<IFrameSource> maskSource_;
Ptr<ImageMotionEstimatorBase> motionEstimator_; Ptr<ImageMotionEstimatorBase> motionEstimator_;
Ptr<DeblurerBase> deblurer_; Ptr<DeblurerBase> deblurer_;
Ptr<InpainterBase> inpainter_; Ptr<InpainterBase> inpainter_;
......
...@@ -89,6 +89,8 @@ void printHelp() ...@@ -89,6 +89,8 @@ void printHelp()
" Number of keypoints to find in each frame. The default is 1000.\n" " Number of keypoints to find in each frame. The default is 1000.\n"
" --local-outlier-rejection=(yes|no)\n" " --local-outlier-rejection=(yes|no)\n"
" Perform local outlier rejection. The default is no.\n\n" " Perform local outlier rejection. The default is no.\n\n"
" --feature-masks=(file_path|no)\n"
" Load masks from file. The default is no.\n\n"
" -sm=, --save-motions=(<file_path>|no)\n" " -sm=, --save-motions=(<file_path>|no)\n"
" Save estimated motions into file. The default is no.\n" " Save estimated motions into file. The default is no.\n"
" -lm=, --load-motions=(<file_path>|no)\n" " -lm=, --load-motions=(<file_path>|no)\n"
...@@ -297,6 +299,7 @@ int main(int argc, const char **argv) ...@@ -297,6 +299,7 @@ int main(int argc, const char **argv)
"{ nkps | 1000 | }" "{ nkps | 1000 | }"
"{ extra-kps | 0 | }" "{ extra-kps | 0 | }"
"{ local-outlier-rejection | no | }" "{ local-outlier-rejection | no | }"
"{ feature-masks | no | }"
"{ sm save-motions | no | }" "{ sm save-motions | no | }"
"{ lm load-motions | no | }" "{ lm load-motions | no | }"
"{ r radius | 15 | }" "{ r radius | 15 | }"
...@@ -461,6 +464,19 @@ int main(int argc, const char **argv) ...@@ -461,6 +464,19 @@ int main(int argc, const char **argv)
stabilizer->setFrameSource(source); stabilizer->setFrameSource(source);
stabilizer->setMotionEstimator(motionEstBuilder->build()); stabilizer->setMotionEstimator(motionEstBuilder->build());
if (arg("feature-masks") != "no")
{
Ptr<MaskFrameSource> maskSource = makePtr<MaskFrameSource>(
makePtr<VideoFileSource>(arg("feature-masks")));
std::function<void(Mat&)> maskCallback = [](Mat & inputFrame)
{
cv::cvtColor(inputFrame, inputFrame, cv::COLOR_BGR2GRAY);
threshold(inputFrame, inputFrame, 127, 255, THRESH_BINARY);
};
maskSource->setMaskCallback(maskCallback);
stabilizer->setMaskSource(maskSource);
}
// cast stabilizer to simple frame source interface to read stabilized frames // cast stabilizer to simple frame source interface to read stabilized frames
stabilizedFrames.reset(dynamic_cast<IFrameSource*>(stabilizer)); stabilizedFrames.reset(dynamic_cast<IFrameSource*>(stabilizer));
......
...@@ -725,7 +725,7 @@ Mat KeypointBasedMotionEstimator::estimate(const Mat &frame0, const Mat &frame1, ...@@ -725,7 +725,7 @@ Mat KeypointBasedMotionEstimator::estimate(const Mat &frame0, const Mat &frame1,
Mat KeypointBasedMotionEstimator::estimate(InputArray frame0, InputArray frame1, bool *ok) Mat KeypointBasedMotionEstimator::estimate(InputArray frame0, InputArray frame1, bool *ok)
{ {
// find keypoints // find keypoints
detector_->detect(frame0, keypointsPrev_); detector_->detect(frame0, keypointsPrev_, mask_);
if (keypointsPrev_.empty()) if (keypointsPrev_.empty())
return Mat::eye(3, 3, CV_32F); return Mat::eye(3, 3, CV_32F);
...@@ -815,7 +815,7 @@ Mat KeypointBasedMotionEstimatorGpu::estimate(const cuda::GpuMat &frame0, const ...@@ -815,7 +815,7 @@ Mat KeypointBasedMotionEstimatorGpu::estimate(const cuda::GpuMat &frame0, const
} }
// find keypoints // find keypoints
detector_->detect(grayFrame0, pointsPrev_); detector_->detect(grayFrame0, pointsPrev_, mask_);
// find correspondences // find correspondences
optFlowEstimator_.run(frame0, frame1, pointsPrev_, points_, status_); optFlowEstimator_.run(frame0, frame1, pointsPrev_, points_, status_);
......
...@@ -391,6 +391,9 @@ void TwoPassStabilizer::runPrePassIfNecessary() ...@@ -391,6 +391,9 @@ void TwoPassStabilizer::runPrePassIfNecessary()
{ {
if (frameCount_ > 0) if (frameCount_ > 0)
{ {
if (maskSource_)
motionEstimator_->setFrameMask(maskSource_->nextFrame());
motions_.push_back(motionEstimator_->estimate(prevFrame, frame, &ok)); motions_.push_back(motionEstimator_->estimate(prevFrame, frame, &ok));
if (doWobbleSuppression_) if (doWobbleSuppression_)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment