TAPI: stitching, replaced Mat->UMat/_Array
authorAlexander Alekhin <alexander.alekhin@itseez.com>
Fri, 14 Feb 2014 11:36:04 +0000 (15:36 +0400)
committerAndrey Pavlenko <andrey.pavlenko@itseez.com>
Fri, 11 Apr 2014 09:01:06 +0000 (13:01 +0400)
15 files changed:
modules/core/include/opencv2/core/mat.hpp
modules/core/src/matrix.cpp
modules/stitching/include/opencv2/stitching.hpp
modules/stitching/include/opencv2/stitching/detail/blenders.hpp
modules/stitching/include/opencv2/stitching/detail/exposure_compensate.hpp
modules/stitching/include/opencv2/stitching/detail/matchers.hpp
modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp
modules/stitching/include/opencv2/stitching/detail/util.hpp
modules/stitching/src/blenders.cpp
modules/stitching/src/exposure_compensate.cpp
modules/stitching/src/matchers.cpp
modules/stitching/src/seam_finders.cpp
modules/stitching/src/stitcher.cpp
modules/stitching/src/util.cpp
samples/cpp/stitching_detailed.cpp

index 6b8368f..d921f75 100644 (file)
@@ -218,6 +218,9 @@ public:
     virtual void release() const;
     virtual void clear() const;
     virtual void setTo(const _InputArray& value, const _InputArray & mask = _InputArray()) const;
+
+    void assign(const UMat& u) const;
+    void assign(const Mat& m) const;
 };
 
 
index 4efba46..32ccd03 100644 (file)
@@ -2592,6 +2592,43 @@ void _OutputArray::setTo(const _InputArray& arr, const _InputArray & mask) const
         CV_Error(Error::StsNotImplemented, "");
 }
 
+
+void _OutputArray::assign(const UMat& u) const
+{
+    int k = kind();
+    if (k == UMAT)
+    {
+        *(UMat*)obj = u;
+    }
+    else if (k == MAT)
+    {
+        u.copyTo(*(Mat*)obj); // TODO check u.getMat()
+    }
+    else
+    {
+        CV_Error(Error::StsNotImplemented, "");
+    }
+}
+
+
+void _OutputArray::assign(const Mat& m) const
+{
+    int k = kind();
+    if (k == UMAT)
+    {
+        m.copyTo(*(UMat*)obj); // TODO check m.getUMat()
+    }
+    else if (k == MAT)
+    {
+        *(Mat*)obj = m;
+    }
+    else
+    {
+        CV_Error(Error::StsNotImplemented, "");
+    }
+}
+
+
 static _InputOutputArray _none;
 InputOutputArray noArray() { return _none; }
 
index 2c48f2f..b647c0f 100644 (file)
@@ -98,8 +98,8 @@ public:
     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)
+    const cv::UMat& matchingMask() const { return matching_mask_; }
+    void setMatchingMask(const cv::UMat &mask)
     {
         CV_Assert(mask.type() == CV_8U && mask.cols == mask.rows);
         matching_mask_ = mask.clone();
@@ -127,14 +127,14 @@ public:
     const Ptr<detail::Blender> blender() const { return blender_; }
     void setBlender(Ptr<detail::Blender> b) { blender_ = b; }
 
-    Status estimateTransform(InputArray images);
-    Status estimateTransform(InputArray images, const std::vector<std::vector<Rect> > &rois);
+    Status estimateTransform(InputArrayOfArrays images);
+    Status estimateTransform(InputArrayOfArrays images, const std::vector<std::vector<Rect> > &rois);
 
     Status composePanorama(OutputArray pano);
-    Status composePanorama(InputArray images, OutputArray pano);
+    Status composePanorama(InputArrayOfArrays images, OutputArray pano);
 
-    Status stitch(InputArray images, OutputArray pano);
-    Status stitch(InputArray images, const std::vector<std::vector<Rect> > &rois, OutputArray pano);
+    Status stitch(InputArrayOfArrays images, OutputArray pano);
+    Status stitch(InputArrayOfArrays images, const std::vector<std::vector<Rect> > &rois, OutputArray pano);
 
     std::vector<int> component() const { return indices_; }
     std::vector<detail::CameraParams> cameras() const { return cameras_; }
@@ -152,7 +152,7 @@ private:
     double conf_thresh_;
     Ptr<detail::FeaturesFinder> features_finder_;
     Ptr<detail::FeaturesMatcher> features_matcher_;
-    cv::Mat matching_mask_;
+    cv::UMat matching_mask_;
     Ptr<detail::BundleAdjusterBase> bundle_adjuster_;
     bool do_wave_correct_;
     detail::WaveCorrectKind wave_correct_kind_;
@@ -161,12 +161,12 @@ private:
     Ptr<detail::SeamFinder> seam_finder_;
     Ptr<detail::Blender> blender_;
 
-    std::vector<cv::Mat> imgs_;
+    std::vector<cv::UMat> imgs_;
     std::vector<std::vector<cv::Rect> > rois_;
     std::vector<cv::Size> full_img_sizes_;
     std::vector<detail::ImageFeatures> features_;
     std::vector<detail::MatchesInfo> pairwise_matches_;
-    std::vector<cv::Mat> seam_est_imgs_;
+    std::vector<cv::UMat> seam_est_imgs_;
     std::vector<int> indices_;
     std::vector<detail::CameraParams> cameras_;
     double work_scale_;
index 8d47d32..f91a0ea 100644 (file)
@@ -60,11 +60,11 @@ public:
 
     void prepare(const std::vector<Point> &corners, const std::vector<Size> &sizes);
     virtual void prepare(Rect dst_roi);
-    virtual void feed(const Mat &img, const Mat &mask, Point tl);
-    virtual void blend(Mat &dst, Mat &dst_mask);
+    virtual void feed(InputArray img, InputArray mask, Point tl);
+    virtual void blend(InputOutputArray dst, InputOutputArray dst_mask);
 
 protected:
-    Mat dst_, dst_mask_;
+    UMat dst_, dst_mask_;
     Rect dst_roi_;
 };
 
@@ -78,18 +78,18 @@ public:
     void setSharpness(float val) { sharpness_ = val; }
 
     void prepare(Rect dst_roi);
-    void feed(const Mat &img, const Mat &mask, Point tl);
-    void blend(Mat &dst, Mat &dst_mask);
+    void feed(InputArray img, InputArray mask, Point tl);
+    void blend(InputOutputArray dst, InputOutputArray dst_mask);
 
     // Creates weight maps for fixed set of source images by their masks and top-left corners.
     // Final image can be obtained by simple weighting of the source images.
-    Rect createWeightMaps(const std::vector<Mat> &masks, const std::vector<Point> &corners,
-                          std::vector<Mat> &weight_maps);
+    Rect createWeightMaps(const std::vector<UMat> &masks, const std::vector<Point> &corners,
+                          std::vector<UMat> &weight_maps);
 
 private:
     float sharpness_;
-    Mat weight_map_;
-    Mat dst_weight_map_;
+    UMat weight_map_;
+    UMat dst_weight_map_;
 };
 
 inline FeatherBlender::FeatherBlender(float _sharpness) { setSharpness(_sharpness); }
@@ -104,13 +104,13 @@ public:
     void setNumBands(int val) { actual_num_bands_ = val; }
 
     void prepare(Rect dst_roi);
-    void feed(const Mat &img, const Mat &mask, Point tl);
-    void blend(Mat &dst, Mat &dst_mask);
+    void feed(InputArray img, InputArray mask, Point tl);
+    void blend(InputOutputArray dst, InputOutputArray dst_mask);
 
 private:
     int actual_num_bands_, num_bands_;
-    std::vector<Mat> dst_pyr_laplace_;
-    std::vector<Mat> dst_band_weights_;
+    std::vector<UMat> dst_pyr_laplace_;
+    std::vector<UMat> dst_band_weights_;
     Rect dst_roi_final_;
     bool can_use_gpu_;
     int weight_type_; //CV_32F or CV_16S
@@ -120,16 +120,16 @@ private:
 //////////////////////////////////////////////////////////////////////////////
 // Auxiliary functions
 
-void CV_EXPORTS normalizeUsingWeightMap(const Mat& weight, Mat& src);
+void CV_EXPORTS normalizeUsingWeightMap(InputArray weight, InputOutputArray src);
 
-void CV_EXPORTS createWeightMap(const Mat& mask, float sharpness, Mat& weight);
+void CV_EXPORTS createWeightMap(InputArray mask, float sharpness, InputOutputArray weight);
 
-void CV_EXPORTS createLaplacePyr(const Mat &img, int num_levels, std::vector<Mat>& pyr);
-void CV_EXPORTS createLaplacePyrGpu(const Mat &img, int num_levels, std::vector<Mat>& pyr);
+void CV_EXPORTS createLaplacePyr(InputArray img, int num_levels, std::vector<UMat>& pyr);
+void CV_EXPORTS createLaplacePyrGpu(InputArray img, int num_levels, std::vector<UMat>& pyr);
 
 // Restores source image
-void CV_EXPORTS restoreImageFromLaplacePyr(std::vector<Mat>& pyr);
-void CV_EXPORTS restoreImageFromLaplacePyrGpu(std::vector<Mat>& pyr);
+void CV_EXPORTS restoreImageFromLaplacePyr(std::vector<UMat>& pyr);
+void CV_EXPORTS restoreImageFromLaplacePyrGpu(std::vector<UMat>& pyr);
 
 } // namespace detail
 } // namespace cv
index 84a8ce4..5626b06 100644 (file)
@@ -56,29 +56,29 @@ public:
     enum { NO, GAIN, GAIN_BLOCKS };
     static Ptr<ExposureCompensator> createDefault(int type);
 
-    void feed(const std::vector<Point> &corners, const std::vector<Mat> &images,
-              const std::vector<Mat> &masks);
-    virtual void feed(const std::vector<Point> &corners, const std::vector<Mat> &images,
-                      const std::vector<std::pair<Mat,uchar> > &masks) = 0;
-    virtual void apply(int index, Point corner, Mat &image, const Mat &mask) = 0;
+    void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
+              const std::vector<UMat> &masks);
+    virtual void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
+                      const std::vector<std::pair<UMat,uchar> > &masks) = 0;
+    virtual void apply(int index, Point corner, InputOutputArray image, InputArray mask) = 0;
 };
 
 
 class CV_EXPORTS NoExposureCompensator : public ExposureCompensator
 {
 public:
-    void feed(const std::vector<Point> &/*corners*/, const std::vector<Mat> &/*images*/,
-              const std::vector<std::pair<Mat,uchar> > &/*masks*/) { }
-    void apply(int /*index*/, Point /*corner*/, Mat &/*image*/, const Mat &/*mask*/) { }
+    void feed(const std::vector<Point> &/*corners*/, const std::vector<UMat> &/*images*/,
+              const std::vector<std::pair<UMat,uchar> > &/*masks*/) { }
+    void apply(int /*index*/, Point /*corner*/, InputOutputArray /*image*/, InputArray /*mask*/) { }
 };
 
 
 class CV_EXPORTS GainCompensator : public ExposureCompensator
 {
 public:
-    void feed(const std::vector<Point> &corners, const std::vector<Mat> &images,
-              const std::vector<std::pair<Mat,uchar> > &masks);
-    void apply(int index, Point corner, Mat &image, const Mat &mask);
+    void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
+              const std::vector<std::pair<UMat,uchar> > &masks);
+    void apply(int index, Point corner, InputOutputArray image, InputArray mask);
     std::vector<double> gains() const;
 
 private:
@@ -91,9 +91,9 @@ class CV_EXPORTS BlocksGainCompensator : public ExposureCompensator
 public:
     BlocksGainCompensator(int bl_width = 32, int bl_height = 32)
             : bl_width_(bl_width), bl_height_(bl_height) {}
-    void feed(const std::vector<Point> &corners, const std::vector<Mat> &images,
-              const std::vector<std::pair<Mat,uchar> > &masks);
-    void apply(int index, Point corner, Mat &image, const Mat &mask);
+    void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
+              const std::vector<std::pair<UMat,uchar> > &masks);
+    void apply(int index, Point corner, InputOutputArray image, InputArray mask);
 
 private:
     int bl_width_, bl_height_;
index 02f8660..8c3284a 100644 (file)
@@ -60,7 +60,7 @@ struct CV_EXPORTS ImageFeatures
     int img_idx;
     Size img_size;
     std::vector<KeyPoint> keypoints;
-    Mat descriptors;
+    UMat descriptors;
 };
 
 
@@ -68,12 +68,12 @@ 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);
+    void operator ()(InputArray image, ImageFeatures &features);
+    void operator ()(InputArray image, ImageFeatures &features, const std::vector<cv::Rect> &rois);
     virtual void collectGarbage() {}
 
 protected:
-    virtual void find(const Mat &image, ImageFeatures &features) = 0;
+    virtual void find(InputArray image, ImageFeatures &features) = 0;
 };
 
 
@@ -84,7 +84,7 @@ public:
                        int num_octaves_descr = /*4*/3, int num_layers_descr = /*2*/4);
 
 private:
-    void find(const Mat &image, ImageFeatures &features);
+    void find(InputArray image, ImageFeatures &features);
 
     Ptr<FeatureDetector> detector_;
     Ptr<DescriptorExtractor> extractor_;
@@ -97,7 +97,7 @@ public:
     OrbFeaturesFinder(Size _grid_size = Size(3,1), int nfeatures=1500, float scaleFactor=1.3f, int nlevels=5);
 
 private:
-    void find(const Mat &image, ImageFeatures &features);
+    void find(InputArray image, ImageFeatures &features);
 
     Ptr<ORB> orb;
     Size grid_size;
@@ -114,7 +114,7 @@ public:
     void collectGarbage();
 
 private:
-    void find(const Mat &image, ImageFeatures &features);
+    void find(InputArray image, ImageFeatures &features);
 
     cuda::GpuMat image_;
     cuda::GpuMat gray_image_;
@@ -151,7 +151,7 @@ public:
                      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());
+                     const cv::UMat &mask = cv::UMat());
 
     bool isThreadSafe() const { return is_thread_safe_; }
 
index 24b7db6..5f085c1 100644 (file)
@@ -54,32 +54,32 @@ class CV_EXPORTS SeamFinder
 {
 public:
     virtual ~SeamFinder() {}
-    virtual void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
-                      std::vector<Mat> &masks) = 0;
+    virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+                      std::vector<UMat> &masks) = 0;
 };
 
 
 class CV_EXPORTS NoSeamFinder : public SeamFinder
 {
 public:
-    void find(const std::vector<Mat>&, const std::vector<Point>&, std::vector<Mat>&) {}
+    void find(const std::vector<UMat>&, const std::vector<Point>&, std::vector<UMat>&) {}
 };
 
 
 class CV_EXPORTS PairwiseSeamFinder : public SeamFinder
 {
 public:
-    virtual void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
-                      std::vector<Mat> &masks);
+    virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+                      std::vector<UMat> &masks);
 
 protected:
     void run();
     virtual void findInPair(size_t first, size_t second, Rect roi) = 0;
 
-    std::vector<Mat> images_;
+    std::vector<UMat> images_;
     std::vector<Size> sizes_;
     std::vector<Point> corners_;
-    std::vector<Mat> masks_;
+    std::vector<UMat> masks_;
 };
 
 
@@ -87,7 +87,7 @@ class CV_EXPORTS VoronoiSeamFinder : public PairwiseSeamFinder
 {
 public:
     virtual void find(const std::vector<Size> &size, const std::vector<Point> &corners,
-                      std::vector<Mat> &masks);
+                      std::vector<UMat> &masks);
 private:
     void findInPair(size_t first, size_t second, Rect roi);
 };
@@ -103,8 +103,8 @@ public:
     CostFunction costFunction() const { return costFunc_; }
     void setCostFunction(CostFunction val) { costFunc_ = val; }
 
-    virtual void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
-                      std::vector<Mat> &masks);
+    virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+                      std::vector<UMat> &masks);
 
 private:
     enum ComponentState
@@ -154,7 +154,7 @@ private:
     };
 
     void process(
-            const Mat &image1, const Mat &image2, Point tl1, Point tl2, Mat &mask1, Mat &mask2);
+            const Mat &image1, const Mat &image2, Point tl1, Point tl2,  Mat &mask1, Mat &mask2);
 
     void findComponents();
 
@@ -217,8 +217,8 @@ public:
 
     ~GraphCutSeamFinder();
 
-    void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
-              std::vector<Mat> &masks);
+    void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+              std::vector<UMat> &masks);
 
 private:
     // To avoid GCGraph dependency
@@ -236,8 +236,8 @@ public:
                           : cost_type_(cost_type), terminal_cost_(terminal_cost),
                             bad_region_penalty_(bad_region_penalty) {}
 
-    void find(const std::vector<cv::Mat> &src, const std::vector<cv::Point> &corners,
-              std::vector<cv::Mat> &masks);
+    void find(const std::vector<cv::UMat> &src, const std::vector<cv::Point> &corners,
+              std::vector<cv::UMat> &masks);
     void findInPair(size_t first, size_t second, Rect roi);
 
 private:
index 6f334b9..561880c 100644 (file)
@@ -145,7 +145,7 @@ private:
 // Auxiliary functions
 
 CV_EXPORTS bool overlapRoi(Point tl1, Point tl2, Size sz1, Size sz2, Rect &roi);
-CV_EXPORTS Rect resultRoi(const std::vector<Point> &corners, const std::vector<Mat> &images);
+CV_EXPORTS Rect resultRoi(const std::vector<Point> &corners, const std::vector<UMat> &images);
 CV_EXPORTS Rect resultRoi(const std::vector<Point> &corners, const std::vector<Size> &sizes);
 CV_EXPORTS Point resultTl(const std::vector<Point> &corners);
 
index 446bfc1..5012d9b 100644 (file)
@@ -76,8 +76,13 @@ void Blender::prepare(Rect dst_roi)
 }
 
 
-void Blender::feed(const Mat &img, const Mat &mask, Point tl)
+void Blender::feed(InputArray _img, InputArray _mask, Point tl)
 {
+    Mat img = _img.getMat();
+    Mat mask = _mask.getMat();
+    Mat dst = dst_.getMat(ACCESS_RW);
+    Mat dst_mask = dst_mask_.getMat(ACCESS_RW);
+
     CV_Assert(img.type() == CV_16SC3);
     CV_Assert(mask.type() == CV_8U);
     int dx = tl.x - dst_roi_.x;
@@ -86,9 +91,9 @@ void Blender::feed(const Mat &img, const Mat &mask, Point tl)
     for (int y = 0; y < img.rows; ++y)
     {
         const Point3_<short> *src_row = img.ptr<Point3_<short> >(y);
-        Point3_<short> *dst_row = dst_.ptr<Point3_<short> >(dy + y);
+        Point3_<short> *dst_row = dst.ptr<Point3_<short> >(dy + y);
         const uchar *mask_row = mask.ptr<uchar>(y);
-        uchar *dst_mask_row = dst_mask_.ptr<uchar>(dy + y);
+        uchar *dst_mask_row = dst_mask.ptr<uchar>(dy + y);
 
         for (int x = 0; x < img.cols; ++x)
         {
@@ -100,11 +105,11 @@ void Blender::feed(const Mat &img, const Mat &mask, Point tl)
 }
 
 
-void Blender::blend(Mat &dst, Mat &dst_mask)
+void Blender::blend(InputOutputArray dst, InputOutputArray dst_mask)
 {
-    dst_.setTo(Scalar::all(0), dst_mask_ == 0);
-    dst = dst_;
-    dst_mask = dst_mask_;
+    dst_.setTo(Scalar::all(0), dst_mask_.getMat(ACCESS_READ) == 0); // TODO
+    dst.assign(dst_);
+    dst_mask.assign(dst_mask_);
     dst_.release();
     dst_mask_.release();
 }
@@ -118,21 +123,27 @@ void FeatherBlender::prepare(Rect dst_roi)
 }
 
 
-void FeatherBlender::feed(const Mat &img, const Mat &mask, Point tl)
+void FeatherBlender::feed(InputArray _img, InputArray mask, Point tl)
 {
+    Mat img = _img.getMat();
+    Mat dst = dst_.getMat(ACCESS_RW);
+
     CV_Assert(img.type() == CV_16SC3);
     CV_Assert(mask.type() == CV_8U);
 
     createWeightMap(mask, sharpness_, weight_map_);
+    Mat weight_map = weight_map_.getMat(ACCESS_READ);
+    Mat dst_weight_map = dst_weight_map_.getMat(ACCESS_RW);
+
     int dx = tl.x - dst_roi_.x;
     int dy = tl.y - dst_roi_.y;
 
     for (int y = 0; y < img.rows; ++y)
     {
         const Point3_<short>* src_row = img.ptr<Point3_<short> >(y);
-        Point3_<short>* dst_row = dst_.ptr<Point3_<short> >(dy + y);
-        const float* weight_row = weight_map_.ptr<float>(y);
-        float* dst_weight_row = dst_weight_map_.ptr<float>(dy + y);
+        Point3_<short>* dst_row = dst.ptr<Point3_<short> >(dy + y);
+        const float* weight_row = weight_map.ptr<float>(y);
+        float* dst_weight_row = dst_weight_map.ptr<float>(dy + y);
 
         for (int x = 0; x < img.cols; ++x)
         {
@@ -145,16 +156,16 @@ void FeatherBlender::feed(const Mat &img, const Mat &mask, Point tl)
 }
 
 
-void FeatherBlender::blend(Mat &dst, Mat &dst_mask)
+void FeatherBlender::blend(InputOutputArray dst, InputOutputArray dst_mask)
 {
     normalizeUsingWeightMap(dst_weight_map_, dst_);
-    dst_mask_ = dst_weight_map_ > WEIGHT_EPS;
+    dst_mask_ = ((Mat)(dst_weight_map_.getMat(ACCESS_READ) > WEIGHT_EPS)).getUMat(ACCESS_READ);
     Blender::blend(dst, dst_mask);
 }
 
 
-Rect FeatherBlender::createWeightMaps(const std::vector<Mat> &masks, const std::vector<Point> &corners,
-                                      std::vector<Mat> &weight_maps)
+Rect FeatherBlender::createWeightMaps(const std::vector<UMat> &masks, const std::vector<Point> &corners,
+                                      std::vector<UMat> &weight_maps)
 {
     weight_maps.resize(masks.size());
     for (size_t i = 0; i < masks.size(); ++i)
@@ -168,7 +179,7 @@ Rect FeatherBlender::createWeightMaps(const std::vector<Mat> &masks, const std::
     {
         Rect roi(corners[i].x - dst_roi.x, corners[i].y - dst_roi.y,
                  weight_maps[i].cols, weight_maps[i].rows);
-        weights_sum(roi) += weight_maps[i];
+        add(weights_sum(roi), weight_maps[i], weights_sum(roi));
     }
 
     for (size_t i = 0; i < weight_maps.size(); ++i)
@@ -233,8 +244,9 @@ void MultiBandBlender::prepare(Rect dst_roi)
 }
 
 
-void MultiBandBlender::feed(const Mat &img, const Mat &mask, Point tl)
+void MultiBandBlender::feed(InputArray _img, InputArray mask, Point tl)
 {
+    Mat img = _img.getMat();
     CV_Assert(img.type() == CV_16SC3 || img.type() == CV_8UC3);
     CV_Assert(mask.type() == CV_8U);
 
@@ -269,27 +281,27 @@ void MultiBandBlender::feed(const Mat &img, const Mat &mask, Point tl)
     int right = br_new.x - tl.x - img.cols;
 
     // Create the source image Laplacian pyramid
-    Mat img_with_border;
-    copyMakeBorder(img, img_with_border, top, bottom, left, right,
+    UMat img_with_border;
+    copyMakeBorder(_img, img_with_border, top, bottom, left, right,
                    BORDER_REFLECT);
-    std::vector<Mat> src_pyr_laplace;
+    std::vector<UMat> src_pyr_laplace;
     if (can_use_gpu_ && img_with_border.depth() == CV_16S)
         createLaplacePyrGpu(img_with_border, num_bands_, src_pyr_laplace);
     else
         createLaplacePyr(img_with_border, num_bands_, src_pyr_laplace);
 
     // Create the weight map Gaussian pyramid
-    Mat weight_map;
-    std::vector<Mat> weight_pyr_gauss(num_bands_ + 1);
+    UMat weight_map;
+    std::vector<UMat> weight_pyr_gauss(num_bands_ + 1);
 
     if(weight_type_ == CV_32F)
     {
-        mask.convertTo(weight_map, CV_32F, 1./255.);
+        mask.getUMat().convertTo(weight_map, CV_32F, 1./255.);
     }
-    else// weight_type_ == CV_16S
+    else // weight_type_ == CV_16S
     {
-        mask.convertTo(weight_map, CV_16S);
-        add(weight_map, 1, weight_map, mask != 0);
+        mask.getUMat().convertTo(weight_map, CV_16S);
+        add(weight_map, Scalar::all(1), weight_map, mask.getMat(ACCESS_READ) != 0); // TODO
     }
 
     copyMakeBorder(weight_map, weight_pyr_gauss[0], top, bottom, left, right, BORDER_CONSTANT);
@@ -307,13 +319,17 @@ void MultiBandBlender::feed(const Mat &img, const Mat &mask, Point tl)
     {
         for (int i = 0; i <= num_bands_; ++i)
         {
+            Mat _src_pyr_laplace = src_pyr_laplace[i].getMat(ACCESS_READ);
+            Mat _dst_pyr_laplace = dst_pyr_laplace_[i].getMat(ACCESS_RW);
+            Mat _weight_pyr_gauss = weight_pyr_gauss[i].getMat(ACCESS_READ);
+            Mat _dst_band_weights = dst_band_weights_[i].getMat(ACCESS_RW);
             for (int y = y_tl; y < y_br; ++y)
             {
                 int y_ = y - y_tl;
-                const Point3_<short>* src_row = src_pyr_laplace[i].ptr<Point3_<short> >(y_);
-                Point3_<short>* dst_row = dst_pyr_laplace_[i].ptr<Point3_<short> >(y);
-                const float* weight_row = weight_pyr_gauss[i].ptr<float>(y_);
-                float* dst_weight_row = dst_band_weights_[i].ptr<float>(y);
+                const Point3_<short>* src_row = _src_pyr_laplace.ptr<Point3_<short> >(y_);
+                Point3_<short>* dst_row = _dst_pyr_laplace.ptr<Point3_<short> >(y);
+                const float* weight_row = _weight_pyr_gauss.ptr<float>(y_);
+                float* dst_weight_row = _dst_band_weights.ptr<float>(y);
 
                 for (int x = x_tl; x < x_br; ++x)
                 {
@@ -332,13 +348,17 @@ void MultiBandBlender::feed(const Mat &img, const Mat &mask, Point tl)
     {
         for (int i = 0; i <= num_bands_; ++i)
         {
+            Mat _src_pyr_laplace = src_pyr_laplace[i].getMat(ACCESS_READ);
+            Mat _dst_pyr_laplace = dst_pyr_laplace_[i].getMat(ACCESS_RW);
+            Mat _weight_pyr_gauss = weight_pyr_gauss[i].getMat(ACCESS_READ);
+            Mat _dst_band_weights = dst_band_weights_[i].getMat(ACCESS_RW);
             for (int y = y_tl; y < y_br; ++y)
             {
                 int y_ = y - y_tl;
-                const Point3_<short>* src_row = src_pyr_laplace[i].ptr<Point3_<short> >(y_);
-                Point3_<short>* dst_row = dst_pyr_laplace_[i].ptr<Point3_<short> >(y);
-                const short* weight_row = weight_pyr_gauss[i].ptr<short>(y_);
-                short* dst_weight_row = dst_band_weights_[i].ptr<short>(y);
+                const Point3_<short>* src_row = _src_pyr_laplace.ptr<Point3_<short> >(y_);
+                Point3_<short>* dst_row = _dst_pyr_laplace.ptr<Point3_<short> >(y);
+                const short* weight_row = _weight_pyr_gauss.ptr<short>(y_);
+                short* dst_weight_row = _dst_band_weights.ptr<short>(y);
 
                 for (int x = x_tl; x < x_br; ++x)
                 {
@@ -356,7 +376,7 @@ void MultiBandBlender::feed(const Mat &img, const Mat &mask, Point tl)
 }
 
 
-void MultiBandBlender::blend(Mat &dst, Mat &dst_mask)
+void MultiBandBlender::blend(InputOutputArray dst, InputOutputArray dst_mask)
 {
     for (int i = 0; i <= num_bands_; ++i)
         normalizeUsingWeightMap(dst_band_weights_[i], dst_pyr_laplace_[i]);
@@ -368,7 +388,7 @@ void MultiBandBlender::blend(Mat &dst, Mat &dst_mask)
 
     dst_ = dst_pyr_laplace_[0];
     dst_ = dst_(Range(0, dst_roi_final_.height), Range(0, dst_roi_final_.width));
-    dst_mask_ = dst_band_weights_[0] > WEIGHT_EPS;
+    dst_mask_ = ((Mat)(dst_band_weights_[0].getMat(ACCESS_READ) > WEIGHT_EPS)).getUMat(ACCESS_READ);
     dst_mask_ = dst_mask_(Range(0, dst_roi_final_.height), Range(0, dst_roi_final_.width));
     dst_pyr_laplace_.clear();
     dst_band_weights_.clear();
@@ -380,12 +400,15 @@ void MultiBandBlender::blend(Mat &dst, Mat &dst_mask)
 //////////////////////////////////////////////////////////////////////////////
 // Auxiliary functions
 
-void normalizeUsingWeightMap(const Mat& weight, Mat& src)
+void normalizeUsingWeightMap(InputArray _weight, InputOutputArray _src)
 {
 #ifdef HAVE_TEGRA_OPTIMIZATION
     if(tegra::normalizeUsingWeightMap(weight, src))
         return;
 #endif
+    Mat weight = _weight.getMat();
+    Mat src = _src.getMat();
+
     CV_Assert(src.type() == CV_16SC3);
 
     if(weight.type() == CV_32FC1)
@@ -424,15 +447,17 @@ void normalizeUsingWeightMap(const Mat& weight, Mat& src)
 }
 
 
-void createWeightMap(const Mat &mask, float sharpness, Mat &weight)
+void createWeightMap(InputArray mask, float sharpness, InputOutputArray weight)
 {
     CV_Assert(mask.type() == CV_8U);
     distanceTransform(mask, weight, DIST_L1, 3);
-    threshold(weight * sharpness, weight, 1.f, 1.f, THRESH_TRUNC);
+    UMat tmp;
+    multiply(weight, sharpness, tmp);
+    threshold(tmp, weight, 1.f, 1.f, THRESH_TRUNC);
 }
 
 
-void createLaplacePyr(const Mat &img, int num_levels, std::vector<Mat> &pyr)
+void createLaplacePyr(InputArray img, int num_levels, std::vector<UMat> &pyr)
 {
 #ifdef HAVE_TEGRA_OPTIMIZATION
     if(tegra::createLaplacePyr(img, num_levels, pyr))
@@ -445,18 +470,18 @@ void createLaplacePyr(const Mat &img, int num_levels, std::vector<Mat> &pyr)
     {
         if(num_levels == 0)
         {
-            img.convertTo(pyr[0], CV_16S);
+            img.getUMat().convertTo(pyr[0], CV_16S);
             return;
         }
 
-        Mat downNext;
-        Mat current = img;
+        UMat downNext;
+        UMat current = img.getUMat();
         pyrDown(img, downNext);
 
         for(int i = 1; i < num_levels; ++i)
         {
-            Mat lvl_up;
-            Mat lvl_down;
+            UMat lvl_up;
+            UMat lvl_down;
 
             pyrDown(downNext, lvl_down);
             pyrUp(downNext, lvl_up, current.size());
@@ -467,7 +492,7 @@ void createLaplacePyr(const Mat &img, int num_levels, std::vector<Mat> &pyr)
         }
 
         {
-            Mat lvl_up;
+            UMat lvl_up;
             pyrUp(downNext, lvl_up, current.size());
             subtract(current, lvl_up, pyr[num_levels-1], noArray(), CV_16S);
 
@@ -476,10 +501,10 @@ void createLaplacePyr(const Mat &img, int num_levels, std::vector<Mat> &pyr)
     }
     else
     {
-        pyr[0] = img;
+        pyr[0] = img.getUMat();
         for (int i = 0; i < num_levels; ++i)
             pyrDown(pyr[i], pyr[i + 1]);
-        Mat tmp;
+        UMat tmp;
         for (int i = 0; i < num_levels; ++i)
         {
             pyrUp(pyr[i + 1], tmp, pyr[i].size());
@@ -489,7 +514,7 @@ void createLaplacePyr(const Mat &img, int num_levels, std::vector<Mat> &pyr)
 }
 
 
-void createLaplacePyrGpu(const Mat &img, int num_levels, std::vector<Mat> &pyr)
+void createLaplacePyrGpu(InputArray img, int num_levels, std::vector<UMat> &pyr)
 {
 #if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
     pyr.resize(num_levels + 1);
@@ -517,11 +542,11 @@ void createLaplacePyrGpu(const Mat &img, int num_levels, std::vector<Mat> &pyr)
 }
 
 
-void restoreImageFromLaplacePyr(std::vector<Mat> &pyr)
+void restoreImageFromLaplacePyr(std::vector<UMat> &pyr)
 {
     if (pyr.empty())
         return;
-    Mat tmp;
+    UMat tmp;
     for (size_t i = pyr.size() - 1; i > 0; --i)
     {
         pyrUp(pyr[i], tmp, pyr[i - 1].size());
@@ -530,7 +555,7 @@ void restoreImageFromLaplacePyr(std::vector<Mat> &pyr)
 }
 
 
-void restoreImageFromLaplacePyrGpu(std::vector<Mat> &pyr)
+void restoreImageFromLaplacePyrGpu(std::vector<UMat> &pyr)
 {
 #if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
     if (pyr.empty())
index 78ce6d3..32112d6 100644 (file)
@@ -58,18 +58,18 @@ Ptr<ExposureCompensator> ExposureCompensator::createDefault(int type)
 }
 
 
-void ExposureCompensator::feed(const std::vector<Point> &corners, const std::vector<Mat> &images,
-                               const std::vector<Mat> &masks)
+void ExposureCompensator::feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
+                               const std::vector<UMat> &masks)
 {
-    std::vector<std::pair<Mat,uchar> > level_masks;
+    std::vector<std::pair<UMat,uchar> > level_masks;
     for (size_t i = 0; i < masks.size(); ++i)
         level_masks.push_back(std::make_pair(masks[i], 255));
     feed(corners, images, level_masks);
 }
 
 
-void GainCompensator::feed(const std::vector<Point> &corners, const std::vector<Mat> &images,
-                           const std::vector<std::pair<Mat,uchar> > &masks)
+void GainCompensator::feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
+                           const std::vector<std::pair<UMat,uchar> > &masks)
 {
     LOGLN("Exposure compensation...");
 #if ENABLE_LOG
@@ -93,11 +93,11 @@ void GainCompensator::feed(const std::vector<Point> &corners, const std::vector<
             Rect roi;
             if (overlapRoi(corners[i], corners[j], images[i].size(), images[j].size(), roi))
             {
-                subimg1 = images[i](Rect(roi.tl() - corners[i], roi.br() - corners[i]));
-                subimg2 = images[j](Rect(roi.tl() - corners[j], roi.br() - corners[j]));
+                subimg1 = images[i](Rect(roi.tl() - corners[i], roi.br() - corners[i])).getMat(ACCESS_READ);
+                subimg2 = images[j](Rect(roi.tl() - corners[j], roi.br() - corners[j])).getMat(ACCESS_READ);
 
-                submask1 = masks[i].first(Rect(roi.tl() - corners[i], roi.br() - corners[i]));
-                submask2 = masks[j].first(Rect(roi.tl() - corners[j], roi.br() - corners[j]));
+                submask1 = masks[i].first(Rect(roi.tl() - corners[i], roi.br() - corners[i])).getMat(ACCESS_READ);
+                submask2 = masks[j].first(Rect(roi.tl() - corners[j], roi.br() - corners[j])).getMat(ACCESS_READ);
                 intersect = (submask1 == masks[i].second) & (submask2 == masks[j].second);
 
                 N(i, j) = N(j, i) = std::max(1, countNonZero(intersect));
@@ -145,9 +145,9 @@ void GainCompensator::feed(const std::vector<Point> &corners, const std::vector<
 }
 
 
-void GainCompensator::apply(int index, Point /*corner*/, Mat &image, const Mat &/*mask*/)
+void GainCompensator::apply(int index, Point /*corner*/, InputOutputArray image, InputArray /*mask*/)
 {
-    image *= gains_(index, 0);
+    multiply(image, gains_(index, 0), image);
 }
 
 
@@ -160,8 +160,8 @@ std::vector<double> GainCompensator::gains() const
 }
 
 
-void BlocksGainCompensator::feed(const std::vector<Point> &corners, const std::vector<Mat> &images,
-                                     const std::vector<std::pair<Mat,uchar> > &masks)
+void BlocksGainCompensator::feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
+                                     const std::vector<std::pair<UMat,uchar> > &masks)
 {
     CV_Assert(corners.size() == images.size() && images.size() == masks.size());
 
@@ -169,8 +169,8 @@ void BlocksGainCompensator::feed(const std::vector<Point> &corners, const std::v
 
     std::vector<Size> bl_per_imgs(num_images);
     std::vector<Point> block_corners;
-    std::vector<Mat> block_images;
-    std::vector<std::pair<Mat,uchar> > block_masks;
+    std::vector<UMat> block_images;
+    std::vector<std::pair<UMat,uchar> > block_masks;
 
     // Construct blocks for gain compensator
     for (int img_idx = 0; img_idx < num_images; ++img_idx)
@@ -220,8 +220,10 @@ void BlocksGainCompensator::feed(const std::vector<Point> &corners, const std::v
 }
 
 
-void BlocksGainCompensator::apply(int index, Point /*corner*/, Mat &image, const Mat &/*mask*/)
+void BlocksGainCompensator::apply(int index, Point /*corner*/, InputOutputArray _image, InputArray /*mask*/)
 {
+    Mat image = _image.getMat();
+
     CV_Assert(image.type() == CV_8UC3);
 
     Mat_<float> gain_map;
index f463518..1ce1fc3 100644 (file)
@@ -264,14 +264,14 @@ void GpuMatcher::collectGarbage()
 namespace cv {
 namespace detail {
 
-void FeaturesFinder::operator ()(const Mat &image, ImageFeatures &features)
+void FeaturesFinder::operator ()(InputArray  image, ImageFeatures &features)
 {
     find(image, features);
     features.img_size = image.size();
 }
 
 
-void FeaturesFinder::operator ()(const Mat &image, ImageFeatures &features, const std::vector<Rect> &rois)
+void FeaturesFinder::operator ()(InputArray image, ImageFeatures &features, const std::vector<Rect> &rois)
 {
     std::vector<ImageFeatures> roi_features(rois.size());
     size_t total_kps_count = 0;
@@ -279,7 +279,7 @@ void FeaturesFinder::operator ()(const Mat &image, ImageFeatures &features, cons
 
     for (size_t i = 0; i < rois.size(); ++i)
     {
-        find(image(rois[i]), roi_features[i]);
+        find(image.getUMat()(rois[i]), roi_features[i]);
         total_kps_count += roi_features[i].keypoints.size();
         total_descriptors_height += roi_features[i].descriptors.rows;
     }
@@ -300,7 +300,7 @@ void FeaturesFinder::operator ()(const Mat &image, ImageFeatures &features, cons
             features.keypoints[kp_idx].pt.x += (float)rois[i].x;
             features.keypoints[kp_idx].pt.y += (float)rois[i].y;
         }
-        Mat subdescr = features.descriptors.rowRange(
+        UMat subdescr = features.descriptors.rowRange(
                 descr_offset, descr_offset + roi_features[i].descriptors.rows);
         roi_features[i].descriptors.copyTo(subdescr);
         descr_offset += roi_features[i].descriptors.rows;
@@ -337,9 +337,9 @@ SurfFeaturesFinder::SurfFeaturesFinder(double hess_thresh, int num_octaves, int
     }
 }
 
-void SurfFeaturesFinder::find(const Mat &image, ImageFeatures &features)
+void SurfFeaturesFinder::find(InputArray image, ImageFeatures &features)
 {
-    Mat gray_image;
+    UMat gray_image;
     CV_Assert((image.type() == CV_8UC3) || (image.type() == CV_8UC1));
     if(image.type() == CV_8UC3)
     {
@@ -347,7 +347,7 @@ void SurfFeaturesFinder::find(const Mat &image, ImageFeatures &features)
     }
     else
     {
-        gray_image = image;
+        gray_image = image.getUMat();
     }
     if (!surf)
     {
@@ -356,7 +356,7 @@ void SurfFeaturesFinder::find(const Mat &image, ImageFeatures &features)
     }
     else
     {
-        Mat descriptors;
+        UMat descriptors;
         (*surf)(gray_image, Mat(), features.keypoints, descriptors);
         features.descriptors = descriptors.reshape(1, (int)features.keypoints.size());
     }
@@ -368,9 +368,9 @@ OrbFeaturesFinder::OrbFeaturesFinder(Size _grid_size, int n_features, float scal
     orb = makePtr<ORB>(n_features * (99 + grid_size.area())/100/grid_size.area(), scaleFactor, nlevels);
 }
 
-void OrbFeaturesFinder::find(const Mat &image, ImageFeatures &features)
+void OrbFeaturesFinder::find(InputArray image, ImageFeatures &features)
 {
-    Mat gray_image;
+    UMat gray_image;
 
     CV_Assert((image.type() == CV_8UC3) || (image.type() == CV_8UC4) || (image.type() == CV_8UC1));
 
@@ -379,7 +379,7 @@ void OrbFeaturesFinder::find(const Mat &image, ImageFeatures &features)
     } else if (image.type() == CV_8UC4) {
         cvtColor(image, gray_image, COLOR_BGRA2GRAY);
     } else if (image.type() == CV_8UC1) {
-        gray_image=image;
+        gray_image = image.getUMat();
     } else {
         CV_Error(Error::StsUnsupportedFormat, "");
     }
@@ -392,7 +392,8 @@ void OrbFeaturesFinder::find(const Mat &image, ImageFeatures &features)
         features.descriptors.release();
 
         std::vector<KeyPoint> points;
-        Mat descriptors;
+        Mat _descriptors;
+        UMat descriptors;
 
         for (int r = 0; r < grid_size.height; ++r)
             for (int c = 0; c < grid_size.width; ++c)
@@ -408,13 +409,13 @@ void OrbFeaturesFinder::find(const Mat &image, ImageFeatures &features)
                 //     << " xl=" << xl << ", xr=" << xr << ", gray_image.data=" << ((size_t)gray_image.data) << ", "
                 //     << "gray_image.dims=" << gray_image.dims << "\n");
 
-                Mat gray_image_part=gray_image(Range(yl, yr), Range(xl, xr));
+                UMat gray_image_part=gray_image(Range(yl, yr), Range(xl, xr));
                 // LOGLN("OrbFeaturesFinder::find: gray_image_part.empty=" << (gray_image_part.empty()?"true":"false") << ", "
                 //     << " gray_image_part.size()=(" << gray_image_part.size().width << "x" << gray_image_part.size().height << "), "
                 //     << " gray_image_part.dims=" << gray_image_part.dims << ", "
                 //     << " gray_image_part.data=" << ((size_t)gray_image_part.data) << "\n");
 
-                (*orb)(gray_image_part, Mat(), points, descriptors);
+                (*orb)(gray_image_part, UMat(), points, descriptors);
 
                 features.keypoints.reserve(features.keypoints.size() + points.size());
                 for (std::vector<KeyPoint>::iterator kp = points.begin(); kp != points.end(); ++kp)
@@ -423,8 +424,10 @@ void OrbFeaturesFinder::find(const Mat &image, ImageFeatures &features)
                     kp->pt.y += yl;
                     features.keypoints.push_back(*kp);
                 }
-                features.descriptors.push_back(descriptors);
+                _descriptors.push_back(descriptors.getMat(ACCESS_READ));
             }
+
+        features.descriptors = _descriptors.getUMat(ACCESS_READ);
     }
 }
 
@@ -442,7 +445,7 @@ SurfFeaturesFinderGpu::SurfFeaturesFinderGpu(double hess_thresh, int num_octaves
 }
 
 
-void SurfFeaturesFinderGpu::find(const Mat &image, ImageFeatures &features)
+void SurfFeaturesFinderGpu::find(InputArray image, ImageFeatures &features)
 {
     CV_Assert(image.depth() == CV_8U);
 
@@ -499,12 +502,12 @@ const MatchesInfo& MatchesInfo::operator =(const MatchesInfo &other)
 //////////////////////////////////////////////////////////////////////////////
 
 void FeaturesMatcher::operator ()(const std::vector<ImageFeatures> &features, std::vector<MatchesInfo> &pairwise_matches,
-                                  const Mat &mask)
+                                  const UMat &mask)
 {
     const int num_images = static_cast<int>(features.size());
 
     CV_Assert(mask.empty() || (mask.type() == CV_8U && mask.cols == num_images && mask.rows));
-    Mat_<uchar> mask_(mask);
+    Mat_<uchar> mask_(mask.getMat(ACCESS_READ));
     if (mask_.empty())
         mask_ = Mat::ones(num_images, num_images, CV_8U);
 
index 2e5117e..4d5c8d1 100644 (file)
@@ -46,8 +46,8 @@
 namespace cv {
 namespace detail {
 
-void PairwiseSeamFinder::find(const std::vector<Mat> &src, const std::vector<Point> &corners,
-                              std::vector<Mat> &masks)
+void PairwiseSeamFinder::find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+                              std::vector<UMat> &masks)
 {
     LOGLN("Finding seams...");
     if (src.size() == 0)
@@ -84,7 +84,7 @@ void PairwiseSeamFinder::run()
 
 
 void VoronoiSeamFinder::find(const std::vector<Size> &sizes, const std::vector<Point> &corners,
-                             std::vector<Mat> &masks)
+                             std::vector<UMat> &masks)
 {
     LOGLN("Finding seams...");
     if (sizes.size() == 0)
@@ -110,7 +110,7 @@ void VoronoiSeamFinder::findInPair(size_t first, size_t second, Rect roi)
     Mat submask2(roi.height + 2 * gap, roi.width + 2 * gap, CV_8U);
 
     Size img1 = sizes_[first], img2 = sizes_[second];
-    Mat mask1 = masks_[first], mask2 = masks_[second];
+    Mat mask1 = masks_[first].getMat(ACCESS_READ), mask2 = masks_[second].getMat(ACCESS_READ);
     Point tl1 = corners_[first], tl2 = corners_[second];
 
     // Cut submasks with some gap
@@ -160,7 +160,7 @@ void VoronoiSeamFinder::findInPair(size_t first, size_t second, Rect roi)
 DpSeamFinder::DpSeamFinder(CostFunction costFunc) : costFunc_(costFunc) {}
 
 
-void DpSeamFinder::find(const std::vector<Mat> &src, const std::vector<Point> &corners, std::vector<Mat> &masks)
+void DpSeamFinder::find(const std::vector<UMat> &src, const std::vector<Point> &corners, std::vector<UMat> &masks)
 {
     LOGLN("Finding seams...");
 #if ENABLE_LOG
@@ -176,13 +176,18 @@ void DpSeamFinder::find(const std::vector<Mat> &src, const std::vector<Point> &c
         for (size_t j = i+1; j < src.size(); ++j)
             pairs.push_back(std::make_pair(i, j));
 
-    sort(pairs.begin(), pairs.end(), ImagePairLess(src, corners));
+    {
+        std::vector<Mat> _src(src.size());
+        for (size_t i = 0; i < src.size(); ++i) _src[i] = src[i].getMat(ACCESS_READ);
+        sort(pairs.begin(), pairs.end(), ImagePairLess(_src, corners));
+    }
     std::reverse(pairs.begin(), pairs.end());
 
     for (size_t i = 0; i < pairs.size(); ++i)
     {
         size_t i0 = pairs[i].first, i1 = pairs[i].second;
-        process(src[i0], src[i1], corners[i0], corners[i1], masks[i0], masks[i1]);
+        Mat mask0 = masks[i0].getMat(ACCESS_RW), mask1 = masks[i1].getMat(ACCESS_RW);
+        process(src[i0].getMat(ACCESS_READ), src[i1].getMat(ACCESS_READ), corners[i0], corners[i1], mask0, mask1);
     }
 
     LOGLN("Finding seams, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
@@ -1055,7 +1060,7 @@ public:
 
     ~Impl() {}
 
-    void find(const std::vector<Mat> &src, const std::vector<Point> &corners, std::vector<Mat> &masks);
+    void find(const std::vector<UMat> &src, const std::vector<Point> &corners, std::vector<UMat> &masks);
     void findInPair(size_t first, size_t second, Rect roi);
 
 private:
@@ -1072,8 +1077,8 @@ private:
 };
 
 
-void GraphCutSeamFinder::Impl::find(const std::vector<Mat> &src, const std::vector<Point> &corners,
-                                    std::vector<Mat> &masks)
+void GraphCutSeamFinder::Impl::find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+                                    std::vector<UMat> &masks)
 {
     // Compute gradients
     dx_.resize(src.size());
@@ -1207,10 +1212,10 @@ void GraphCutSeamFinder::Impl::setGraphWeightsColorGrad(
 
 void GraphCutSeamFinder::Impl::findInPair(size_t first, size_t second, Rect roi)
 {
-    Mat img1 = images_[first], img2 = images_[second];
+    Mat img1 = images_[first].getMat(ACCESS_READ), img2 = images_[second].getMat(ACCESS_READ);
     Mat dx1 = dx_[first], dx2 = dx_[second];
     Mat dy1 = dy_[first], dy2 = dy_[second];
-    Mat mask1 = masks_[first], mask2 = masks_[second];
+    Mat mask1 = masks_[first].getMat(ACCESS_RW), mask2 = masks_[second].getMat(ACCESS_RW);
     Point tl1 = corners_[first], tl2 = corners_[second];
 
     const int gap = 10;
@@ -1309,16 +1314,16 @@ GraphCutSeamFinder::GraphCutSeamFinder(int cost_type, float terminal_cost, float
 GraphCutSeamFinder::~GraphCutSeamFinder() {}
 
 
-void GraphCutSeamFinder::find(const std::vector<Mat> &src, const std::vector<Point> &corners,
-                              std::vector<Mat> &masks)
+void GraphCutSeamFinder::find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+                              std::vector<UMat> &masks)
 {
     impl_->find(src, corners, masks);
 }
 
 
 #ifdef HAVE_OPENCV_CUDA
-void GraphCutSeamFinderGpu::find(const std::vector<Mat> &src, const std::vector<Point> &corners,
-                                 std::vector<Mat> &masks)
+void GraphCutSeamFinderGpu::find(const std::vector<UMat> &src, const std::vector<Point> &corners,
+                                 std::vector<UMat> &masks)
 {
     // Compute gradients
     dx_.resize(src.size());
@@ -1350,10 +1355,10 @@ void GraphCutSeamFinderGpu::find(const std::vector<Mat> &src, const std::vector<
 
 void GraphCutSeamFinderGpu::findInPair(size_t first, size_t second, Rect roi)
 {
-    Mat img1 = images_[first], img2 = images_[second];
+    Mat img1 = images_[first].getMat(ACCESS_READ), img2 = images_[second].getMat(ACCESS_READ);
     Mat dx1 = dx_[first], dx2 = dx_[second];
     Mat dy1 = dy_[first], dy2 = dy_[second];
-    Mat mask1 = masks_[first], mask2 = masks_[second];
+    Mat mask1 = masks_[first].getMat(ACCESS_READ), mask2 = masks_[second].getMat(ACCESS_READ);
     Point tl1 = corners_[first], tl2 = corners_[second];
 
     const int gap = 10;
index 5683ec3..ae46726 100644 (file)
@@ -86,15 +86,15 @@ Stitcher Stitcher::createDefault(bool try_use_gpu)
 }
 
 
-Stitcher::Status Stitcher::estimateTransform(InputArray images)
+Stitcher::Status Stitcher::estimateTransform(InputArrayOfArrays images)
 {
     return estimateTransform(images, std::vector<std::vector<Rect> >());
 }
 
 
-Stitcher::Status Stitcher::estimateTransform(InputArray images, const std::vector<std::vector<Rect> > &rois)
+Stitcher::Status Stitcher::estimateTransform(InputArrayOfArrays images, const std::vector<std::vector<Rect> > &rois)
 {
-    images.getMatVector(imgs_);
+    images.getUMatVector(imgs_);
     rois_ = rois;
 
     Status status;
@@ -112,21 +112,21 @@ Stitcher::Status Stitcher::estimateTransform(InputArray images, const std::vecto
 
 Stitcher::Status Stitcher::composePanorama(OutputArray pano)
 {
-    return composePanorama(std::vector<Mat>(), pano);
+    return composePanorama(std::vector<UMat>(), pano);
 }
 
 
-Stitcher::Status Stitcher::composePanorama(InputArray images, OutputArray pano)
+Stitcher::Status Stitcher::composePanorama(InputArrayOfArrays images, OutputArray pano)
 {
     LOGLN("Warping images (auxiliary)... ");
 
-    std::vector<Mat> imgs;
-    images.getMatVector(imgs);
+    std::vector<UMat> imgs;
+    images.getUMatVector(imgs);
     if (!imgs.empty())
     {
         CV_Assert(imgs.size() == imgs_.size());
 
-        Mat img;
+        UMat img;
         seam_est_imgs_.resize(imgs.size());
 
         for (size_t i = 0; i < imgs.size(); ++i)
@@ -136,8 +136,8 @@ Stitcher::Status Stitcher::composePanorama(InputArray images, OutputArray pano)
             seam_est_imgs_[i] = img.clone();
         }
 
-        std::vector<Mat> seam_est_imgs_subset;
-        std::vector<Mat> imgs_subset;
+        std::vector<UMat> seam_est_imgs_subset;
+        std::vector<UMat> imgs_subset;
 
         for (size_t i = 0; i < indices_.size(); ++i)
         {
@@ -149,17 +149,17 @@ Stitcher::Status Stitcher::composePanorama(InputArray images, OutputArray pano)
         imgs_ = imgs_subset;
     }
 
-    Mat &pano_ = pano.getMatRef();
+    UMat pano_;
 
 #if ENABLE_LOG
     int64 t = getTickCount();
 #endif
 
     std::vector<Point> corners(imgs_.size());
-    std::vector<Mat> masks_warped(imgs_.size());
-    std::vector<Mat> images_warped(imgs_.size());
+    std::vector<UMat> masks_warped(imgs_.size());
+    std::vector<UMat> images_warped(imgs_.size());
     std::vector<Size> sizes(imgs_.size());
-    std::vector<Mat> masks(imgs_.size());
+    std::vector<UMat> masks(imgs_.size());
 
     // Prepare image masks
     for (size_t i = 0; i < imgs_.size(); ++i)
@@ -185,7 +185,7 @@ Stitcher::Status Stitcher::composePanorama(InputArray images, OutputArray pano)
         w->warp(masks[i], K, cameras_[i].R, INTER_NEAREST, BORDER_CONSTANT, masks_warped[i]);
     }
 
-    std::vector<Mat> images_warped_f(imgs_.size());
+    std::vector<UMat> images_warped_f(imgs_.size());
     for (size_t i = 0; i < imgs_.size(); ++i)
         images_warped[i].convertTo(images_warped_f[i], CV_32F);
 
@@ -206,8 +206,8 @@ Stitcher::Status Stitcher::composePanorama(InputArray images, OutputArray pano)
     t = getTickCount();
 #endif
 
-    Mat img_warped, img_warped_s;
-    Mat dilated_mask, seam_mask, mask, mask_warped;
+    UMat img_warped, img_warped_s;
+    UMat dilated_mask, seam_mask, mask, mask_warped;
 
     //double compose_seam_aspect = 1;
     double compose_work_aspect = 1;
@@ -216,7 +216,7 @@ Stitcher::Status Stitcher::composePanorama(InputArray images, OutputArray pano)
     double compose_scale = 1;
     bool is_compose_scale_set = false;
 
-    Mat full_img, img;
+    UMat full_img, img;
     for (size_t img_idx = 0; img_idx < imgs_.size(); ++img_idx)
     {
         LOGLN("Compositing image #" << indices_[img_idx] + 1);
@@ -290,7 +290,7 @@ Stitcher::Status Stitcher::composePanorama(InputArray images, OutputArray pano)
         dilate(masks_warped[img_idx], dilated_mask, Mat());
         resize(dilated_mask, seam_mask, mask_warped.size());
 
-        mask_warped = seam_mask & mask_warped;
+        bitwise_and(seam_mask, mask_warped, mask_warped);
 
         if (!is_blender_prepared)
         {
@@ -302,7 +302,7 @@ Stitcher::Status Stitcher::composePanorama(InputArray images, OutputArray pano)
         blender_->feed(img_warped_s, mask_warped, corners[img_idx]);
     }
 
-    Mat result, result_mask;
+    UMat result, result_mask;
     blender_->blend(result, result_mask);
 
     LOGLN("Compositing, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
@@ -311,11 +311,13 @@ Stitcher::Status Stitcher::composePanorama(InputArray images, OutputArray pano)
     // so convert it to avoid user confusing
     result.convertTo(pano_, CV_8U);
 
+    pano.assign(pano_);
+
     return OK;
 }
 
 
-Stitcher::Status Stitcher::stitch(InputArray images, OutputArray pano)
+Stitcher::Status Stitcher::stitch(InputArrayOfArrays images, OutputArray pano)
 {
     Status status = estimateTransform(images);
     if (status != OK)
@@ -324,7 +326,7 @@ Stitcher::Status Stitcher::stitch(InputArray images, OutputArray pano)
 }
 
 
-Stitcher::Status Stitcher::stitch(InputArray images, const std::vector<std::vector<Rect> > &rois, OutputArray pano)
+Stitcher::Status Stitcher::stitch(InputArrayOfArrays images, const std::vector<std::vector<Rect> > &rois, OutputArray pano)
 {
     Status status = estimateTransform(images, rois);
     if (status != OK)
@@ -346,7 +348,7 @@ Stitcher::Status Stitcher::matchImages()
     seam_scale_ = 1;
     bool is_work_scale_set = false;
     bool is_seam_scale_set = false;
-    Mat full_img, img;
+    UMat full_img, img;
     features_.resize(imgs_.size());
     seam_est_imgs_.resize(imgs_.size());
     full_img_sizes_.resize(imgs_.size());
@@ -420,8 +422,8 @@ Stitcher::Status Stitcher::matchImages()
 
     // Leave only images we are sure are from the same panorama
     indices_ = detail::leaveBiggestComponent(features_, pairwise_matches_, (float)conf_thresh_);
-    std::vector<Mat> seam_est_imgs_subset;
-    std::vector<Mat> imgs_subset;
+    std::vector<UMat> seam_est_imgs_subset;
+    std::vector<UMat> imgs_subset;
     std::vector<Size> full_img_sizes_subset;
     for (size_t i = 0; i < indices_.size(); ++i)
     {
index f6abf9e..5e026f0 100644 (file)
@@ -113,7 +113,7 @@ bool overlapRoi(Point tl1, Point tl2, Size sz1, Size sz2, Rect &roi)
 }
 
 
-Rect resultRoi(const std::vector<Point> &corners, const std::vector<Mat> &images)
+Rect resultRoi(const std::vector<Point> &corners, const std::vector<UMat> &images)
 {
     std::vector<Size> sizes(images.size());
     for (size_t i = 0; i < images.size(); ++i)
index 5eb3df4..93389a9 100644 (file)
@@ -348,7 +348,9 @@ int main(int argc, char* argv[])
     int64 app_start_time = getTickCount();
 #endif
 
+#if 0
     cv::setBreakOnError(true);
+#endif
 
     int retval = parseCmdArgs(argc, argv);
     if (retval)
@@ -554,10 +556,10 @@ int main(int argc, char* argv[])
 #endif
 
     vector<Point> corners(num_images);
-    vector<Mat> masks_warped(num_images);
-    vector<Mat> images_warped(num_images);
+    vector<UMat> masks_warped(num_images);
+    vector<UMat> images_warped(num_images);
     vector<Size> sizes(num_images);
-    vector<Mat> masks(num_images);
+    vector<UMat> masks(num_images);
 
     // Preapre images masks
     for (int i = 0; i < num_images; ++i)
@@ -645,7 +647,7 @@ int main(int argc, char* argv[])
         warper->warp(masks[i], K, cameras[i].R, INTER_NEAREST, BORDER_CONSTANT, masks_warped[i]);
     }
 
-    vector<Mat> images_warped_f(num_images);
+    vector<UMat> images_warped_f(num_images);
     for (int i = 0; i < num_images; ++i)
         images_warped[i].convertTo(images_warped_f[i], CV_32F);