1/*M///////////////////////////////////////////////////////////////////////////////////////
2//
3//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4//
5//  By downloading, copying, installing or using the software you agree to this license.
6//  If you do not agree to this license, do not download, install,
7//  copy or use the software.
8//
9//
10//                           License Agreement
11//                For Open Source Computer Vision Library
12//
13// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
15// Third party copyrights are property of their respective owners.
16//
17// Redistribution and use in source and binary forms, with or without modification,
18// are permitted provided that the following conditions are met:
19//
20//   * Redistribution's of source code must retain the above copyright notice,
21//     this list of conditions and the following disclaimer.
22//
23//   * Redistribution's in binary form must reproduce the above copyright notice,
24//     this list of conditions and the following disclaimer in the documentation
25//     and/or other materials provided with the distribution.
26//
27//   * The name of the copyright holders may not be used to endorse or promote products
28//     derived from this software without specific prior written permission.
29//
30// This software is provided by the copyright holders and contributors "as is" and
31// any express or implied warranties, including, but not limited to, the implied
32// warranties of merchantability and fitness for a particular purpose are disclaimed.
33// In no event shall the Intel Corporation or contributors be liable for any direct,
34// indirect, incidental, special, exemplary, or consequential damages
35// (including, but not limited to, procurement of substitute goods or services;
36// loss of use, data, or profits; or business interruption) however caused
37// and on any theory of liability, whether in contract, strict liability,
38// or tort (including negligence or otherwise) arising in any way out of
39// the use of this software, even if advised of the possibility of such damage.
40//
41//M*/
42
43#ifndef __OPENCV_VIDEOSTAB_GLOBAL_MOTION_HPP__
44#define __OPENCV_VIDEOSTAB_GLOBAL_MOTION_HPP__
45
46#include <vector>
47#include <fstream>
48#include "opencv2/core.hpp"
49#include "opencv2/features2d.hpp"
50#include "opencv2/opencv_modules.hpp"
51#include "opencv2/videostab/optical_flow.hpp"
52#include "opencv2/videostab/motion_core.hpp"
53#include "opencv2/videostab/outlier_rejection.hpp"
54
55#ifdef HAVE_OPENCV_CUDAIMGPROC
56#  include "opencv2/cudaimgproc.hpp"
57#endif
58
59namespace cv
60{
61namespace videostab
62{
63
64//! @addtogroup videostab_motion
65//! @{
66
67/** @brief Estimates best global motion between two 2D point clouds in the least-squares sense.
68
69@note Works in-place and changes input point arrays.
70
71@param points0 Source set of 2D points (32F).
72@param points1 Destination set of 2D points (32F).
73@param model Motion model (up to MM_AFFINE).
74@param rmse Final root-mean-square error.
75@return 3x3 2D transformation matrix (32F).
76 */
77CV_EXPORTS Mat estimateGlobalMotionLeastSquares(
78        InputOutputArray points0, InputOutputArray points1, int model = MM_AFFINE,
79        float *rmse = 0);
80
81/** @brief Estimates best global motion between two 2D point clouds robustly (using RANSAC method).
82
83@param points0 Source set of 2D points (32F).
84@param points1 Destination set of 2D points (32F).
85@param model Motion model. See cv::videostab::MotionModel.
86@param params RANSAC method parameters. See videostab::RansacParams.
87@param rmse Final root-mean-square error.
88@param ninliers Final number of inliers.
89 */
90CV_EXPORTS Mat estimateGlobalMotionRansac(
91        InputArray points0, InputArray points1, int model = MM_AFFINE,
92        const RansacParams &params = RansacParams::default2dMotion(MM_AFFINE),
93        float *rmse = 0, int *ninliers = 0);
94
95/** @brief Base class for all global motion estimation methods.
96 */
97class CV_EXPORTS MotionEstimatorBase
98{
99public:
100    virtual ~MotionEstimatorBase() {}
101
102    /** @brief Sets motion model.
103
104    @param val Motion model. See cv::videostab::MotionModel.
105     */
106    virtual void setMotionModel(MotionModel val) { motionModel_ = val; }
107
108    /**
109    @return Motion model. See cv::videostab::MotionModel.
110    */
111    virtual MotionModel motionModel() const { return motionModel_; }
112
113    /** @brief Estimates global motion between two 2D point clouds.
114
115    @param points0 Source set of 2D points (32F).
116    @param points1 Destination set of 2D points (32F).
117    @param ok Indicates whether motion was estimated successfully.
118    @return 3x3 2D transformation matrix (32F).
119     */
120    virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0) = 0;
121
122protected:
123    MotionEstimatorBase(MotionModel model) { setMotionModel(model); }
124
125private:
126    MotionModel motionModel_;
127};
128
129/** @brief Describes a robust RANSAC-based global 2D motion estimation method which minimizes L2 error.
130 */
131class CV_EXPORTS MotionEstimatorRansacL2 : public MotionEstimatorBase
132{
133public:
134    MotionEstimatorRansacL2(MotionModel model = MM_AFFINE);
135
136    void setRansacParams(const RansacParams &val) { ransacParams_ = val; }
137    RansacParams ransacParams() const { return ransacParams_; }
138
139    void setMinInlierRatio(float val) { minInlierRatio_ = val; }
140    float minInlierRatio() const { return minInlierRatio_; }
141
142    virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0);
143
144private:
145    RansacParams ransacParams_;
146    float minInlierRatio_;
147};
148
149/** @brief Describes a global 2D motion estimation method which minimizes L1 error.
150
151@note To be able to use this method you must build OpenCV with CLP library support. :
152 */
153class CV_EXPORTS MotionEstimatorL1 : public MotionEstimatorBase
154{
155public:
156    MotionEstimatorL1(MotionModel model = MM_AFFINE);
157
158    virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0);
159
160private:
161    std::vector<double> obj_, collb_, colub_;
162    std::vector<double> elems_, rowlb_, rowub_;
163    std::vector<int> rows_, cols_;
164
165    void set(int row, int col, double coef)
166    {
167        rows_.push_back(row);
168        cols_.push_back(col);
169        elems_.push_back(coef);
170    }
171};
172
173/** @brief Base class for global 2D motion estimation methods which take frames as input.
174 */
175class CV_EXPORTS ImageMotionEstimatorBase
176{
177public:
178    virtual ~ImageMotionEstimatorBase() {}
179
180    virtual void setMotionModel(MotionModel val) { motionModel_ = val; }
181    virtual MotionModel motionModel() const { return motionModel_; }
182
183    virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) = 0;
184
185protected:
186    ImageMotionEstimatorBase(MotionModel model) { setMotionModel(model); }
187
188private:
189    MotionModel motionModel_;
190};
191
192class CV_EXPORTS FromFileMotionReader : public ImageMotionEstimatorBase
193{
194public:
195    FromFileMotionReader(const String &path);
196
197    virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0);
198
199private:
200    std::ifstream file_;
201};
202
203class CV_EXPORTS ToFileMotionWriter : public ImageMotionEstimatorBase
204{
205public:
206    ToFileMotionWriter(const String &path, Ptr<ImageMotionEstimatorBase> estimator);
207
208    virtual void setMotionModel(MotionModel val) { motionEstimator_->setMotionModel(val); }
209    virtual MotionModel motionModel() const { return motionEstimator_->motionModel(); }
210
211    virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0);
212
213private:
214    std::ofstream file_;
215    Ptr<ImageMotionEstimatorBase> motionEstimator_;
216};
217
218/** @brief Describes a global 2D motion estimation method which uses keypoints detection and optical flow for
219matching.
220 */
221class CV_EXPORTS KeypointBasedMotionEstimator : public ImageMotionEstimatorBase
222{
223public:
224    KeypointBasedMotionEstimator(Ptr<MotionEstimatorBase> estimator);
225
226    virtual void setMotionModel(MotionModel val) { motionEstimator_->setMotionModel(val); }
227    virtual MotionModel motionModel() const { return motionEstimator_->motionModel(); }
228
229    void setDetector(Ptr<FeatureDetector> val) { detector_ = val; }
230    Ptr<FeatureDetector> detector() const { return detector_; }
231
232    void setOpticalFlowEstimator(Ptr<ISparseOptFlowEstimator> val) { optFlowEstimator_ = val; }
233    Ptr<ISparseOptFlowEstimator> opticalFlowEstimator() const { return optFlowEstimator_; }
234
235    void setOutlierRejector(Ptr<IOutlierRejector> val) { outlierRejector_ = val; }
236    Ptr<IOutlierRejector> outlierRejector() const { return outlierRejector_; }
237
238    virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0);
239
240private:
241    Ptr<MotionEstimatorBase> motionEstimator_;
242    Ptr<FeatureDetector> detector_;
243    Ptr<ISparseOptFlowEstimator> optFlowEstimator_;
244    Ptr<IOutlierRejector> outlierRejector_;
245
246    std::vector<uchar> status_;
247    std::vector<KeyPoint> keypointsPrev_;
248    std::vector<Point2f> pointsPrev_, points_;
249    std::vector<Point2f> pointsPrevGood_, pointsGood_;
250};
251
252#if defined(HAVE_OPENCV_CUDAIMGPROC) && defined(HAVE_OPENCV_CUDAOPTFLOW)
253
254class CV_EXPORTS KeypointBasedMotionEstimatorGpu : public ImageMotionEstimatorBase
255{
256public:
257    KeypointBasedMotionEstimatorGpu(Ptr<MotionEstimatorBase> estimator);
258
259    virtual void setMotionModel(MotionModel val) { motionEstimator_->setMotionModel(val); }
260    virtual MotionModel motionModel() const { return motionEstimator_->motionModel(); }
261
262    void setOutlierRejector(Ptr<IOutlierRejector> val) { outlierRejector_ = val; }
263    Ptr<IOutlierRejector> outlierRejector() const { return outlierRejector_; }
264
265    virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0);
266    Mat estimate(const cuda::GpuMat &frame0, const cuda::GpuMat &frame1, bool *ok = 0);
267
268private:
269    Ptr<MotionEstimatorBase> motionEstimator_;
270    Ptr<cuda::CornersDetector> detector_;
271    SparsePyrLkOptFlowEstimatorGpu optFlowEstimator_;
272    Ptr<IOutlierRejector> outlierRejector_;
273
274    cuda::GpuMat frame0_, grayFrame0_, frame1_;
275    cuda::GpuMat pointsPrev_, points_;
276    cuda::GpuMat status_;
277
278    Mat hostPointsPrev_, hostPoints_;
279    std::vector<Point2f> hostPointsPrevTmp_, hostPointsTmp_;
280    std::vector<uchar> rejectionStatus_;
281};
282
283#endif // defined(HAVE_OPENCV_CUDAIMGPROC) && defined(HAVE_OPENCV_CUDAOPTFLOW)
284
285/** @brief Computes motion between two frames assuming that all the intermediate motions are known.
286
287@param from Source frame index.
288@param to Destination frame index.
289@param motions Pair-wise motions. motions[i] denotes motion from the frame i to the frame i+1
290@return Motion from the frame from to the frame to.
291 */
292CV_EXPORTS Mat getMotion(int from, int to, const std::vector<Mat> &motions);
293
294//! @}
295
296} // namespace videostab
297} // namespace cv
298
299#endif
300