Added the first version of the stitching module docs
authorAlexey Spizhevoy <no@email>
Wed, 18 Jan 2012 13:43:34 +0000 (13:43 +0000)
committerAlexey Spizhevoy <no@email>
Wed, 18 Jan 2012 13:43:34 +0000 (13:43 +0000)
modules/refman.rst
modules/stitching/doc/high_level.rst [new file with mode: 0644]
modules/stitching/doc/matching.rst [new file with mode: 0644]
modules/stitching/doc/motion_estimation.rst [new file with mode: 0644]
modules/stitching/doc/stitching.rst [new file with mode: 0644]

index 5dc0c13..394f616 100644 (file)
@@ -16,3 +16,5 @@ OpenCV API Reference
    ml/doc/ml.rst
    flann/doc/flann.rst
    gpu/doc/gpu.rst
+   stitching/doc/stitching.rst
+
diff --git a/modules/stitching/doc/high_level.rst b/modules/stitching/doc/high_level.rst
new file mode 100644 (file)
index 0000000..6800eea
--- /dev/null
@@ -0,0 +1,145 @@
+High Level Functionality
+========================
+
+.. highlight:: cpp
+
+Stitcher
+--------
+.. ocv:class:: Stitcher
+
+High level image stitcher. It's possible to use this class without being aware of the entire stitching pipeline. However, to be able to achieve higher stitching stability and quality of the final images at least being familiar with the theory is recommended. ::
+
+    class CV_EXPORTS Stitcher
+    {
+    public:
+        enum { ORIG_RESOL = -1 };
+        enum Status { OK, ERR_NEED_MORE_IMGS };
+
+        // Creates stitcher with default parameters
+        static Stitcher createDefault(bool try_use_gpu = false);
+
+        Status estimateTransform(InputArray images);
+        Status estimateTransform(InputArray images, const std::vector<std::vector<Rect> > &rois);
+
+        Status composePanorama(OutputArray pano);
+        Status composePanorama(InputArray images, OutputArray pano);
+
+        Status stitch(InputArray images, OutputArray pano);
+        Status stitch(InputArray images, const std::vector<std::vector<Rect> > &rois, OutputArray pano);
+
+        double registrationResol() const { return registr_resol_; }
+        void setRegistrationResol(double resol_mpx) { registr_resol_ = resol_mpx; }
+
+        double seamEstimationResol() const { return seam_est_resol_; }
+        void setSeamEstimationResol(double resol_mpx) { seam_est_resol_ = resol_mpx; }
+
+        double compositingResol() const { return compose_resol_; }
+        void setCompositingResol(double resol_mpx) { compose_resol_ = resol_mpx; }
+
+        double panoConfidenceThresh() const { return conf_thresh_; }
+        void setPanoConfidenceThresh(double conf_thresh) { conf_thresh_ = conf_thresh; }
+
+        bool waveCorrection() const { return do_wave_correct_; }
+        void setWaveCorrection(bool flag) { do_wave_correct_ = flag; }
+
+        detail::WaveCorrectKind waveCorrectKind() const { return wave_correct_kind_; }
+        void setWaveCorrectKind(detail::WaveCorrectKind kind) { wave_correct_kind_ = kind; }
+
+        Ptr<detail::FeaturesFinder> featuresFinder() { return features_finder_; }
+        const Ptr<detail::FeaturesFinder> featuresFinder() const { return features_finder_; }
+        void setFeaturesFinder(Ptr<detail::FeaturesFinder> features_finder)
+            { features_finder_ = features_finder; }
+
+        Ptr<detail::FeaturesMatcher> featuresMatcher() { return features_matcher_; }
+        const Ptr<detail::FeaturesMatcher> featuresMatcher() const { return features_matcher_; }
+        void setFeaturesMatcher(Ptr<detail::FeaturesMatcher> features_matcher)
+            { features_matcher_ = features_matcher; }
+
+        const cv::Mat& matchingMask() const { return matching_mask_; }
+        void setMatchingMask(const cv::Mat &mask)
+        { 
+            CV_Assert(mask.type() == CV_8U && mask.cols == mask.rows);
+            matching_mask_ = mask.clone(); 
+        }
+
+        Ptr<detail::BundleAdjusterBase> bundleAdjuster() { return bundle_adjuster_; }
+        const Ptr<detail::BundleAdjusterBase> bundleAdjuster() const { return bundle_adjuster_; }
+        void setBundleAdjuster(Ptr<detail::BundleAdjusterBase> bundle_adjuster)
+            { bundle_adjuster_ = bundle_adjuster; }
+
+        Ptr<WarperCreator> warper() { return warper_; }
+        const Ptr<WarperCreator> warper() const { return warper_; }
+        void setWarper(Ptr<WarperCreator> warper) { warper_ = warper; }
+
+        Ptr<detail::ExposureCompensator> exposureCompensator() { return exposure_comp_; }
+        const Ptr<detail::ExposureCompensator> exposureCompensator() const { return exposure_comp_; }
+        void setExposureCompensator(Ptr<detail::ExposureCompensator> exposure_comp)
+            { exposure_comp_ = exposure_comp; }
+
+        Ptr<detail::SeamFinder> seamFinder() { return seam_finder_; }
+        const Ptr<detail::SeamFinder> seamFinder() const { return seam_finder_; }
+        void setSeamFinder(Ptr<detail::SeamFinder> seam_finder) { seam_finder_ = seam_finder; }
+
+        Ptr<detail::Blender> blender() { return blender_; }
+        const Ptr<detail::Blender> blender() const { return blender_; }
+        void setBlender(Ptr<detail::Blender> blender) { blender_ = blender; }
+
+    private: 
+        /* hidden */
+    };
+
+WarperCreator
+-------------
+.. ocv:class:: WarperCreator
+
+Image warper factories base class. ::
+
+    class WarperCreator
+    {
+    public:
+        virtual ~WarperCreator() {}
+        virtual Ptr<detail::RotationWarper> create(float scale) const = 0;
+    };
+
+PlaneWarper
+-----------
+.. ocv:class:: PlaneWarper
+
+Plane warper factory class. ::
+
+    class PlaneWarper : public WarperCreator
+    {
+    public:
+        Ptr<detail::RotationWarper> create(float scale) const { return new detail::PlaneWarper(scale); }
+    };
+
+.. seealso:: :ocv:class:`detail::PlaneWarper`
+
+CylindricalWarper
+-----------------
+.. ocv:class:: CylindricalWarper
+
+Cylindrical warper factory class. ::
+
+    class CylindricalWarper: public WarperCreator
+    {
+    public:
+        Ptr<detail::RotationWarper> create(float scale) const { return new detail::CylindricalWarper(scale); }
+    };
+
+.. seealso:: :ocv:class:`detail::CylindricalWarper`
+
+SphericalWarper
+---------------
+.. ocv:class:: SphericalWarper
+
+Spherical warper factory class. ::
+
+    class SphericalWarper: public WarperCreator
+    {
+    public:
+        Ptr<detail::RotationWarper> create(float scale) const { return new detail::SphericalWarper(scale); }
+    };
+
+.. seealso:: :ocv:class:`detail::SphericalWarper`
+
diff --git a/modules/stitching/doc/matching.rst b/modules/stitching/doc/matching.rst
new file mode 100644 (file)
index 0000000..28bf7b8
--- /dev/null
@@ -0,0 +1,151 @@
+Features Finding and Images Matching
+====================================
+
+.. highlight:: cpp
+
+detail::ImageFeatures
+-----------------------
+.. ocv:struct:: detail::ImageFeatures 
+
+Structure containing image keypoints and descriptors. ::
+
+    struct CV_EXPORTS ImageFeatures
+    {
+        int img_idx;
+        Size img_size;
+        std::vector<KeyPoint> keypoints;
+        Mat descriptors;
+    };
+
+detail::FeaturesFinder
+----------------------
+.. ocv:class:: detail::FeaturesFinder
+
+Feature finders base class. ::
+
+    class CV_EXPORTS FeaturesFinder
+    {
+    public:
+        virtual ~FeaturesFinder() {}
+        void operator ()(const Mat &image, ImageFeatures &features);
+        void operator ()(const Mat &image, ImageFeatures &features, const std::vector<cv::Rect> &rois);
+        virtual void collectGarbage() {}
+
+    protected:
+        virtual void find(const Mat &image, ImageFeatures &features) = 0;
+    };
+
+detail::SurfFeaturesFinder
+--------------------------
+.. ocv:class:: detail::SurfFeaturesFinder
+
+SURF features finder. ::
+
+    class CV_EXPORTS SurfFeaturesFinder : public FeaturesFinder
+    {
+    public:
+        SurfFeaturesFinder(double hess_thresh = 300., int num_octaves = 3, int num_layers = 4,
+                           int num_octaves_descr = /*4*/3, int num_layers_descr = /*2*/4);
+
+    private:
+        /* hidden */
+    };
+
+.. seealso::
+    :ocv:class:`detail::FeaturesFinder`
+    :ocv:class:`SURF`
+
+detail::OrbFeaturesFinder
+-------------------------
+.. ocv:class:: detail::OrbFeaturesFinder
+
+ORB features finder. ::
+
+    class CV_EXPORTS OrbFeaturesFinder : public FeaturesFinder
+    {
+    public:
+        OrbFeaturesFinder(Size _grid_size = Size(3,1), size_t n_features = 1500, 
+                          const ORB::CommonParams &detector_params = ORB::CommonParams(1.3f, 5));
+
+    private:
+        /* hidden */
+    };
+
+.. seealso:: 
+    :ocv:class:`detail::FeaturesFinder`,
+    :ocv:class:`ORB`
+
+detail::MatchesInfo
+-------------------
+.. ocv:struct: detail::MatchesInfo
+
+Structure containing information about matches between two images. It's assumed that there is a homography between those images. ::
+
+    struct CV_EXPORTS MatchesInfo
+    {
+        MatchesInfo();
+        MatchesInfo(const MatchesInfo &other);
+        const MatchesInfo& operator =(const MatchesInfo &other);
+
+        int src_img_idx, dst_img_idx;       // Images indices (optional)
+        std::vector<DMatch> matches;
+        std::vector<uchar> inliers_mask;    // Geometrically consistent matches mask
+        int num_inliers;                    // Number of geometrically consistent matches
+        Mat H;                              // Estimated homography
+        double confidence;                  // Confidence two images are from the same panorama
+    };
+
+detail::FeaturesMatcher
+-----------------------
+.. ocv:class:: detail::FeaturesMatcher
+
+Feature matchers base class. ::
+
+    class CV_EXPORTS FeaturesMatcher
+    {
+    public:
+        virtual ~FeaturesMatcher() {}
+
+        void operator ()(const ImageFeatures &features1, const ImageFeatures &features2, 
+                         MatchesInfo& matches_info) { match(features1, features2, matches_info); }
+
+        void operator ()(const std::vector<ImageFeatures> &features, std::vector<MatchesInfo> &pairwise_matches, 
+                         const cv::Mat &mask = cv::Mat());
+
+        bool isThreadSafe() const { return is_thread_safe_; }
+
+        virtual void collectGarbage() {}
+
+    protected:
+        FeaturesMatcher(bool is_thread_safe = false) : is_thread_safe_(is_thread_safe) {}
+
+        virtual void match(const ImageFeatures &features1, const ImageFeatures &features2, 
+                           MatchesInfo& matches_info) = 0;
+
+        bool is_thread_safe_;
+    };
+
+detail::BestOf2NearestMatcher
+-----------------------------
+.. ocv:class:: detail::BestOf2NearestMatcher
+
+Features matcher which finds two best matches for each feature and leaves the best one only if the ratio between descriptor distances is greater than the threshold ``match_conf``. ::
+
+    class CV_EXPORTS BestOf2NearestMatcher : public FeaturesMatcher
+    {
+    public:
+        BestOf2NearestMatcher(bool try_use_gpu = false, float match_conf = 0.65f, 
+                              int num_matches_thresh1 = 6, int num_matches_thresh2 = 6);
+
+        void collectGarbage();
+
+    protected:
+        void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info);
+
+        int num_matches_thresh1_;
+        int num_matches_thresh2_;
+        Ptr<FeaturesMatcher> impl_;
+    };
+
+.. seealso:: :ocv:class:`detail::FeaturesMatcher`
+
diff --git a/modules/stitching/doc/motion_estimation.rst b/modules/stitching/doc/motion_estimation.rst
new file mode 100644 (file)
index 0000000..b3c7f88
--- /dev/null
@@ -0,0 +1,174 @@
+Rotation Estimation
+===================
+
+.. highlight:: cpp
+
+detail::Estimator
+-----------------
+.. ocv:class:: detail::Estimator
+
+Rotation estimator base class. It takes features of all images, pairwise matches between all images and estimates rotations of all cameras. 
+
+.. note:: The coordinate system origin is implementation-dependent, but you can always normalize the rotations in respect to the first camera, for instance. 
+
+::
+
+    class CV_EXPORTS Estimator
+    {
+    public:
+        virtual ~Estimator() {}
+
+        void operator ()(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches, 
+                         std::vector<CameraParams> &cameras)
+            { estimate(features, pairwise_matches, cameras); }
+
+    protected:
+        virtual void estimate(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches, 
+                              std::vector<CameraParams> &cameras) = 0;
+    };
+
+detail::HomographyBasedEstimator
+--------------------------------
+.. ocv:class:: detail::HomographyBasedEstimator
+
+Homography based rotation estimator. ::
+
+    class CV_EXPORTS HomographyBasedEstimator : public Estimator
+    {
+    public:
+        HomographyBasedEstimator(bool is_focals_estimated = false)
+            : is_focals_estimated_(is_focals_estimated) {}
+
+        bool isFocalsEstimated() const { return is_focals_estimated_; }
+
+    private:   
+        void estimate(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches, 
+                      std::vector<CameraParams> &cameras);
+
+        bool is_focals_estimated_;
+    };
+
+detail::BundleAdjusterBase
+--------------------------
+.. ocv:class:: detail::BundleAdjusterBase
+
+Base class for all camera parameters refinement methods. ::
+
+    class CV_EXPORTS BundleAdjusterBase : public Estimator
+    {
+    public:
+        const Mat refinementMask() const { return refinement_mask_.clone(); }
+        void setRefinementMask(const Mat &mask) 
+        { 
+            CV_Assert(mask.type() == CV_8U && mask.size() == Size(3, 3));
+            refinement_mask_ = mask.clone(); 
+        }
+
+        double confThresh() const { return conf_thresh_; }
+        void setConfThresh(double conf_thresh) { conf_thresh_ = conf_thresh; }
+
+        CvTermCriteria termCriteria() { return term_criteria_; }
+        void setTermCriteria(const CvTermCriteria& term_criteria) { term_criteria_ = term_criteria; }
+
+    protected:
+        BundleAdjusterBase(int num_params_per_cam, int num_errs_per_measurement) 
+            : num_params_per_cam_(num_params_per_cam), 
+              num_errs_per_measurement_(num_errs_per_measurement) 
+        {    
+            setRefinementMask(Mat::ones(3, 3, CV_8U));
+            setConfThresh(1.); 
+            setTermCriteria(cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 1000, DBL_EPSILON));
+        }
+
+        // Runs bundle adjustment
+        virtual void estimate(const std::vector<ImageFeatures> &features, 
+                              const std::vector<MatchesInfo> &pairwise_matches,
+                              std::vector<CameraParams> &cameras);
+
+        virtual void setUpInitialCameraParams(const std::vector<CameraParams> &cameras) = 0;
+        virtual void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const = 0;
+        virtual void calcError(Mat &err) = 0;
+        virtual void calcJacobian(Mat &jac) = 0;
+
+        // 3x3 8U mask, where 0 means don't refine respective parameter, != 0 means refine
+        Mat refinement_mask_;
+
+        int num_images_;
+        int total_num_matches_;
+
+        int num_params_per_cam_;
+        int num_errs_per_measurement_;
+
+        const ImageFeatures *features_;
+        const MatchesInfo *pairwise_matches_;
+
+        // Threshold to filter out poorly matched image pairs
+        double conf_thresh_;
+
+        //Levenberg–Marquardt algorithm termination criteria
+        CvTermCriteria term_criteria_;
+
+        // Camera parameters matrix (CV_64F)
+        Mat cam_params_;
+
+        // Connected images pairs
+        std::vector<std::pair<int,int> > edges_;
+    };
+
+
+detail::BundleAdjusterReproj
+----------------------------
+.. ocv:class:: detail::BundleAdjusterReproj
+
+Implementation of the camera parameters refinement algorithm which minimizes sum of the reprojection error squares. ::
+
+    class CV_EXPORTS BundleAdjusterReproj : public BundleAdjusterBase
+    {
+    public:
+        BundleAdjusterReproj() : BundleAdjusterBase(7, 2) {}
+
+    private:
+        /* hidden */
+    };
+
+.. seealso:: :ocv:class:`detail::BundleAdjusterBase`
+
+detail::BundleAdjusterRay
+-------------------------
+
+Implementation of the camera parameters refinement algorithm which minimizes sum of the distances between the rays passing through the camera center and a feature. ::
+
+    class CV_EXPORTS BundleAdjusterRay : public BundleAdjusterBase
+    {
+    public:
+        BundleAdjusterRay() : BundleAdjusterBase(4, 3) {}
+
+    private:
+        /* hidden */
+    };
+
+.. seealso:: :ocv:class:`detail::BundleAdjusterBase`
+
+detail::WaveCorrectKind
+-----------------------
+.. ocv:class:: detail::WaveCorrectKind
+
+Wave correction kind. ::
+
+    enum CV_EXPORTS WaveCorrectKind
+    {
+        WAVE_CORRECT_HORIZ,
+        WAVE_CORRECT_VERT
+    };
+
+detail::waveCorrect
+-------------------
+Tries to make panorama more horizontal (or verical).
+
+.. ocv:function:: void waveCorrect(std::vector<Mat> &rmats, WaveCorrectKind kind)
+
+    :param rmats: Camera rotation matrices.
+
+    :param kind: Correction kind, see :ocv:class:`detail::WaveCorrectKind`.
+
+
diff --git a/modules/stitching/doc/stitching.rst b/modules/stitching/doc/stitching.rst
new file mode 100644 (file)
index 0000000..0c91a8e
--- /dev/null
@@ -0,0 +1,12 @@
+***************************
+stitching. Images stitching
+***************************
+
+.. toctree::
+    :maxdepth: 2
+
+    high_level
+    matching
+    motion_estimation
+
+