diff --git a/modules/core/src/arithm.cpp b/modules/core/src/arithm.cpp index f0ef92055..4058856ff 100644 --- a/modules/core/src/arithm.cpp +++ b/modules/core/src/arithm.cpp @@ -1553,43 +1553,58 @@ void cv::add( InputArray src1, InputArray src2, OutputArray dst, arithm_op(src1, src2, dst, mask, dtype, getAddTab() ); } -void cv::subtract( InputArray src1, InputArray src2, OutputArray dst, +void cv::subtract( InputArray _src1, InputArray _src2, OutputArray _dst, InputArray mask, int dtype ) { #ifdef HAVE_TEGRA_OPTIMIZATION - if (mask.empty() && src1.depth() == CV_8U && src2.depth() == CV_8U) + int kind1 = _src1.kind(), kind2 = _src2.kind(); + Mat src1 = _src1.getMat(), src2 = _src2.getMat(); + bool src1Scalar = checkScalar(src1, _src2.type(), kind1, kind2); + bool src2Scalar = checkScalar(src2, _src1.type(), kind2, kind1); + + if (!src1Scalar && !src2Scalar && mask.empty() && + src1.depth() == CV_8U && src2.depth() == CV_8U) { - if (dtype == -1 && dst.fixedType()) - dtype = dst.depth(); - - dtype = CV_MAKE_TYPE(CV_MAT_DEPTH(dtype), src1.channels()); - - if (!dst.fixedType() || dtype == dst.type()) + if (dtype == -1) { - dst.create(src1.size(), dtype); + if (_dst.fixedType()) + { + dtype = _dst.depth(); + } + else + { + dtype = src1.depth(); + } + } + + dtype = CV_MAKE_TYPE(CV_MAT_DEPTH(dtype), _src1.channels()); + + if (dtype == _dst.type()) + { + _dst.create(_src1.size(), dtype); if (dtype == CV_16S) { - Mat _dst = dst.getMat(); - if(tegra::subtract_8u8u16s(src1.getMat(), src2.getMat(), _dst)) + Mat dst = _dst.getMat(); + if(tegra::subtract_8u8u16s(src1, src2, dst)) return; } else if (dtype == CV_32F) { - Mat _dst = dst.getMat(); - if(tegra::subtract_8u8u32f(src1.getMat(), src2.getMat(), _dst)) + Mat dst = _dst.getMat(); + if(tegra::subtract_8u8u32f(src1, src2, dst)) return; } else if (dtype == CV_8S) { - Mat _dst = dst.getMat(); - if(tegra::subtract_8u8u8s(src1.getMat(), src2.getMat(), _dst)) + Mat dst = _dst.getMat(); + if(tegra::subtract_8u8u8s(src1, src2, dst)) return; } } } #endif - arithm_op(src1, src2, dst, mask, dtype, getSubTab() ); + arithm_op(_src1, _src2, _dst, mask, dtype, getSubTab() ); } void cv::absdiff( InputArray src1, InputArray src2, OutputArray dst ) diff --git a/modules/core/test/test_arithm.cpp b/modules/core/test/test_arithm.cpp index 1687285a6..68b06267b 100644 --- a/modules/core/test/test_arithm.cpp +++ b/modules/core/test/test_arithm.cpp @@ -1580,12 +1580,21 @@ TEST_P(Mul1, One) INSTANTIATE_TEST_CASE_P(Arithm, Mul1, testing::Values(Size(2, 2), Size(1, 1))); -TEST(Subtract8u8u16s, EmptyOutputMat) +TEST(Subtract, EmptyOutputMat) { cv::Mat src1 = cv::Mat::zeros(16, 16, CV_8UC1); cv::Mat src2 = cv::Mat::zeros(16, 16, CV_8UC1); - cv::Mat dst; - cv::subtract(src1, src2, dst, cv::noArray(), CV_16S); - ASSERT_FALSE(dst.empty()); - ASSERT_EQ(0, cv::countNonZero(dst)); + cv::Mat dst1, dst2, dst3; + + cv::subtract(src1, src2, dst1, cv::noArray(), CV_16S); + cv::subtract(src1, src2, dst2); + cv::subtract(src1, cv::Scalar::all(0), dst3, cv::noArray(), CV_16S); + + ASSERT_FALSE(dst1.empty()); + ASSERT_FALSE(dst2.empty()); + ASSERT_FALSE(dst3.empty()); + + ASSERT_EQ(0, cv::countNonZero(dst1)); + ASSERT_EQ(0, cv::countNonZero(dst2)); + ASSERT_EQ(0, cv::countNonZero(dst3)); }