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, 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_STITCHING_STITCHER_HPP
44 #define OPENCV_STITCHING_STITCHER_HPP
45 
46 #include "opencv2/core.hpp"
47 #include "opencv2/features2d.hpp"
48 #include "opencv2/stitching/warpers.hpp"
49 #include "opencv2/stitching/detail/matchers.hpp"
50 #include "opencv2/stitching/detail/motion_estimators.hpp"
51 #include "opencv2/stitching/detail/exposure_compensate.hpp"
52 #include "opencv2/stitching/detail/seam_finders.hpp"
53 #include "opencv2/stitching/detail/blenders.hpp"
54 #include "opencv2/stitching/detail/camera.hpp"
55 
56 
57 #if defined(Status)
58 #  warning Detected X11 'Status' macro definition, it can cause build conflicts. Please, include this header before any X11 headers.
59 #endif
60 
61 
62 /**
63 @defgroup stitching Images stitching
64 
65 This figure illustrates the stitching module pipeline implemented in the Stitcher class. Using that
66 class it's possible to configure/remove some steps, i.e. adjust the stitching pipeline according to
67 the particular needs. All building blocks from the pipeline are available in the detail namespace,
68 one can combine and use them separately.
69 
70 The implemented stitching pipeline is very similar to the one proposed in @cite BL07 .
71 
72 ![stitching pipeline](StitchingPipeline.jpg)
73 
74 Camera models
75 -------------
76 
77 There are currently 2 camera models implemented in stitching pipeline.
78 
79 - _Homography model_ expecting perspective transformations between images
80   implemented in @ref cv::detail::BestOf2NearestMatcher cv::detail::HomographyBasedEstimator
81   cv::detail::BundleAdjusterReproj cv::detail::BundleAdjusterRay
82 - _Affine model_ expecting affine transformation with 6 DOF or 4 DOF implemented in
83   @ref cv::detail::AffineBestOf2NearestMatcher cv::detail::AffineBasedEstimator
84   cv::detail::BundleAdjusterAffine cv::detail::BundleAdjusterAffinePartial cv::AffineWarper
85 
86 Homography model is useful for creating photo panoramas captured by camera,
87 while affine-based model can be used to stitch scans and object captured by
88 specialized devices. Use @ref cv::Stitcher::create to get preconfigured pipeline for one
89 of those models.
90 
91 @note
92 Certain detailed settings of @ref cv::Stitcher might not make sense. Especially
93 you should not mix classes implementing affine model and classes implementing
94 Homography model, as they work with different transformations.
95 
96 @{
97     @defgroup stitching_match Features Finding and Images Matching
98     @defgroup stitching_rotation Rotation Estimation
99     @defgroup stitching_autocalib Autocalibration
100     @defgroup stitching_warp Images Warping
101     @defgroup stitching_seam Seam Estimation
102     @defgroup stitching_exposure Exposure Compensation
103     @defgroup stitching_blend Image Blenders
104 @}
105   */
106 
107 namespace cv {
108 
109 //! @addtogroup stitching
110 //! @{
111 
112 /** @brief High level image stitcher.
113 
114 It's possible to use this class without being aware of the entire stitching pipeline. However, to
115 be able to achieve higher stitching stability and quality of the final images at least being
116 familiar with the theory is recommended.
117 
118 @note
119    -   A basic example on image stitching can be found at
120         opencv_source_code/samples/cpp/stitching.cpp
121     -   A detailed example on image stitching can be found at
122         opencv_source_code/samples/cpp/stitching_detailed.cpp
123  */
124 class CV_EXPORTS_W Stitcher
125 {
126 public:
127     enum { ORIG_RESOL = -1 };
128     enum Status
129     {
130         OK = 0,
131         ERR_NEED_MORE_IMGS = 1,
132         ERR_HOMOGRAPHY_EST_FAIL = 2,
133         ERR_CAMERA_PARAMS_ADJUST_FAIL = 3
134     };
135     enum Mode
136     {
137         /** Mode for creating photo panoramas. Expects images under perspective
138         transformation and projects resulting pano to sphere.
139 
140         @sa detail::BestOf2NearestMatcher SphericalWarper
141         */
142         PANORAMA = 0,
143         /** Mode for composing scans. Expects images under affine transformation does
144         not compensate exposure by default.
145 
146         @sa detail::AffineBestOf2NearestMatcher AffineWarper
147         */
148         SCANS = 1,
149 
150     };
151 
152    // Stitcher() {}
153     /** @brief Creates a stitcher with the default parameters.
154 
155     @param try_use_gpu Flag indicating whether GPU should be used whenever it's possible.
156     @return Stitcher class instance.
157      */
158     static Stitcher createDefault(bool try_use_gpu = false);
159     /** @brief Creates a Stitcher configured in one of the stitching modes.
160 
161     @param mode Scenario for stitcher operation. This is usually determined by source of images
162     to stitch and their transformation. Default parameters will be chosen for operation in given
163     scenario.
164     @param try_use_gpu Flag indicating whether GPU should be used whenever it's possible.
165     @return Stitcher class instance.
166      */
167     static Ptr<Stitcher> create(Mode mode = PANORAMA, bool try_use_gpu = false);
168 
registrationResol() const169     CV_WRAP double registrationResol() const { return registr_resol_; }
setRegistrationResol(double resol_mpx)170     CV_WRAP void setRegistrationResol(double resol_mpx) { registr_resol_ = resol_mpx; }
171 
seamEstimationResol() const172     CV_WRAP double seamEstimationResol() const { return seam_est_resol_; }
setSeamEstimationResol(double resol_mpx)173     CV_WRAP void setSeamEstimationResol(double resol_mpx) { seam_est_resol_ = resol_mpx; }
174 
compositingResol() const175     CV_WRAP double compositingResol() const { return compose_resol_; }
setCompositingResol(double resol_mpx)176     CV_WRAP void setCompositingResol(double resol_mpx) { compose_resol_ = resol_mpx; }
177 
panoConfidenceThresh() const178     CV_WRAP double panoConfidenceThresh() const { return conf_thresh_; }
setPanoConfidenceThresh(double conf_thresh)179     CV_WRAP void setPanoConfidenceThresh(double conf_thresh) { conf_thresh_ = conf_thresh; }
180 
waveCorrection() const181     CV_WRAP bool waveCorrection() const { return do_wave_correct_; }
setWaveCorrection(bool flag)182     CV_WRAP void setWaveCorrection(bool flag) { do_wave_correct_ = flag; }
183 
waveCorrectKind() const184     detail::WaveCorrectKind waveCorrectKind() const { return wave_correct_kind_; }
setWaveCorrectKind(detail::WaveCorrectKind kind)185     void setWaveCorrectKind(detail::WaveCorrectKind kind) { wave_correct_kind_ = kind; }
186 
featuresFinder()187     Ptr<detail::FeaturesFinder> featuresFinder() { return features_finder_; }
featuresFinder() const188     const Ptr<detail::FeaturesFinder> featuresFinder() const { return features_finder_; }
setFeaturesFinder(Ptr<detail::FeaturesFinder> features_finder)189     void setFeaturesFinder(Ptr<detail::FeaturesFinder> features_finder)
190         { features_finder_ = features_finder; }
191 
featuresMatcher()192     Ptr<detail::FeaturesMatcher> featuresMatcher() { return features_matcher_; }
featuresMatcher() const193     const Ptr<detail::FeaturesMatcher> featuresMatcher() const { return features_matcher_; }
setFeaturesMatcher(Ptr<detail::FeaturesMatcher> features_matcher)194     void setFeaturesMatcher(Ptr<detail::FeaturesMatcher> features_matcher)
195         { features_matcher_ = features_matcher; }
196 
matchingMask() const197     const cv::UMat& matchingMask() const { return matching_mask_; }
setMatchingMask(const cv::UMat & mask)198     void setMatchingMask(const cv::UMat &mask)
199     {
200         CV_Assert(mask.type() == CV_8U && mask.cols == mask.rows);
201         matching_mask_ = mask.clone();
202     }
203 
bundleAdjuster()204     Ptr<detail::BundleAdjusterBase> bundleAdjuster() { return bundle_adjuster_; }
bundleAdjuster() const205     const Ptr<detail::BundleAdjusterBase> bundleAdjuster() const { return bundle_adjuster_; }
setBundleAdjuster(Ptr<detail::BundleAdjusterBase> bundle_adjuster)206     void setBundleAdjuster(Ptr<detail::BundleAdjusterBase> bundle_adjuster)
207         { bundle_adjuster_ = bundle_adjuster; }
208 
209     /* TODO OpenCV ABI 4.x
210     Ptr<detail::Estimator> estimator() { return estimator_; }
211     const Ptr<detail::Estimator> estimator() const { return estimator_; }
212     void setEstimator(Ptr<detail::Estimator> estimator)
213         { estimator_ = estimator; }
214     */
215 
warper()216     Ptr<WarperCreator> warper() { return warper_; }
warper() const217     const Ptr<WarperCreator> warper() const { return warper_; }
setWarper(Ptr<WarperCreator> creator)218     void setWarper(Ptr<WarperCreator> creator) { warper_ = creator; }
219 
exposureCompensator()220     Ptr<detail::ExposureCompensator> exposureCompensator() { return exposure_comp_; }
exposureCompensator() const221     const Ptr<detail::ExposureCompensator> exposureCompensator() const { return exposure_comp_; }
setExposureCompensator(Ptr<detail::ExposureCompensator> exposure_comp)222     void setExposureCompensator(Ptr<detail::ExposureCompensator> exposure_comp)
223         { exposure_comp_ = exposure_comp; }
224 
seamFinder()225     Ptr<detail::SeamFinder> seamFinder() { return seam_finder_; }
seamFinder() const226     const Ptr<detail::SeamFinder> seamFinder() const { return seam_finder_; }
setSeamFinder(Ptr<detail::SeamFinder> seam_finder)227     void setSeamFinder(Ptr<detail::SeamFinder> seam_finder) { seam_finder_ = seam_finder; }
228 
blender()229     Ptr<detail::Blender> blender() { return blender_; }
blender() const230     const Ptr<detail::Blender> blender() const { return blender_; }
setBlender(Ptr<detail::Blender> b)231     void setBlender(Ptr<detail::Blender> b) { blender_ = b; }
232 
233     /** @overload */
234     CV_WRAP Status estimateTransform(InputArrayOfArrays images);
235     /** @brief These functions try to match the given images and to estimate rotations of each camera.
236 
237     @note Use the functions only if you're aware of the stitching pipeline, otherwise use
238     Stitcher::stitch.
239 
240     @param images Input images.
241     @param rois Region of interest rectangles.
242     @return Status code.
243      */
244     Status estimateTransform(InputArrayOfArrays images, const std::vector<std::vector<Rect> > &rois);
245 
246     /** @overload */
247     CV_WRAP Status composePanorama(OutputArray pano);
248     /** @brief These functions try to compose the given images (or images stored internally from the other function
249     calls) into the final pano under the assumption that the image transformations were estimated
250     before.
251 
252     @note Use the functions only if you're aware of the stitching pipeline, otherwise use
253     Stitcher::stitch.
254 
255     @param images Input images.
256     @param pano Final pano.
257     @return Status code.
258      */
259     Status composePanorama(InputArrayOfArrays images, OutputArray pano);
260 
261     /** @overload */
262     CV_WRAP Status stitch(InputArrayOfArrays images, OutputArray pano);
263     /** @brief These functions try to stitch the given images.
264 
265     @param images Input images.
266     @param rois Region of interest rectangles.
267     @param pano Final pano.
268     @return Status code.
269      */
270     Status stitch(InputArrayOfArrays images, const std::vector<std::vector<Rect> > &rois, OutputArray pano);
271 
component() const272     std::vector<int> component() const { return indices_; }
cameras() const273     std::vector<detail::CameraParams> cameras() const { return cameras_; }
workScale() const274     CV_WRAP double workScale() const { return work_scale_; }
275 
276 private:
277     //Stitcher() {}
278 
279     Status matchImages();
280     Status estimateCameraParams();
281 
282     double registr_resol_;
283     double seam_est_resol_;
284     double compose_resol_;
285     double conf_thresh_;
286     Ptr<detail::FeaturesFinder> features_finder_;
287     Ptr<detail::FeaturesMatcher> features_matcher_;
288     cv::UMat matching_mask_;
289     Ptr<detail::BundleAdjusterBase> bundle_adjuster_;
290     /* TODO OpenCV ABI 4.x
291     Ptr<detail::Estimator> estimator_;
292     */
293     bool do_wave_correct_;
294     detail::WaveCorrectKind wave_correct_kind_;
295     Ptr<WarperCreator> warper_;
296     Ptr<detail::ExposureCompensator> exposure_comp_;
297     Ptr<detail::SeamFinder> seam_finder_;
298     Ptr<detail::Blender> blender_;
299 
300     std::vector<cv::UMat> imgs_;
301     std::vector<std::vector<cv::Rect> > rois_;
302     std::vector<cv::Size> full_img_sizes_;
303     std::vector<detail::ImageFeatures> features_;
304     std::vector<detail::MatchesInfo> pairwise_matches_;
305     std::vector<cv::UMat> seam_est_imgs_;
306     std::vector<int> indices_;
307     std::vector<detail::CameraParams> cameras_;
308     double work_scale_;
309     double seam_scale_;
310     double seam_work_aspect_;
311     double warped_image_scale_;
312 };
313 
314 CV_EXPORTS_W Ptr<Stitcher> createStitcher(bool try_use_gpu = false);
315 CV_EXPORTS_W Ptr<Stitcher> createStitcherScans(bool try_use_gpu = false);
316 
317 //! @} stitching
318 
319 } // namespace cv
320 
321 #endif // OPENCV_STITCHING_STITCHER_HPP
322