diff --git a/modules/core/src/arithm.cpp b/modules/core/src/arithm.cpp index 130d3fafa01fe98df19f103a53c8663fadabb606..10ca872a988daa2aafce26aa17c18964d68d8ad5 100644 --- a/modules/core/src/arithm.cpp +++ b/modules/core/src/arithm.cpp @@ -1218,28 +1218,21 @@ namespace cv static int actualScalarDepth(const double* data, int len) { - double minval = data[0]; - double maxval = data[0]; - for(int i = 1; i < len; ++i) - { - minval = MIN(minval, data[i]); - maxval = MAX(maxval, data[i]); - } - - int depth = CV_64F; - if(minval >= 0 && maxval <= UCHAR_MAX) - depth = CV_8U; - else if(minval >= SCHAR_MIN && maxval <= SCHAR_MAX) - depth = CV_8S; - else if(minval >= 0 && maxval <= USHRT_MAX) - depth = CV_16U; - else if(minval >= SHRT_MIN && maxval <= SHRT_MAX) - depth = CV_16S; - else if(minval >= INT_MIN && maxval <= INT_MAX) - depth = CV_32S; - else if(minval >= -FLT_MAX && maxval <= FLT_MAX) - depth = CV_32F; - return depth; + int i = 0, minval = INT_MAX, maxval = INT_MIN; + for(; i < len; ++i) + { + int ival = cvRound(data[i]); + if( ival != data[i] ) + break; + minval = MIN(minval, ival); + maxval = MAX(maxval, ival); + } + return i < len ? CV_64F : + minval >= 0 && maxval <= UCHAR_MAX ? CV_8U : + minval >= SCHAR_MIN && maxval <= SCHAR_MAX ? CV_8S : + minval >= 0 && maxval <= USHRT_MAX ? CV_16U : + minval >= SHRT_MIN && maxval <= SHRT_MAX ? CV_16S : + CV_32S; } static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, @@ -1264,7 +1257,9 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, bool haveScalar = false, swapped12 = false; int depth2 = src2.depth(); - if( src1.size != src2.size || src1.channels() != src2.channels() ) + if( src1.size != src2.size || src1.channels() != src2.channels() || + ((kind1 == _InputArray::MATX || kind2 == _InputArray::MATX) && + src1.cols == 1 && src2.rows == 4) ) { if( checkScalar(src1, src2.type(), kind1, kind2) ) { @@ -1279,10 +1274,14 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, haveScalar = true; CV_Assert(src2.type() == CV_64F && (src2.rows == 4 || src2.rows == 1)); - if (usrdata == 0) // hack to filter out multiply and divide + if (!muldiv) + { depth2 = actualScalarDepth(src2.ptr(), src1.channels()); + if( depth2 == CV_64F && (src1.depth() < CV_32S || src1.depth() == CV_32F) ) + depth2 = CV_32F; + } else - depth2 = CV_64F; + depth2 = src1.depth() < CV_32S || src1.depth() == CV_32F ? CV_32F : CV_64F; } int cn = src1.channels(), depth1 = src1.depth(), wtype; diff --git a/modules/core/test/test_operations.cpp b/modules/core/test/test_operations.cpp index edc9633af87433065e6ab352d32edd9d67e76b27..2e4714639c8c464562a514993cdf3b3cb608d795 100644 --- a/modules/core/test/test_operations.cpp +++ b/modules/core/test/test_operations.cpp @@ -76,6 +76,7 @@ protected: bool TestVec(); bool TestMatxMultiplication(); bool TestSubMatAccess(); + bool TestExp(); bool TestSVD(); bool operations1(); @@ -1003,6 +1004,17 @@ bool CV_OperationsTest::operations1() } +bool CV_OperationsTest::TestExp() +{ + Mat1f tt = Mat1f::ones(4,2); + Mat1f outs; + exp(-tt, outs); + Mat1f tt2 = Mat1f::ones(4,1), outs2; + exp(-tt2, outs2); + return true; +} + + bool CV_OperationsTest::TestSVD() { try @@ -1079,6 +1091,9 @@ void CV_OperationsTest::run( int /* start_from */) if (!TestSubMatAccess()) return; + if (!TestExp()) + return; + if (!TestSVD()) return;