diff --git a/modules/core/src/dxt.cpp b/modules/core/src/dxt.cpp index 033bf45120..90eb392f58 100644 --- a/modules/core/src/dxt.cpp +++ b/modules/core/src/dxt.cpp @@ -1070,11 +1070,12 @@ RealDFT( const T* src, T* dst, int n, int nf, int* factors, const int* itab, } } - if( complex_output && (n & 1) == 0 ) + if (complex_output && ((n & 1) == 0 || n == 1)) { dst[-1] = dst[0]; dst[0] = 0; - dst[n] = 0; + if (n > 1) + dst[n] = 0; } } @@ -1473,6 +1474,47 @@ typedef IppStatus (CV_STDCALL* IppDFTGetSizeFunc)(int, int, IppHintAlgorithm, in typedef IppStatus (CV_STDCALL* IppDFTInitFunc)(int, int, IppHintAlgorithm, void*, uchar*); #endif +namespace cv +{ +static void complementComplexOutput(Mat& dst, int len, int dft_dims) +{ + int i, n = dst.cols; + size_t elem_size = dst.elemSize1(); + if (elem_size == sizeof(float)) + { + float* p0 = dst.ptr(); + size_t dstep = dst.step / sizeof(p0[0]); + for (i = 0; i < len; i++) + { + float* p = p0 + dstep*i; + float* q = dft_dims == 1 || i == 0 || i * 2 == len ? p : p0 + dstep*(len - i); + + for (int j = 1; j < (n + 1) / 2; j++) + { + p[(n - j) * 2] = q[j * 2]; + p[(n - j) * 2 + 1] = -q[j * 2 + 1]; + } + } + } + else + { + double* p0 = dst.ptr(); + size_t dstep = dst.step / sizeof(p0[0]); + for (i = 0; i < len; i++) + { + double* p = p0 + dstep*i; + double* q = dft_dims == 1 || i == 0 || i * 2 == len ? p : p0 + dstep*(len - i); + + for (int j = 1; j < (n + 1) / 2; j++) + { + p[(n - j) * 2] = q[j * 2]; + p[(n - j) * 2 + 1] = -q[j * 2 + 1]; + } + } + } +} +} + void cv::dft( InputArray _src0, OutputArray _dst, int flags, int nonzero_rows ) { static DFTFunc dft_tbl[6] = @@ -1688,8 +1730,12 @@ void cv::dft( InputArray _src0, OutputArray _dst, int flags, int nonzero_rows ) memset( dptr0, 0, dst_full_len ); } - if( stage != 1 ) + if (stage != 1) + { + if (!inv && real_transform && dst.channels() == 2) + complementComplexOutput(dst, nonzero_rows, 1); break; + } src = dst; } else @@ -1831,41 +1877,7 @@ void cv::dft( InputArray _src0, OutputArray _dst, int flags, int nonzero_rows ) if( stage != 0 ) { if( !inv && real_transform && dst.channels() == 2 && len > 1 ) - { - int n = dst.cols; - if( elem_size == (int)sizeof(float) ) - { - float* p0 = (float*)dst.data; - size_t dstep = dst.step/sizeof(p0[0]); - for( i = 0; i < len; i++ ) - { - float* p = p0 + dstep*i; - float* q = i == 0 || i*2 == len ? p : p0 + dstep*(len-i); - - for( int j = 1; j < (n+1)/2; j++ ) - { - p[(n-j)*2] = q[j*2]; - p[(n-j)*2+1] = -q[j*2+1]; - } - } - } - else - { - double* p0 = (double*)dst.data; - size_t dstep = dst.step/sizeof(p0[0]); - for( i = 0; i < len; i++ ) - { - double* p = p0 + dstep*i; - double* q = i == 0 || i*2 == len ? p : p0 + dstep*(len-i); - - for( int j = 1; j < (n+1)/2; j++ ) - { - p[(n-j)*2] = q[j*2]; - p[(n-j)*2+1] = -q[j*2+1]; - } - } - } - } + complementComplexOutput(dst, len, 2); break; } src = dst; diff --git a/modules/core/src/lapack.cpp b/modules/core/src/lapack.cpp index 7ee84a6d45..3084a5354b 100644 --- a/modules/core/src/lapack.cpp +++ b/modules/core/src/lapack.cpp @@ -688,7 +688,7 @@ JacobiSVDImpl_(_Tp* At, size_t astep, _Tp* _W, _Tp* Vt, size_t vstep, At[i*astep + k] = t; asum += std::abs(t); } - asum = asum ? 1/asum : 0; + asum = asum > eps * 100 ? 1 / asum : 0; for( k = 0; k < m; k++ ) At[i*astep + k] *= asum; } @@ -1560,18 +1560,18 @@ static void _SVDcompute( InputArray _aarr, OutputArray _w, JacobiSVD(temp_a.ptr(), temp_u.step, temp_w.ptr(), temp_v.ptr(), temp_v.step, m, n, compute_uv ? urows : 0); } - temp_w.copyTo(_w); + if(_w.needed()) temp_w.copyTo(_w); if( compute_uv ) { if( !at ) { - transpose(temp_u, _u); - temp_v.copyTo(_vt); + if(_u.needed()) transpose(temp_u, _u); + if(_vt.needed()) temp_v.copyTo(_vt); } else { - transpose(temp_v, _u); - temp_u.copyTo(_vt); + if(_u.needed()) transpose(temp_v, _u); + if(_vt.needed()) temp_u.copyTo(_vt); } } } diff --git a/modules/core/src/matmul.cpp b/modules/core/src/matmul.cpp index d537b7dced..4be9c4daa3 100644 --- a/modules/core/src/matmul.cpp +++ b/modules/core/src/matmul.cpp @@ -1013,7 +1013,7 @@ void cv::gemm( InputArray matA, InputArray matB, double alpha, GEMMBlockMulFunc blockMulFunc; GEMMStoreFunc storeFunc; Mat *matD = &D, tmat; - int tmat_size = 0; + size_t tmat_size = 0; const uchar* Cdata = C.data; size_t Cstep = C.data ? (size_t)C.step : 0; AutoBuffer buf; @@ -1046,7 +1046,7 @@ void cv::gemm( InputArray matA, InputArray matB, double alpha, if( D.data == A.data || D.data == B.data ) { - tmat_size = d_size.width*d_size.height*CV_ELEM_SIZE(type); + tmat_size = (size_t)d_size.width*d_size.height*CV_ELEM_SIZE(type); // Allocate tmat later, once the size of buf is known matD = &tmat; } @@ -1137,7 +1137,7 @@ void cv::gemm( InputArray matA, InputArray matB, double alpha, int is_b_t = flags & GEMM_2_T; int elem_size = CV_ELEM_SIZE(type); int dk0_1, dk0_2; - int a_buf_size = 0, b_buf_size, d_buf_size; + size_t a_buf_size = 0, b_buf_size, d_buf_size; uchar* a_buf = 0; uchar* b_buf = 0; uchar* d_buf = 0; @@ -1178,8 +1178,8 @@ void cv::gemm( InputArray matA, InputArray matB, double alpha, dn0 = block_size / dk0; dk0_1 = (dn0+dn0/8+2) & -2; - b_buf_size = (dk0+dk0/8+1)*dk0_1*elem_size; - d_buf_size = (dk0+dk0/8+1)*dk0_1*work_elem_size; + b_buf_size = (size_t)(dk0+dk0/8+1)*dk0_1*elem_size; + d_buf_size = (size_t)(dk0+dk0/8+1)*dk0_1*work_elem_size; if( is_a_t ) { diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index 3c24f02541..e88d175108 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -2587,6 +2587,11 @@ void cv::findNonZero( InputArray _src, OutputArray _idx ) Mat src = _src.getMat(); CV_Assert( src.type() == CV_8UC1 ); int n = countNonZero(src); + if (n == 0) + { + _idx.release(); + return; + } if( _idx.kind() == _InputArray::MAT && !_idx.getMatRef().isContinuous() ) _idx.release(); _idx.create(n, 1, CV_32SC2); diff --git a/modules/core/test/test_arithm.cpp b/modules/core/test/test_arithm.cpp index ac88615955..57adb89210 100644 --- a/modules/core/test/test_arithm.cpp +++ b/modules/core/test/test_arithm.cpp @@ -1810,3 +1810,13 @@ TEST(MinMaxLoc, Mat_IntMax_Without_Mask) ASSERT_EQ(Point(0, 0), minLoc); ASSERT_EQ(Point(0, 0), maxLoc); } + + +TEST(Core_FindNonZero, singular) +{ + Mat img(10, 10, CV_8U, Scalar::all(0)); + vector pts, pts2(10); + findNonZero(img, pts); + findNonZero(img, pts2); + ASSERT_TRUE(pts.empty() && pts2.empty()); +} \ No newline at end of file diff --git a/modules/core/test/test_dxt.cpp b/modules/core/test/test_dxt.cpp index 1c0c7b00bf..33ddb02660 100644 --- a/modules/core/test/test_dxt.cpp +++ b/modules/core/test/test_dxt.cpp @@ -866,3 +866,24 @@ protected: }; TEST(Core_DFT, complex_output) { Core_DFTComplexOutputTest test; test.safe_run(); } + +TEST(Core_DFT, complex_output2) +{ + for (int i = 0; i < 100; i++) + { + int type = theRNG().uniform(0, 2) ? CV_64F : CV_32F; + int m = theRNG().uniform(1, 10); + int n = theRNG().uniform(1, 10); + Mat x(m, n, type), out; + randu(x, -1., 1.); + dft(x, out, DFT_ROWS | DFT_COMPLEX_OUTPUT); + double nrm = norm(out, NORM_INF); + double thresh = n*m * 2; + if (nrm > thresh) + { + cout << "x: " << x << endl; + cout << "out: " << out << endl; + ASSERT_LT(nrm, thresh); + } + } +} diff --git a/modules/core/test/test_mat.cpp b/modules/core/test/test_mat.cpp index f854abed7e..0d35e60780 100644 --- a/modules/core/test/test_mat.cpp +++ b/modules/core/test/test_mat.cpp @@ -919,6 +919,39 @@ TEST(Core_Mat, copyNx1ToVector) ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), ref_dst16, cv::Mat_(dst16)); } +TEST(Core_InputArray, empty) +{ + vector > data; + ASSERT_TRUE(_InputArray(data).empty()); +} + + +TEST(Core_CopyMask, bug1918) +{ + Mat_ tmpSrc(100, 100); + tmpSrc = 124; + Mat_ tmpMask(100, 100); + tmpMask = 255; + Mat_ tmpDst(100, 100); + tmpDst = 2; + tmpSrc.copyTo(tmpDst, tmpMask); + ASSERT_EQ(sum(tmpDst)[0], 124 * 100 * 100); +} + +TEST(Core_SVD, orthogonality) +{ + for (int i = 0; i < 2; i++) + { + int type = i == 0 ? CV_32F : CV_64F; + Mat mat_D(2, 2, type); + mat_D.setTo(88.); + Mat mat_U, mat_W; + SVD::compute(mat_D, mat_W, mat_U, noArray(), SVD::FULL_UV); + mat_U *= mat_U.t(); + ASSERT_LT(norm(mat_U, Mat::eye(2, 2, type), NORM_INF), 1e-5); + } +} + TEST(Core_Mat, multiDim) { int d[]={3,3,3};