From: Alexander Alekhin Date: Fri, 14 Feb 2014 11:36:04 +0000 (+0400) Subject: TAPI: stitching, replaced Mat->UMat/_Array X-Git-Tag: accepted/tizen/6.0/unified/20201030.111113~3303^2~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1d9808e5d5c6f53fe25077f77279404bab205755;p=platform%2Fupstream%2Fopencv.git TAPI: stitching, replaced Mat->UMat/_Array --- diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index 6b8368f..d921f75 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -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; }; diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 4efba46..32ccd03 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -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; } diff --git a/modules/stitching/include/opencv2/stitching.hpp b/modules/stitching/include/opencv2/stitching.hpp index 2c48f2f..b647c0f 100644 --- a/modules/stitching/include/opencv2/stitching.hpp +++ b/modules/stitching/include/opencv2/stitching.hpp @@ -98,8 +98,8 @@ public: void setFeaturesMatcher(Ptr 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 blender() const { return blender_; } void setBlender(Ptr b) { blender_ = b; } - Status estimateTransform(InputArray images); - Status estimateTransform(InputArray images, const std::vector > &rois); + Status estimateTransform(InputArrayOfArrays images); + Status estimateTransform(InputArrayOfArrays images, const std::vector > &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 > &rois, OutputArray pano); + Status stitch(InputArrayOfArrays images, OutputArray pano); + Status stitch(InputArrayOfArrays images, const std::vector > &rois, OutputArray pano); std::vector component() const { return indices_; } std::vector cameras() const { return cameras_; } @@ -152,7 +152,7 @@ private: double conf_thresh_; Ptr features_finder_; Ptr features_matcher_; - cv::Mat matching_mask_; + cv::UMat matching_mask_; Ptr bundle_adjuster_; bool do_wave_correct_; detail::WaveCorrectKind wave_correct_kind_; @@ -161,12 +161,12 @@ private: Ptr seam_finder_; Ptr blender_; - std::vector imgs_; + std::vector imgs_; std::vector > rois_; std::vector full_img_sizes_; std::vector features_; std::vector pairwise_matches_; - std::vector seam_est_imgs_; + std::vector seam_est_imgs_; std::vector indices_; std::vector cameras_; double work_scale_; diff --git a/modules/stitching/include/opencv2/stitching/detail/blenders.hpp b/modules/stitching/include/opencv2/stitching/detail/blenders.hpp index 8d47d32..f91a0ea 100644 --- a/modules/stitching/include/opencv2/stitching/detail/blenders.hpp +++ b/modules/stitching/include/opencv2/stitching/detail/blenders.hpp @@ -60,11 +60,11 @@ public: void prepare(const std::vector &corners, const std::vector &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 &masks, const std::vector &corners, - std::vector &weight_maps); + Rect createWeightMaps(const std::vector &masks, const std::vector &corners, + std::vector &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 dst_pyr_laplace_; - std::vector dst_band_weights_; + std::vector dst_pyr_laplace_; + std::vector 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& pyr); -void CV_EXPORTS createLaplacePyrGpu(const Mat &img, int num_levels, std::vector& pyr); +void CV_EXPORTS createLaplacePyr(InputArray img, int num_levels, std::vector& pyr); +void CV_EXPORTS createLaplacePyrGpu(InputArray img, int num_levels, std::vector& pyr); // Restores source image -void CV_EXPORTS restoreImageFromLaplacePyr(std::vector& pyr); -void CV_EXPORTS restoreImageFromLaplacePyrGpu(std::vector& pyr); +void CV_EXPORTS restoreImageFromLaplacePyr(std::vector& pyr); +void CV_EXPORTS restoreImageFromLaplacePyrGpu(std::vector& pyr); } // namespace detail } // namespace cv diff --git a/modules/stitching/include/opencv2/stitching/detail/exposure_compensate.hpp b/modules/stitching/include/opencv2/stitching/detail/exposure_compensate.hpp index 84a8ce4..5626b06 100644 --- a/modules/stitching/include/opencv2/stitching/detail/exposure_compensate.hpp +++ b/modules/stitching/include/opencv2/stitching/detail/exposure_compensate.hpp @@ -56,29 +56,29 @@ public: enum { NO, GAIN, GAIN_BLOCKS }; static Ptr createDefault(int type); - void feed(const std::vector &corners, const std::vector &images, - const std::vector &masks); - virtual void feed(const std::vector &corners, const std::vector &images, - const std::vector > &masks) = 0; - virtual void apply(int index, Point corner, Mat &image, const Mat &mask) = 0; + void feed(const std::vector &corners, const std::vector &images, + const std::vector &masks); + virtual void feed(const std::vector &corners, const std::vector &images, + const std::vector > &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 &/*corners*/, const std::vector &/*images*/, - const std::vector > &/*masks*/) { } - void apply(int /*index*/, Point /*corner*/, Mat &/*image*/, const Mat &/*mask*/) { } + void feed(const std::vector &/*corners*/, const std::vector &/*images*/, + const std::vector > &/*masks*/) { } + void apply(int /*index*/, Point /*corner*/, InputOutputArray /*image*/, InputArray /*mask*/) { } }; class CV_EXPORTS GainCompensator : public ExposureCompensator { public: - void feed(const std::vector &corners, const std::vector &images, - const std::vector > &masks); - void apply(int index, Point corner, Mat &image, const Mat &mask); + void feed(const std::vector &corners, const std::vector &images, + const std::vector > &masks); + void apply(int index, Point corner, InputOutputArray image, InputArray mask); std::vector 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 &corners, const std::vector &images, - const std::vector > &masks); - void apply(int index, Point corner, Mat &image, const Mat &mask); + void feed(const std::vector &corners, const std::vector &images, + const std::vector > &masks); + void apply(int index, Point corner, InputOutputArray image, InputArray mask); private: int bl_width_, bl_height_; diff --git a/modules/stitching/include/opencv2/stitching/detail/matchers.hpp b/modules/stitching/include/opencv2/stitching/detail/matchers.hpp index 02f8660..8c3284a 100644 --- a/modules/stitching/include/opencv2/stitching/detail/matchers.hpp +++ b/modules/stitching/include/opencv2/stitching/detail/matchers.hpp @@ -60,7 +60,7 @@ struct CV_EXPORTS ImageFeatures int img_idx; Size img_size; std::vector 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 &rois); + void operator ()(InputArray image, ImageFeatures &features); + void operator ()(InputArray image, ImageFeatures &features, const std::vector &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 detector_; Ptr 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; 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 &features, std::vector &pairwise_matches, - const cv::Mat &mask = cv::Mat()); + const cv::UMat &mask = cv::UMat()); bool isThreadSafe() const { return is_thread_safe_; } diff --git a/modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp b/modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp index 24b7db6..5f085c1 100644 --- a/modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp +++ b/modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp @@ -54,32 +54,32 @@ class CV_EXPORTS SeamFinder { public: virtual ~SeamFinder() {} - virtual void find(const std::vector &src, const std::vector &corners, - std::vector &masks) = 0; + virtual void find(const std::vector &src, const std::vector &corners, + std::vector &masks) = 0; }; class CV_EXPORTS NoSeamFinder : public SeamFinder { public: - void find(const std::vector&, const std::vector&, std::vector&) {} + void find(const std::vector&, const std::vector&, std::vector&) {} }; class CV_EXPORTS PairwiseSeamFinder : public SeamFinder { public: - virtual void find(const std::vector &src, const std::vector &corners, - std::vector &masks); + virtual void find(const std::vector &src, const std::vector &corners, + std::vector &masks); protected: void run(); virtual void findInPair(size_t first, size_t second, Rect roi) = 0; - std::vector images_; + std::vector images_; std::vector sizes_; std::vector corners_; - std::vector masks_; + std::vector masks_; }; @@ -87,7 +87,7 @@ class CV_EXPORTS VoronoiSeamFinder : public PairwiseSeamFinder { public: virtual void find(const std::vector &size, const std::vector &corners, - std::vector &masks); + std::vector &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 &src, const std::vector &corners, - std::vector &masks); + virtual void find(const std::vector &src, const std::vector &corners, + std::vector &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 &src, const std::vector &corners, - std::vector &masks); + void find(const std::vector &src, const std::vector &corners, + std::vector &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 &src, const std::vector &corners, - std::vector &masks); + void find(const std::vector &src, const std::vector &corners, + std::vector &masks); void findInPair(size_t first, size_t second, Rect roi); private: diff --git a/modules/stitching/include/opencv2/stitching/detail/util.hpp b/modules/stitching/include/opencv2/stitching/detail/util.hpp index 6f334b9..561880c 100644 --- a/modules/stitching/include/opencv2/stitching/detail/util.hpp +++ b/modules/stitching/include/opencv2/stitching/detail/util.hpp @@ -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 &corners, const std::vector &images); +CV_EXPORTS Rect resultRoi(const std::vector &corners, const std::vector &images); CV_EXPORTS Rect resultRoi(const std::vector &corners, const std::vector &sizes); CV_EXPORTS Point resultTl(const std::vector &corners); diff --git a/modules/stitching/src/blenders.cpp b/modules/stitching/src/blenders.cpp index 446bfc1..5012d9b 100644 --- a/modules/stitching/src/blenders.cpp +++ b/modules/stitching/src/blenders.cpp @@ -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_ *src_row = img.ptr >(y); - Point3_ *dst_row = dst_.ptr >(dy + y); + Point3_ *dst_row = dst.ptr >(dy + y); const uchar *mask_row = mask.ptr(y); - uchar *dst_mask_row = dst_mask_.ptr(dy + y); + uchar *dst_mask_row = dst_mask.ptr(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_* src_row = img.ptr >(y); - Point3_* dst_row = dst_.ptr >(dy + y); - const float* weight_row = weight_map_.ptr(y); - float* dst_weight_row = dst_weight_map_.ptr(dy + y); + Point3_* dst_row = dst.ptr >(dy + y); + const float* weight_row = weight_map.ptr(y); + float* dst_weight_row = dst_weight_map.ptr(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 &masks, const std::vector &corners, - std::vector &weight_maps) +Rect FeatherBlender::createWeightMaps(const std::vector &masks, const std::vector &corners, + std::vector &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 &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 src_pyr_laplace; + std::vector 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 weight_pyr_gauss(num_bands_ + 1); + UMat weight_map; + std::vector 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_* src_row = src_pyr_laplace[i].ptr >(y_); - Point3_* dst_row = dst_pyr_laplace_[i].ptr >(y); - const float* weight_row = weight_pyr_gauss[i].ptr(y_); - float* dst_weight_row = dst_band_weights_[i].ptr(y); + const Point3_* src_row = _src_pyr_laplace.ptr >(y_); + Point3_* dst_row = _dst_pyr_laplace.ptr >(y); + const float* weight_row = _weight_pyr_gauss.ptr(y_); + float* dst_weight_row = _dst_band_weights.ptr(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_* src_row = src_pyr_laplace[i].ptr >(y_); - Point3_* dst_row = dst_pyr_laplace_[i].ptr >(y); - const short* weight_row = weight_pyr_gauss[i].ptr(y_); - short* dst_weight_row = dst_band_weights_[i].ptr(y); + const Point3_* src_row = _src_pyr_laplace.ptr >(y_); + Point3_* dst_row = _dst_pyr_laplace.ptr >(y); + const short* weight_row = _weight_pyr_gauss.ptr(y_); + short* dst_weight_row = _dst_band_weights.ptr(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 &pyr) +void createLaplacePyr(InputArray img, int num_levels, std::vector &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 &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 &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 &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 &pyr) } -void createLaplacePyrGpu(const Mat &img, int num_levels, std::vector &pyr) +void createLaplacePyrGpu(InputArray img, int num_levels, std::vector &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 &pyr) } -void restoreImageFromLaplacePyr(std::vector &pyr) +void restoreImageFromLaplacePyr(std::vector &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 &pyr) } -void restoreImageFromLaplacePyrGpu(std::vector &pyr) +void restoreImageFromLaplacePyrGpu(std::vector &pyr) { #if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING) if (pyr.empty()) diff --git a/modules/stitching/src/exposure_compensate.cpp b/modules/stitching/src/exposure_compensate.cpp index 78ce6d3..32112d6 100644 --- a/modules/stitching/src/exposure_compensate.cpp +++ b/modules/stitching/src/exposure_compensate.cpp @@ -58,18 +58,18 @@ Ptr ExposureCompensator::createDefault(int type) } -void ExposureCompensator::feed(const std::vector &corners, const std::vector &images, - const std::vector &masks) +void ExposureCompensator::feed(const std::vector &corners, const std::vector &images, + const std::vector &masks) { - std::vector > level_masks; + std::vector > 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 &corners, const std::vector &images, - const std::vector > &masks) +void GainCompensator::feed(const std::vector &corners, const std::vector &images, + const std::vector > &masks) { LOGLN("Exposure compensation..."); #if ENABLE_LOG @@ -93,11 +93,11 @@ void GainCompensator::feed(const std::vector &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 &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 GainCompensator::gains() const } -void BlocksGainCompensator::feed(const std::vector &corners, const std::vector &images, - const std::vector > &masks) +void BlocksGainCompensator::feed(const std::vector &corners, const std::vector &images, + const std::vector > &masks) { CV_Assert(corners.size() == images.size() && images.size() == masks.size()); @@ -169,8 +169,8 @@ void BlocksGainCompensator::feed(const std::vector &corners, const std::v std::vector bl_per_imgs(num_images); std::vector block_corners; - std::vector block_images; - std::vector > block_masks; + std::vector block_images; + std::vector > 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 &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_ gain_map; diff --git a/modules/stitching/src/matchers.cpp b/modules/stitching/src/matchers.cpp index f463518..1ce1fc3 100644 --- a/modules/stitching/src/matchers.cpp +++ b/modules/stitching/src/matchers.cpp @@ -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 &rois) +void FeaturesFinder::operator ()(InputArray image, ImageFeatures &features, const std::vector &rois) { std::vector 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(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 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::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 &features, std::vector &pairwise_matches, - const Mat &mask) + const UMat &mask) { const int num_images = static_cast(features.size()); CV_Assert(mask.empty() || (mask.type() == CV_8U && mask.cols == num_images && mask.rows)); - Mat_ mask_(mask); + Mat_ mask_(mask.getMat(ACCESS_READ)); if (mask_.empty()) mask_ = Mat::ones(num_images, num_images, CV_8U); diff --git a/modules/stitching/src/seam_finders.cpp b/modules/stitching/src/seam_finders.cpp index 2e5117e..4d5c8d1 100644 --- a/modules/stitching/src/seam_finders.cpp +++ b/modules/stitching/src/seam_finders.cpp @@ -46,8 +46,8 @@ namespace cv { namespace detail { -void PairwiseSeamFinder::find(const std::vector &src, const std::vector &corners, - std::vector &masks) +void PairwiseSeamFinder::find(const std::vector &src, const std::vector &corners, + std::vector &masks) { LOGLN("Finding seams..."); if (src.size() == 0) @@ -84,7 +84,7 @@ void PairwiseSeamFinder::run() void VoronoiSeamFinder::find(const std::vector &sizes, const std::vector &corners, - std::vector &masks) + std::vector &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 &src, const std::vector &corners, std::vector &masks) +void DpSeamFinder::find(const std::vector &src, const std::vector &corners, std::vector &masks) { LOGLN("Finding seams..."); #if ENABLE_LOG @@ -176,13 +176,18 @@ void DpSeamFinder::find(const std::vector &src, const std::vector &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 _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 &src, const std::vector &corners, std::vector &masks); + void find(const std::vector &src, const std::vector &corners, std::vector &masks); void findInPair(size_t first, size_t second, Rect roi); private: @@ -1072,8 +1077,8 @@ private: }; -void GraphCutSeamFinder::Impl::find(const std::vector &src, const std::vector &corners, - std::vector &masks) +void GraphCutSeamFinder::Impl::find(const std::vector &src, const std::vector &corners, + std::vector &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 &src, const std::vector &corners, - std::vector &masks) +void GraphCutSeamFinder::find(const std::vector &src, const std::vector &corners, + std::vector &masks) { impl_->find(src, corners, masks); } #ifdef HAVE_OPENCV_CUDA -void GraphCutSeamFinderGpu::find(const std::vector &src, const std::vector &corners, - std::vector &masks) +void GraphCutSeamFinderGpu::find(const std::vector &src, const std::vector &corners, + std::vector &masks) { // Compute gradients dx_.resize(src.size()); @@ -1350,10 +1355,10 @@ void GraphCutSeamFinderGpu::find(const std::vector &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; diff --git a/modules/stitching/src/stitcher.cpp b/modules/stitching/src/stitcher.cpp index 5683ec3..ae46726 100644 --- a/modules/stitching/src/stitcher.cpp +++ b/modules/stitching/src/stitcher.cpp @@ -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 >()); } -Stitcher::Status Stitcher::estimateTransform(InputArray images, const std::vector > &rois) +Stitcher::Status Stitcher::estimateTransform(InputArrayOfArrays images, const std::vector > &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(), pano); + return composePanorama(std::vector(), pano); } -Stitcher::Status Stitcher::composePanorama(InputArray images, OutputArray pano) +Stitcher::Status Stitcher::composePanorama(InputArrayOfArrays images, OutputArray pano) { LOGLN("Warping images (auxiliary)... "); - std::vector imgs; - images.getMatVector(imgs); + std::vector 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 seam_est_imgs_subset; - std::vector imgs_subset; + std::vector seam_est_imgs_subset; + std::vector 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 corners(imgs_.size()); - std::vector masks_warped(imgs_.size()); - std::vector images_warped(imgs_.size()); + std::vector masks_warped(imgs_.size()); + std::vector images_warped(imgs_.size()); std::vector sizes(imgs_.size()); - std::vector masks(imgs_.size()); + std::vector 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 images_warped_f(imgs_.size()); + std::vector 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 > &rois, OutputArray pano) +Stitcher::Status Stitcher::stitch(InputArrayOfArrays images, const std::vector > &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 seam_est_imgs_subset; - std::vector imgs_subset; + std::vector seam_est_imgs_subset; + std::vector imgs_subset; std::vector full_img_sizes_subset; for (size_t i = 0; i < indices_.size(); ++i) { diff --git a/modules/stitching/src/util.cpp b/modules/stitching/src/util.cpp index f6abf9e..5e026f0 100644 --- a/modules/stitching/src/util.cpp +++ b/modules/stitching/src/util.cpp @@ -113,7 +113,7 @@ bool overlapRoi(Point tl1, Point tl2, Size sz1, Size sz2, Rect &roi) } -Rect resultRoi(const std::vector &corners, const std::vector &images) +Rect resultRoi(const std::vector &corners, const std::vector &images) { std::vector sizes(images.size()); for (size_t i = 0; i < images.size(); ++i) diff --git a/samples/cpp/stitching_detailed.cpp b/samples/cpp/stitching_detailed.cpp index 5eb3df4..93389a9 100644 --- a/samples/cpp/stitching_detailed.cpp +++ b/samples/cpp/stitching_detailed.cpp @@ -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 corners(num_images); - vector masks_warped(num_images); - vector images_warped(num_images); + vector masks_warped(num_images); + vector images_warped(num_images); vector sizes(num_images); - vector masks(num_images); + vector 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 images_warped_f(num_images); + vector images_warped_f(num_images); for (int i = 0; i < num_images; ++i) images_warped[i].convertTo(images_warped_f[i], CV_32F);