diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index f8cb64bbf4..2a6673d88c 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -4021,6 +4021,11 @@ void cv::reduce(InputArray _src, OutputArray _dst, int dim, int op, int dtype) CV_OCL_RUN(_dst.isUMat(), ocl_reduce(_src, _dst, dim, op, op0, stype, dtype)) + // Fake reference to source. Resolves issue 8693 in case of src == dst. + UMat srcUMat; + if (_src.isUMat()) + srcUMat = _src.getUMat(); + Mat src = _src.getMat(); _dst.create(dim == 0 ? 1 : src.rows, dim == 0 ? src.cols : 1, dtype); Mat dst = _dst.getMat(), temp = dst; diff --git a/modules/core/src/umatrix.cpp b/modules/core/src/umatrix.cpp index 58f7390321..1be5fc6123 100644 --- a/modules/core/src/umatrix.cpp +++ b/modules/core/src/umatrix.cpp @@ -961,6 +961,8 @@ void UMat::convertTo(OutputArray _dst, int _type, double alpha, double beta) con } } #endif + UMat src = *this; // Fake reference to itself. + // Resolves issue 8693 in case of src == dst. Mat m = getMat(ACCESS_READ); m.convertTo(_dst, _type, alpha, beta); } diff --git a/modules/core/test/test_umat.cpp b/modules/core/test/test_umat.cpp index d7a3e6de1f..092abec3f1 100644 --- a/modules/core/test/test_umat.cpp +++ b/modules/core/test/test_umat.cpp @@ -1366,4 +1366,21 @@ TEST(UMat, DISABLED_regression_5991) EXPECT_EQ(0, cvtest::norm(mat.getMat(ACCESS_READ), Mat(3, sz, CV_8U, Scalar(1)), NORM_INF)); } +TEST(UMat, testTempObjects_Mat_issue_8693) +{ + UMat srcUMat(3, 4, CV_32FC1); + Mat srcMat; + + randu(srcUMat, -1.f, 1.f); + srcUMat.copyTo(srcMat); + + reduce(srcUMat, srcUMat, 0, CV_REDUCE_SUM); + reduce(srcMat, srcMat, 0, CV_REDUCE_SUM); + + srcUMat.convertTo(srcUMat, CV_64FC1); + srcMat.convertTo(srcMat, CV_64FC1); + + EXPECT_EQ(0, cvtest::norm(srcUMat.getMat(ACCESS_READ), srcMat, NORM_INF)); +} + } } // namespace cvtest::ocl