1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 #include "test_precomp.hpp"
9 #include "opencv2/core/eigen.hpp"
12 namespace opencv_test { namespace {
14 class Core_ReduceTest : public cvtest::BaseTest
20 int checkOp( const Mat& src, int dstType, int opType, const Mat& opRes, int dim );
21 int checkCase( int srcType, int dstType, int dim, Size sz );
22 int checkDim( int dim, Size sz );
23 int checkSize( Size sz );
27 void testReduce( const Mat& src, Mat& sum, Mat& avg, Mat& max, Mat& min, int dim )
29 assert( src.channels() == 1 );
32 sum.create( 1, src.cols, CV_64FC1 );
33 max.create( 1, src.cols, CV_64FC1 );
34 min.create( 1, src.cols, CV_64FC1 );
38 sum.create( src.rows, 1, CV_64FC1 );
39 max.create( src.rows, 1, CV_64FC1 );
40 min.create( src.rows, 1, CV_64FC1 );
43 max.setTo(Scalar(-DBL_MAX));
44 min.setTo(Scalar(DBL_MAX));
46 const Mat_<Type>& src_ = src;
47 Mat_<double>& sum_ = (Mat_<double>&)sum;
48 Mat_<double>& min_ = (Mat_<double>&)min;
49 Mat_<double>& max_ = (Mat_<double>&)max;
53 for( int ri = 0; ri < src.rows; ri++ )
55 for( int ci = 0; ci < src.cols; ci++ )
57 sum_(0, ci) += src_(ri, ci);
58 max_(0, ci) = std::max( max_(0, ci), (double)src_(ri, ci) );
59 min_(0, ci) = std::min( min_(0, ci), (double)src_(ri, ci) );
65 for( int ci = 0; ci < src.cols; ci++ )
67 for( int ri = 0; ri < src.rows; ri++ )
69 sum_(ri, 0) += src_(ri, ci);
70 max_(ri, 0) = std::max( max_(ri, 0), (double)src_(ri, ci) );
71 min_(ri, 0) = std::min( min_(ri, 0), (double)src_(ri, ci) );
75 sum.convertTo( avg, CV_64FC1 );
76 avg = avg * (1.0 / (dim==0 ? (double)src.rows : (double)src.cols));
79 void getMatTypeStr( int type, string& str)
81 str = type == CV_8UC1 ? "CV_8UC1" :
82 type == CV_8SC1 ? "CV_8SC1" :
83 type == CV_16UC1 ? "CV_16UC1" :
84 type == CV_16SC1 ? "CV_16SC1" :
85 type == CV_32SC1 ? "CV_32SC1" :
86 type == CV_32FC1 ? "CV_32FC1" :
87 type == CV_64FC1 ? "CV_64FC1" : "unsupported matrix type";
90 int Core_ReduceTest::checkOp( const Mat& src, int dstType, int opType, const Mat& opRes, int dim )
92 int srcType = src.type();
94 if( opType == CV_REDUCE_SUM || opType == CV_REDUCE_AVG )
96 if( srcType == CV_8U && (dstType == CV_32S || dstType == CV_32F || dstType == CV_64F) )
98 if( srcType == CV_16U && (dstType == CV_32F || dstType == CV_64F) )
100 if( srcType == CV_16S && (dstType == CV_32F || dstType == CV_64F) )
102 if( srcType == CV_32F && (dstType == CV_32F || dstType == CV_64F) )
104 if( srcType == CV_64F && dstType == CV_64F)
107 else if( opType == CV_REDUCE_MAX )
109 if( srcType == CV_8U && dstType == CV_8U )
111 if( srcType == CV_32F && dstType == CV_32F )
113 if( srcType == CV_64F && dstType == CV_64F )
116 else if( opType == CV_REDUCE_MIN )
118 if( srcType == CV_8U && dstType == CV_8U)
120 if( srcType == CV_32F && dstType == CV_32F)
122 if( srcType == CV_64F && dstType == CV_64F)
126 return cvtest::TS::OK;
129 if ( opType == CV_REDUCE_SUM || opType == CV_REDUCE_AVG )
131 if ( dstType == CV_32F )
133 else if( dstType == CV_64F )
135 else if ( dstType == CV_32S )
139 assert( opRes.type() == CV_64FC1 );
141 cv::reduce( src, _dst, dim, opType, dstType );
142 _dst.convertTo( dst, CV_64FC1 );
144 absdiff( opRes,dst,diff );
146 if (dstType == CV_32F || dstType == CV_64F)
147 check = countNonZero(diff>eps*dst) > 0;
149 check = countNonZero(diff>eps) > 0;
153 const char* opTypeStr = opType == CV_REDUCE_SUM ? "CV_REDUCE_SUM" :
154 opType == CV_REDUCE_AVG ? "CV_REDUCE_AVG" :
155 opType == CV_REDUCE_MAX ? "CV_REDUCE_MAX" :
156 opType == CV_REDUCE_MIN ? "CV_REDUCE_MIN" : "unknown operation type";
157 string srcTypeStr, dstTypeStr;
158 getMatTypeStr( src.type(), srcTypeStr );
159 getMatTypeStr( dstType, dstTypeStr );
160 const char* dimStr = dim == 0 ? "ROWS" : "COLS";
162 sprintf( msg, "bad accuracy with srcType = %s, dstType = %s, opType = %s, dim = %s",
163 srcTypeStr.c_str(), dstTypeStr.c_str(), opTypeStr, dimStr );
164 ts->printf( cvtest::TS::LOG, msg );
165 return cvtest::TS::FAIL_BAD_ACCURACY;
167 return cvtest::TS::OK;
170 int Core_ReduceTest::checkCase( int srcType, int dstType, int dim, Size sz )
172 int code = cvtest::TS::OK, tempCode;
173 Mat src, sum, avg, max, min;
175 src.create( sz, srcType );
176 randu( src, Scalar(0), Scalar(100) );
178 if( srcType == CV_8UC1 )
179 testReduce<uchar>( src, sum, avg, max, min, dim );
180 else if( srcType == CV_8SC1 )
181 testReduce<char>( src, sum, avg, max, min, dim );
182 else if( srcType == CV_16UC1 )
183 testReduce<unsigned short int>( src, sum, avg, max, min, dim );
184 else if( srcType == CV_16SC1 )
185 testReduce<short int>( src, sum, avg, max, min, dim );
186 else if( srcType == CV_32SC1 )
187 testReduce<int>( src, sum, avg, max, min, dim );
188 else if( srcType == CV_32FC1 )
189 testReduce<float>( src, sum, avg, max, min, dim );
190 else if( srcType == CV_64FC1 )
191 testReduce<double>( src, sum, avg, max, min, dim );
196 tempCode = checkOp( src, dstType, CV_REDUCE_SUM, sum, dim );
197 code = tempCode != cvtest::TS::OK ? tempCode : code;
200 tempCode = checkOp( src, dstType, CV_REDUCE_AVG, avg, dim );
201 code = tempCode != cvtest::TS::OK ? tempCode : code;
204 tempCode = checkOp( src, dstType, CV_REDUCE_MAX, max, dim );
205 code = tempCode != cvtest::TS::OK ? tempCode : code;
208 tempCode = checkOp( src, dstType, CV_REDUCE_MIN, min, dim );
209 code = tempCode != cvtest::TS::OK ? tempCode : code;
214 int Core_ReduceTest::checkDim( int dim, Size sz )
216 int code = cvtest::TS::OK, tempCode;
219 tempCode = checkCase( CV_8UC1, CV_8UC1, dim, sz );
220 code = tempCode != cvtest::TS::OK ? tempCode : code;
222 tempCode = checkCase( CV_8UC1, CV_32SC1, dim, sz );
223 code = tempCode != cvtest::TS::OK ? tempCode : code;
225 tempCode = checkCase( CV_8UC1, CV_32FC1, dim, sz );
226 code = tempCode != cvtest::TS::OK ? tempCode : code;
228 tempCode = checkCase( CV_8UC1, CV_64FC1, dim, sz );
229 code = tempCode != cvtest::TS::OK ? tempCode : code;
232 tempCode = checkCase( CV_16UC1, CV_32FC1, dim, sz );
233 code = tempCode != cvtest::TS::OK ? tempCode : code;
235 tempCode = checkCase( CV_16UC1, CV_64FC1, dim, sz );
236 code = tempCode != cvtest::TS::OK ? tempCode : code;
239 tempCode = checkCase( CV_16SC1, CV_32FC1, dim, sz );
240 code = tempCode != cvtest::TS::OK ? tempCode : code;
242 tempCode = checkCase( CV_16SC1, CV_64FC1, dim, sz );
243 code = tempCode != cvtest::TS::OK ? tempCode : code;
246 tempCode = checkCase( CV_32FC1, CV_32FC1, dim, sz );
247 code = tempCode != cvtest::TS::OK ? tempCode : code;
249 tempCode = checkCase( CV_32FC1, CV_64FC1, dim, sz );
250 code = tempCode != cvtest::TS::OK ? tempCode : code;
253 tempCode = checkCase( CV_64FC1, CV_64FC1, dim, sz );
254 code = tempCode != cvtest::TS::OK ? tempCode : code;
259 int Core_ReduceTest::checkSize( Size sz )
261 int code = cvtest::TS::OK, tempCode;
263 tempCode = checkDim( 0, sz ); // rows
264 code = tempCode != cvtest::TS::OK ? tempCode : code;
266 tempCode = checkDim( 1, sz ); // cols
267 code = tempCode != cvtest::TS::OK ? tempCode : code;
272 void Core_ReduceTest::run( int )
274 int code = cvtest::TS::OK, tempCode;
276 tempCode = checkSize( Size(1,1) );
277 code = tempCode != cvtest::TS::OK ? tempCode : code;
279 tempCode = checkSize( Size(1,100) );
280 code = tempCode != cvtest::TS::OK ? tempCode : code;
282 tempCode = checkSize( Size(100,1) );
283 code = tempCode != cvtest::TS::OK ? tempCode : code;
285 tempCode = checkSize( Size(1000,500) );
286 code = tempCode != cvtest::TS::OK ? tempCode : code;
288 ts->set_failed_test_info( code );
294 TEST(Core_PCA, accuracy)
296 const Size sz(200, 500);
298 double diffPrjEps, diffBackPrjEps,
301 int maxComponents = 100;
302 double retainedVariance = 0.95;
303 Mat rPoints(sz, CV_32FC1), rTestPoints(sz, CV_32FC1);
306 rng.fill( rPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) );
307 rng.fill( rTestPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) );
309 PCA rPCA( rPoints, Mat(), CV_PCA_DATA_AS_ROW, maxComponents ), cPCA;
311 // 1. check C++ PCA & ROW
312 Mat rPrjTestPoints = rPCA.project( rTestPoints );
313 Mat rBackPrjTestPoints = rPCA.backProject( rPrjTestPoints );
315 Mat avg(1, sz.width, CV_32FC1 );
316 cv::reduce( rPoints, avg, 0, CV_REDUCE_AVG );
317 Mat Q = rPoints - repeat( avg, rPoints.rows, 1 ), Qt = Q.t(), eval, evec;
319 Q = Q /(float)rPoints.rows;
321 eigen( Q, eval, evec );
326 Mat subEval( maxComponents, 1, eval.type(), eval.ptr() ),
327 subEvec( maxComponents, evec.cols, evec.type(), evec.ptr() );
330 Mat prjTestPoints, backPrjTestPoints, cPoints = rPoints.t(), cTestPoints = rTestPoints.t();
331 CvMat _points, _testPoints, _avg, _eval, _evec, _prjTestPoints, _backPrjTestPoints;
335 double eigenEps = 1e-4;
337 for(int i = 0; i < Q.rows; i++ )
339 Mat v = evec.row(i).t();
342 Mat lv = eval.at<float>(i,0) * v;
343 err = cvtest::norm(Qv, lv, NORM_L2 | NORM_RELATIVE);
344 EXPECT_LE(err, eigenEps) << "bad accuracy of eigen(); i = " << i;
346 // check pca eigenvalues
347 evalEps = 1e-5, evecEps = 5e-3;
348 err = cvtest::norm(rPCA.eigenvalues, subEval, NORM_L2 | NORM_RELATIVE);
349 EXPECT_LE(err , evalEps) << "pca.eigenvalues is incorrect (CV_PCA_DATA_AS_ROW)";
350 // check pca eigenvectors
351 for(int i = 0; i < subEvec.rows; i++)
353 Mat r0 = rPCA.eigenvectors.row(i);
354 Mat r1 = subEvec.row(i);
355 // eigenvectors have normalized length, but both directions v and -v are valid
356 double err1 = cvtest::norm(r0, r1, NORM_L2 | NORM_RELATIVE);
357 double err2 = cvtest::norm(r0, -r1, NORM_L2 | NORM_RELATIVE);
358 err = std::min(err1, err2);
362 absdiff(rPCA.eigenvectors, subEvec, tmp);
363 double mval = 0; Point mloc;
364 minMaxLoc(tmp, 0, &mval, 0, &mloc);
366 EXPECT_LE(err, evecEps) << "pca.eigenvectors is incorrect (CV_PCA_DATA_AS_ROW) at " << i << " "
367 << cv::format("max diff is %g at (i=%d, j=%d) (%g vs %g)\n",
368 mval, mloc.y, mloc.x, rPCA.eigenvectors.at<float>(mloc.y, mloc.x),
369 subEvec.at<float>(mloc.y, mloc.x))
370 << "r0=" << r0 << std::endl
371 << "r1=" << r1 << std::endl
372 << "err1=" << err1 << " err2=" << err2
377 prjEps = 1.265, backPrjEps = 1.265;
378 for( int i = 0; i < rTestPoints.rows; i++ )
381 Mat subEvec_t = subEvec.t();
382 Mat prj = rTestPoints.row(i) - avg; prj *= subEvec_t;
383 err = cvtest::norm(rPrjTestPoints.row(i), prj, NORM_L2 | NORM_RELATIVE);
386 EXPECT_LE(err, prjEps) << "bad accuracy of project() (CV_PCA_DATA_AS_ROW)";
389 // check pca backProject
390 Mat backPrj = rPrjTestPoints.row(i) * subEvec + avg;
391 err = cvtest::norm(rBackPrjTestPoints.row(i), backPrj, NORM_L2 | NORM_RELATIVE);
392 if (err > backPrjEps)
394 EXPECT_LE(err, backPrjEps) << "bad accuracy of backProject() (CV_PCA_DATA_AS_ROW)";
399 // 2. check C++ PCA & COL
400 cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, maxComponents );
401 diffPrjEps = 1, diffBackPrjEps = 1;
402 Mat ocvPrjTestPoints = cPCA.project(rTestPoints.t());
403 err = cvtest::norm(cv::abs(ocvPrjTestPoints), cv::abs(rPrjTestPoints.t()), NORM_L2 | NORM_RELATIVE);
404 ASSERT_LE(err, diffPrjEps) << "bad accuracy of project() (CV_PCA_DATA_AS_COL)";
405 err = cvtest::norm(cPCA.backProject(ocvPrjTestPoints), rBackPrjTestPoints.t(), NORM_L2 | NORM_RELATIVE);
406 ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of backProject() (CV_PCA_DATA_AS_COL)";
408 // 3. check C++ PCA w/retainedVariance
409 cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, retainedVariance );
410 diffPrjEps = 1, diffBackPrjEps = 1;
411 Mat rvPrjTestPoints = cPCA.project(rTestPoints.t());
413 if( cPCA.eigenvectors.rows > maxComponents)
414 err = cvtest::norm(cv::abs(rvPrjTestPoints.rowRange(0,maxComponents)), cv::abs(rPrjTestPoints.t()), NORM_L2 | NORM_RELATIVE);
416 err = cvtest::norm(cv::abs(rvPrjTestPoints), cv::abs(rPrjTestPoints.colRange(0,cPCA.eigenvectors.rows).t()), NORM_L2 | NORM_RELATIVE);
418 ASSERT_LE(err, diffPrjEps) << "bad accuracy of project() (CV_PCA_DATA_AS_COL); retainedVariance=" << retainedVariance;
419 err = cvtest::norm(cPCA.backProject(rvPrjTestPoints), rBackPrjTestPoints.t(), NORM_L2 | NORM_RELATIVE);
420 ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of backProject() (CV_PCA_DATA_AS_COL); retainedVariance=" << retainedVariance;
423 // 4. check C PCA & ROW
424 _points = cvMat(rPoints);
425 _testPoints = cvMat(rTestPoints);
429 prjTestPoints.create(rTestPoints.rows, maxComponents, rTestPoints.type() );
430 backPrjTestPoints.create(rPoints.size(), rPoints.type() );
431 _prjTestPoints = cvMat(prjTestPoints);
432 _backPrjTestPoints = cvMat(backPrjTestPoints);
434 cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_ROW );
435 cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );
436 cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );
438 err = cvtest::norm(prjTestPoints, rPrjTestPoints, NORM_L2 | NORM_RELATIVE);
439 ASSERT_LE(err, diffPrjEps) << "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_ROW)";
440 err = cvtest::norm(backPrjTestPoints, rBackPrjTestPoints, NORM_L2 | NORM_RELATIVE);
441 ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_ROW)";
443 // 5. check C PCA & COL
444 _points = cvMat(cPoints);
445 _testPoints = cvMat(cTestPoints);
446 avg = avg.t(); _avg = cvMat(avg);
447 eval = eval.t(); _eval = cvMat(eval);
448 evec = evec.t(); _evec = cvMat(evec);
449 prjTestPoints = prjTestPoints.t(); _prjTestPoints = cvMat(prjTestPoints);
450 backPrjTestPoints = backPrjTestPoints.t(); _backPrjTestPoints = cvMat(backPrjTestPoints);
452 cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_COL );
453 cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );
454 cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );
456 err = cvtest::norm(cv::abs(prjTestPoints), cv::abs(rPrjTestPoints.t()), NORM_L2 | NORM_RELATIVE);
457 ASSERT_LE(err, diffPrjEps) << "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_COL)";
458 err = cvtest::norm(backPrjTestPoints, rBackPrjTestPoints.t(), NORM_L2 | NORM_RELATIVE);
459 ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_COL)";
461 // Test read and write
462 FileStorage fs( "PCA_store.yml", FileStorage::WRITE );
467 fs.open( "PCA_store.yml", FileStorage::READ );
468 lPCA.read( fs.root() );
469 err = cvtest::norm(rPCA.eigenvectors, lPCA.eigenvectors, NORM_L2 | NORM_RELATIVE);
470 EXPECT_LE(err, 0) << "bad accuracy of write/load functions (YML)";
471 err = cvtest::norm(rPCA.eigenvalues, lPCA.eigenvalues, NORM_L2 | NORM_RELATIVE);
472 EXPECT_LE(err, 0) << "bad accuracy of write/load functions (YML)";
473 err = cvtest::norm(rPCA.mean, lPCA.mean, NORM_L2 | NORM_RELATIVE);
474 EXPECT_LE(err, 0) << "bad accuracy of write/load functions (YML)";
477 class Core_ArrayOpTest : public cvtest::BaseTest
487 Core_ArrayOpTest::Core_ArrayOpTest()
490 Core_ArrayOpTest::~Core_ArrayOpTest() {}
492 static string idx2string(const int* idx, int dims)
496 for( int k = 0; k < dims; k++ )
498 sprintf(ptr, "%4d ", idx[k]);
505 static const int* string2idx(const string& s, int* idx, int dims)
507 const char* ptr = s.c_str();
508 for( int k = 0; k < dims; k++ )
511 sscanf(ptr, "%d%n", idx + k, &n);
517 static double getValue(SparseMat& M, const int* idx, RNG& rng)
520 size_t hv = 0, *phv = 0;
521 if( (unsigned)rng % 2 )
523 hv = d == 2 ? M.hash(idx[0], idx[1]) :
524 d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
528 const uchar* ptr = d == 2 ? M.ptr(idx[0], idx[1], false, phv) :
529 d == 3 ? M.ptr(idx[0], idx[1], idx[2], false, phv) :
530 M.ptr(idx, false, phv);
531 return !ptr ? 0 : M.type() == CV_32F ? *(float*)ptr : M.type() == CV_64F ? *(double*)ptr : 0;
534 static double getValue(const CvSparseMat* M, const int* idx)
537 const uchar* ptr = cvPtrND(M, idx, &type, 0);
538 return !ptr ? 0 : type == CV_32F ? *(float*)ptr : type == CV_64F ? *(double*)ptr : 0;
541 static void eraseValue(SparseMat& M, const int* idx, RNG& rng)
544 size_t hv = 0, *phv = 0;
545 if( (unsigned)rng % 2 )
547 hv = d == 2 ? M.hash(idx[0], idx[1]) :
548 d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
553 M.erase(idx[0], idx[1], phv);
555 M.erase(idx[0], idx[1], idx[2], phv);
560 static void eraseValue(CvSparseMat* M, const int* idx)
565 static void setValue(SparseMat& M, const int* idx, double value, RNG& rng)
568 size_t hv = 0, *phv = 0;
569 if( (unsigned)rng % 2 )
571 hv = d == 2 ? M.hash(idx[0], idx[1]) :
572 d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
576 uchar* ptr = d == 2 ? M.ptr(idx[0], idx[1], true, phv) :
577 d == 3 ? M.ptr(idx[0], idx[1], idx[2], true, phv) :
578 M.ptr(idx, true, phv);
579 if( M.type() == CV_32F )
580 *(float*)ptr = (float)value;
581 else if( M.type() == CV_64F )
582 *(double*)ptr = value;
584 CV_Error(CV_StsUnsupportedFormat, "");
587 template<typename Pixel>
588 struct InitializerFunctor{
589 /// Initializer for cv::Mat::forEach test
590 void operator()(Pixel & pixel, const int * idx) const {
597 template<typename Pixel>
598 struct InitializerFunctor5D{
599 /// Initializer for cv::Mat::forEach test (5 dimensional case)
600 void operator()(Pixel & pixel, const int * idx) const {
609 template<typename Pixel>
612 void operator()(const Pixel &, const int *) const {}
616 void Core_ArrayOpTest::run( int /* start_from */)
620 // dense matrix operations
622 int sz3[] = {5, 10, 15};
623 MatND A(3, sz3, CV_32F), B(3, sz3, CV_16SC4);
624 CvMatND matA = cvMatND(A), matB = cvMatND(B);
626 rng.fill(A, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10));
627 rng.fill(B, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10));
629 int idx0[] = {3,4,5}, idx1[] = {0, 9, 7};
631 Scalar val1(-1000, 30, 3, 8);
632 cvSetRealND(&matA, idx0, val0);
633 cvSetReal3D(&matA, idx1[0], idx1[1], idx1[2], -val0);
634 cvSetND(&matB, idx0, cvScalar(val1));
635 cvSet3D(&matB, idx1[0], idx1[1], idx1[2], cvScalar(-val1));
636 Ptr<CvMatND> matC(cvCloneMatND(&matB));
638 if( A.at<float>(idx0[0], idx0[1], idx0[2]) != val0 ||
639 A.at<float>(idx1[0], idx1[1], idx1[2]) != -val0 ||
640 cvGetReal3D(&matA, idx0[0], idx0[1], idx0[2]) != val0 ||
641 cvGetRealND(&matA, idx1) != -val0 ||
643 Scalar(B.at<Vec4s>(idx0[0], idx0[1], idx0[2])) != val1 ||
644 Scalar(B.at<Vec4s>(idx1[0], idx1[1], idx1[2])) != -val1 ||
645 Scalar(cvGet3D(matC, idx0[0], idx0[1], idx0[2])) != val1 ||
646 Scalar(cvGetND(matC, idx1)) != -val1 )
648 ts->printf(cvtest::TS::LOG, "one of cvSetReal3D, cvSetRealND, cvSet3D, cvSetND "
649 "or the corresponding *Get* functions is not correct\n");
653 // test cv::Mat::forEach
655 const int dims[3] = { 101, 107, 7 };
656 typedef cv::Point3i Pixel;
658 cv::Mat a = cv::Mat::zeros(3, dims, CV_32SC3);
659 InitializerFunctor<Pixel> initializer;
661 a.forEach<Pixel>(initializer);
664 bool error_reported = false;
665 for (int i0 = 0; i0 < dims[0]; ++i0) {
666 for (int i1 = 0; i1 < dims[1]; ++i1) {
667 for (int i2 = 0; i2 < dims[2]; ++i2) {
668 Pixel& pixel = a.at<Pixel>(i0, i1, i2);
669 if (pixel.x != i0 || pixel.y != i1 || pixel.z != i2) {
670 if (!error_reported) {
671 ts->printf(cvtest::TS::LOG, "forEach is not correct.\n"
672 "First error detected at (%d, %d, %d).\n", pixel.x, pixel.y, pixel.z);
673 error_reported = true;
684 for (size_t i = 0; i < sizeof(dims) / sizeof(dims[0]); ++i) {
685 total2 += ((dims[i] - 1) * dims[i] / 2) * dims[0] * dims[1] * dims[2] / dims[i];
687 if (total != total2) {
688 ts->printf(cvtest::TS::LOG, "forEach is not correct because total is invalid.\n");
693 // test cv::Mat::forEach
694 // with a matrix that has more dimensions than columns
695 // See https://github.com/opencv/opencv/issues/8447
697 const int dims[5] = { 2, 2, 2, 2, 2 };
698 typedef cv::Vec<int, 5> Pixel;
700 cv::Mat a = cv::Mat::zeros(5, dims, CV_32SC(5));
701 InitializerFunctor5D<Pixel> initializer;
703 a.forEach<Pixel>(initializer);
706 bool error_reported = false;
707 for (int i0 = 0; i0 < dims[0]; ++i0) {
708 for (int i1 = 0; i1 < dims[1]; ++i1) {
709 for (int i2 = 0; i2 < dims[2]; ++i2) {
710 for (int i3 = 0; i3 < dims[3]; ++i3) {
711 for (int i4 = 0; i4 < dims[4]; ++i4) {
712 const int i[5] = { i0, i1, i2, i3, i4 };
713 Pixel& pixel = a.at<Pixel>(i);
714 if (pixel[0] != i0 || pixel[1] != i1 || pixel[2] != i2 || pixel[3] != i3 || pixel[4] != i4) {
715 if (!error_reported) {
716 ts->printf(cvtest::TS::LOG, "forEach is not correct.\n"
717 "First error detected at position (%d, %d, %d, %d, %d), got value (%d, %d, %d, %d, %d).\n",
719 pixel[0], pixel[1], pixel[2], pixel[3], pixel[4]);
720 error_reported = true;
735 for (size_t i = 0; i < sizeof(dims) / sizeof(dims[0]); ++i) {
736 total2 += ((dims[i] - 1) * dims[i] / 2) * dims[0] * dims[1] * dims[2] * dims[3] * dims[4] / dims[i];
738 if (total != total2) {
739 ts->printf(cvtest::TS::LOG, "forEach is not correct because total is invalid.\n");
744 // test const cv::Mat::forEach
746 const Mat a(10, 10, CV_32SC3);
747 Mat b(10, 10, CV_32SC3);
749 a.forEach<Point3i>(EmptyFunctor<Point3i>());
750 b.forEach<Point3i>(EmptyFunctor<const Point3i>());
751 c.forEach<Point3i>(EmptyFunctor<Point3i>());
752 // tests compilation, no runtime check is needed
756 const int MAX_DIM = 5, MAX_DIM_SZ = 10;
757 // sparse matrix operations
758 for( int si = 0; si < 10; si++ )
760 int depth = (unsigned)rng % 2 == 0 ? CV_32F : CV_64F;
761 int dims = ((unsigned)rng % MAX_DIM) + 1;
762 int i, k, size[MAX_DIM]={0}, idx[MAX_DIM]={0};
763 vector<string> all_idxs;
764 vector<double> all_vals;
765 vector<double> all_vals2;
766 string sidx, min_sidx, max_sidx;
767 double min_val=0, max_val=0;
770 for( k = 0; k < dims; k++ )
772 size[k] = ((unsigned)rng % MAX_DIM_SZ) + 1;
775 SparseMat M( dims, size, depth );
776 map<string, double> M0;
778 int nz0 = (unsigned)rng % std::max(p/5,10);
779 nz0 = std::min(std::max(nz0, 1), p);
780 all_vals.resize(nz0);
781 all_vals2.resize(nz0);
782 Mat_<double> _all_vals(all_vals), _all_vals2(all_vals2);
783 rng.fill(_all_vals, CV_RAND_UNI, Scalar(-1000), Scalar(1000));
784 if( depth == CV_32F )
787 _all_vals.convertTo(_all_vals_f, CV_32F);
788 _all_vals_f.convertTo(_all_vals, CV_64F);
790 _all_vals.convertTo(_all_vals2, _all_vals2.type(), 2);
791 if( depth == CV_32F )
794 _all_vals2.convertTo(_all_vals2_f, CV_32F);
795 _all_vals2_f.convertTo(_all_vals2, CV_64F);
798 minMaxLoc(_all_vals, &min_val, &max_val);
799 double _norm0 = cv/*test*/::norm(_all_vals, CV_C);
800 double _norm1 = cv/*test*/::norm(_all_vals, CV_L1);
801 double _norm2 = cv/*test*/::norm(_all_vals, CV_L2);
803 for( i = 0; i < nz0; i++ )
807 for( k = 0; k < dims; k++ )
808 idx[k] = (unsigned)rng % size[k];
809 sidx = idx2string(idx, dims);
810 if( M0.count(sidx) == 0 )
813 all_idxs.push_back(sidx);
814 M0[sidx] = all_vals[i];
815 if( all_vals[i] == min_val )
817 if( all_vals[i] == max_val )
819 setValue(M, idx, all_vals[i], rng);
820 double v = getValue(M, idx, rng);
821 if( v != all_vals[i] )
823 ts->printf(cvtest::TS::LOG, "%d. immediately after SparseMat[%s]=%.20g the current value is %.20g\n",
824 i, sidx.c_str(), all_vals[i], v);
830 Ptr<CvSparseMat> M2(cvCreateSparseMat(M));
833 SparseMat M3; SparseMat(Md).convertTo(M3, Md.type(), 2);
835 int nz1 = (int)M.nzcount(), nz2 = (int)M3.nzcount();
836 double norm0 = cv/*test*/::norm(M, CV_C);
837 double norm1 = cv/*test*/::norm(M, CV_L1);
838 double norm2 = cv/*test*/::norm(M, CV_L2);
839 double eps = depth == CV_32F ? FLT_EPSILON*100 : DBL_EPSILON*1000;
841 if( nz1 != nz0 || nz2 != nz0)
844 ts->printf(cvtest::TS::LOG, "%d: The number of non-zero elements before/after converting to/from dense matrix is not correct: %d/%d (while it should be %d)\n",
849 if( fabs(norm0 - _norm0) > fabs(_norm0)*eps ||
850 fabs(norm1 - _norm1) > fabs(_norm1)*eps ||
851 fabs(norm2 - _norm2) > fabs(_norm2)*eps )
854 ts->printf(cvtest::TS::LOG, "%d: The norms are different: %.20g/%.20g/%.20g vs %.20g/%.20g/%.20g\n",
855 si, norm0, norm1, norm2, _norm0, _norm1, _norm2 );
859 int n = (unsigned)rng % std::max(p/5,10);
860 n = std::min(std::max(n, 1), p) + nz0;
862 for( i = 0; i < n; i++ )
864 double val1, val2, val3, val0;
868 string2idx(sidx, idx, dims);
873 for( k = 0; k < dims; k++ )
874 idx[k] = (unsigned)rng % size[k];
875 sidx = idx2string(idx, dims);
878 val1 = getValue(M, idx, rng);
879 val2 = getValue(M2, idx);
880 val3 = getValue(M3, idx, rng);
882 if( val1 != val0 || val2 != val0 || fabs(val3 - val0*2) > fabs(val0*2)*FLT_EPSILON )
885 ts->printf(cvtest::TS::LOG, "SparseMat M[%s] = %g/%g/%g (while it should be %g)\n", sidx.c_str(), val1, val2, val3, val0 );
890 for( i = 0; i < n; i++ )
896 string2idx(sidx, idx, dims);
900 for( k = 0; k < dims; k++ )
901 idx[k] = (unsigned)rng % size[k];
902 sidx = idx2string(idx, dims);
904 eraseValue(M, idx, rng);
906 val1 = getValue(M, idx, rng);
907 val2 = getValue(M2, idx);
908 if( val1 != 0 || val2 != 0 )
911 ts->printf(cvtest::TS::LOG, "SparseMat: after deleting M[%s], it is =%g/%g (while it should be 0)\n", sidx.c_str(), val1, val2 );
916 int nz = (int)M.nzcount();
920 ts->printf(cvtest::TS::LOG, "The number of non-zero elements after removing all the elements = %d (while it should be 0)\n", nz );
924 int idx1[MAX_DIM], idx2[MAX_DIM];
925 double val1 = 0, val2 = 0;
927 cv::minMaxLoc(M3, &val1, &val2, idx1, idx2);
928 string s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims);
929 if( val1 != min_val || val2 != max_val || s1 != min_sidx || s2 != max_sidx )
932 ts->printf(cvtest::TS::LOG, "%d. Sparse: The value and positions of minimum/maximum elements are different from the reference values and positions:\n\t"
933 "(%g, %g, %s, %s) vs (%g, %g, %s, %s)\n", si, val1, val2, s1.c_str(), s2.c_str(),
934 min_val, max_val, min_sidx.c_str(), max_sidx.c_str());
938 cv::minMaxIdx(Md, &val1, &val2, idx1, idx2);
939 s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims);
940 if( (min_val < 0 && (val1 != min_val || s1 != min_sidx)) ||
941 (max_val > 0 && (val2 != max_val || s2 != max_sidx)) )
944 ts->printf(cvtest::TS::LOG, "%d. Dense: The value and positions of minimum/maximum elements are different from the reference values and positions:\n\t"
945 "(%g, %g, %s, %s) vs (%g, %g, %s, %s)\n", si, val1, val2, s1.c_str(), s2.c_str(),
946 min_val, max_val, min_sidx.c_str(), max_sidx.c_str());
951 ts->set_failed_test_info(errcount == 0 ? cvtest::TS::OK : cvtest::TS::FAIL_INVALID_OUTPUT);
955 template <class ElemType>
956 int calcDiffElemCountImpl(const vector<Mat>& mv, const Mat& m)
958 int diffElemCount = 0;
959 const int mChannels = m.channels();
960 for(int y = 0; y < m.rows; y++)
962 for(int x = 0; x < m.cols; x++)
964 const ElemType* mElem = &m.at<ElemType>(y,x*mChannels);
966 for(size_t i = 0; i < mv.size(); i++)
968 const size_t mvChannel = mv[i].channels();
969 const ElemType* mvElem = &mv[i].at<ElemType>(y,x*(int)mvChannel);
970 for(size_t li = 0; li < mvChannel; li++)
971 if(mElem[loc + li] != mvElem[li])
975 CV_Assert(loc == (size_t)mChannels);
978 return diffElemCount;
982 int calcDiffElemCount(const vector<Mat>& mv, const Mat& m)
984 int depth = m.depth();
988 return calcDiffElemCountImpl<uchar>(mv, m);
990 return calcDiffElemCountImpl<char>(mv, m);
992 return calcDiffElemCountImpl<unsigned short>(mv, m);
994 return calcDiffElemCountImpl<short int>(mv, m);
996 return calcDiffElemCountImpl<int>(mv, m);
998 return calcDiffElemCountImpl<float>(mv, m);
1000 return calcDiffElemCountImpl<double>(mv, m);
1006 class Core_MergeSplitBaseTest : public cvtest::BaseTest
1009 virtual int run_case(int depth, size_t channels, const Size& size, RNG& rng) = 0;
1011 virtual void run(int)
1014 // mv is vector<Mat>
1015 const int minMSize = 1;
1016 const int maxMSize = 100;
1017 const size_t maxMvSize = 10;
1019 RNG& rng = theRNG();
1020 Size mSize(rng.uniform(minMSize, maxMSize), rng.uniform(minMSize, maxMSize));
1021 size_t mvSize = rng.uniform(1, maxMvSize);
1023 int res = cvtest::TS::OK;
1024 int curRes = run_case(CV_8U, mvSize, mSize, rng);
1025 res = curRes != cvtest::TS::OK ? curRes : res;
1027 curRes = run_case(CV_8S, mvSize, mSize, rng);
1028 res = curRes != cvtest::TS::OK ? curRes : res;
1030 curRes = run_case(CV_16U, mvSize, mSize, rng);
1031 res = curRes != cvtest::TS::OK ? curRes : res;
1033 curRes = run_case(CV_16S, mvSize, mSize, rng);
1034 res = curRes != cvtest::TS::OK ? curRes : res;
1036 curRes = run_case(CV_32S, mvSize, mSize, rng);
1037 res = curRes != cvtest::TS::OK ? curRes : res;
1039 curRes = run_case(CV_32F, mvSize, mSize, rng);
1040 res = curRes != cvtest::TS::OK ? curRes : res;
1042 curRes = run_case(CV_64F, mvSize, mSize, rng);
1043 res = curRes != cvtest::TS::OK ? curRes : res;
1045 ts->set_failed_test_info(res);
1049 class Core_MergeTest : public Core_MergeSplitBaseTest
1053 ~Core_MergeTest() {}
1056 virtual int run_case(int depth, size_t matCount, const Size& size, RNG& rng)
1058 const int maxMatChannels = 10;
1060 vector<Mat> src(matCount);
1062 for(size_t i = 0; i < src.size(); i++)
1064 Mat m(size, CV_MAKETYPE(depth, rng.uniform(1,maxMatChannels)));
1065 rng.fill(m, RNG::UNIFORM, 0, 100, true);
1066 channels += m.channels();
1074 std::stringstream commonLog;
1075 commonLog << "Depth " << depth << " :";
1076 if(dst.depth() != depth)
1078 ts->printf(cvtest::TS::LOG, "%s incorrect depth of dst (%d instead of %d)\n",
1079 commonLog.str().c_str(), dst.depth(), depth);
1080 return cvtest::TS::FAIL_INVALID_OUTPUT;
1082 if(dst.size() != size)
1084 ts->printf(cvtest::TS::LOG, "%s incorrect size of dst (%d x %d instead of %d x %d)\n",
1085 commonLog.str().c_str(), dst.rows, dst.cols, size.height, size.width);
1086 return cvtest::TS::FAIL_INVALID_OUTPUT;
1088 if(dst.channels() != channels)
1090 ts->printf(cvtest::TS::LOG, "%s: incorrect channels count of dst (%d instead of %d)\n",
1091 commonLog.str().c_str(), dst.channels(), channels);
1092 return cvtest::TS::FAIL_INVALID_OUTPUT;
1095 int diffElemCount = calcDiffElemCount(src, dst);
1096 if(diffElemCount > 0)
1098 ts->printf(cvtest::TS::LOG, "%s: there are incorrect elements in dst (part of them is %f)\n",
1099 commonLog.str().c_str(), static_cast<float>(diffElemCount)/(channels*size.area()));
1100 return cvtest::TS::FAIL_INVALID_OUTPUT;
1103 return cvtest::TS::OK;
1107 class Core_SplitTest : public Core_MergeSplitBaseTest
1111 ~Core_SplitTest() {}
1114 virtual int run_case(int depth, size_t channels, const Size& size, RNG& rng)
1116 Mat src(size, CV_MAKETYPE(depth, (int)channels));
1117 rng.fill(src, RNG::UNIFORM, 0, 100, true);
1123 std::stringstream commonLog;
1124 commonLog << "Depth " << depth << " :";
1125 if(dst.size() != channels)
1127 ts->printf(cvtest::TS::LOG, "%s incorrect count of matrices in dst (%d instead of %d)\n",
1128 commonLog.str().c_str(), dst.size(), channels);
1129 return cvtest::TS::FAIL_INVALID_OUTPUT;
1131 for(size_t i = 0; i < dst.size(); i++)
1133 if(dst[i].size() != size)
1135 ts->printf(cvtest::TS::LOG, "%s incorrect size of dst[%d] (%d x %d instead of %d x %d)\n",
1136 commonLog.str().c_str(), i, dst[i].rows, dst[i].cols, size.height, size.width);
1137 return cvtest::TS::FAIL_INVALID_OUTPUT;
1139 if(dst[i].depth() != depth)
1141 ts->printf(cvtest::TS::LOG, "%s: incorrect depth of dst[%d] (%d instead of %d)\n",
1142 commonLog.str().c_str(), i, dst[i].depth(), depth);
1143 return cvtest::TS::FAIL_INVALID_OUTPUT;
1145 if(dst[i].channels() != 1)
1147 ts->printf(cvtest::TS::LOG, "%s: incorrect channels count of dst[%d] (%d instead of %d)\n",
1148 commonLog.str().c_str(), i, dst[i].channels(), 1);
1149 return cvtest::TS::FAIL_INVALID_OUTPUT;
1153 int diffElemCount = calcDiffElemCount(dst, src);
1154 if(diffElemCount > 0)
1156 ts->printf(cvtest::TS::LOG, "%s: there are incorrect elements in dst (part of them is %f)\n",
1157 commonLog.str().c_str(), static_cast<float>(diffElemCount)/(channels*size.area()));
1158 return cvtest::TS::FAIL_INVALID_OUTPUT;
1161 return cvtest::TS::OK;
1165 TEST(Core_Reduce, accuracy) { Core_ReduceTest test; test.safe_run(); }
1166 TEST(Core_Array, basic_operations) { Core_ArrayOpTest test; test.safe_run(); }
1168 TEST(Core_Merge, shape_operations) { Core_MergeTest test; test.safe_run(); }
1169 TEST(Core_Split, shape_operations) { Core_SplitTest test; test.safe_run(); }
1172 TEST(Core_IOArray, submat_assignment)
1174 Mat1f A = Mat1f::zeros(2,2);
1175 Mat1f B = Mat1f::ones(1,3);
1177 EXPECT_THROW( B.colRange(0,3).copyTo(A.row(0)), cv::Exception );
1179 EXPECT_NO_THROW( B.colRange(0,2).copyTo(A.row(0)) );
1181 EXPECT_EQ( 1.0f, A(0,0) );
1182 EXPECT_EQ( 1.0f, A(0,1) );
1185 void OutputArray_create1(OutputArray m) { m.create(1, 2, CV_32S); }
1186 void OutputArray_create2(OutputArray m) { m.create(1, 3, CV_32F); }
1188 TEST(Core_IOArray, submat_create)
1190 Mat1f A = Mat1f::zeros(2,2);
1192 EXPECT_THROW( OutputArray_create1(A.row(0)), cv::Exception );
1193 EXPECT_THROW( OutputArray_create2(A.row(0)), cv::Exception );
1196 TEST(Core_Mat, issue4457_pass_null_ptr)
1198 ASSERT_ANY_THROW(cv::Mat mask(45, 45, CV_32F, 0));
1201 TEST(Core_Mat, reshape_1942)
1203 cv::Mat A = (cv::Mat_<float>(2,3) << 3.4884074, 1.4159607, 0.78737736, 2.3456569, -0.88010466, 0.3009364);
1206 cv::Mat_<float> M = A.reshape(3);
1212 static void check_ndim_shape(const cv::Mat &mat, int cn, int ndims, const int *sizes)
1214 EXPECT_EQ(mat.channels(), cn);
1215 EXPECT_EQ(mat.dims, ndims);
1217 if (mat.dims != ndims)
1220 for (int i = 0; i < ndims; i++)
1221 EXPECT_EQ(mat.size[i], sizes[i]);
1224 TEST(Core_Mat, reshape_ndims_2)
1226 const cv::Mat A(8, 16, CV_8UC3);
1230 int new_sizes_mask[] = { 0, 3, 4, 4 };
1231 int new_sizes_real[] = { 8, 3, 4, 4 };
1232 ASSERT_NO_THROW(B = A.reshape(1, 4, new_sizes_mask));
1233 check_ndim_shape(B, 1, 4, new_sizes_real);
1236 int new_sizes[] = { 16, 8 };
1237 ASSERT_NO_THROW(B = A.reshape(0, 2, new_sizes));
1238 check_ndim_shape(B, 3, 2, new_sizes);
1239 EXPECT_EQ(B.rows, new_sizes[0]);
1240 EXPECT_EQ(B.cols, new_sizes[1]);
1243 int new_sizes[] = { 2, 5, 1, 3 };
1244 cv::Mat A_sliced = A(cv::Range::all(), cv::Range(0, 15));
1245 ASSERT_ANY_THROW(A_sliced.reshape(4, 4, new_sizes));
1249 TEST(Core_Mat, reshape_ndims_4)
1251 const int sizes[] = { 2, 6, 4, 12 };
1252 const cv::Mat A(4, sizes, CV_8UC3);
1256 int new_sizes_mask[] = { 0, 864 };
1257 int new_sizes_real[] = { 2, 864 };
1258 ASSERT_NO_THROW(B = A.reshape(1, 2, new_sizes_mask));
1259 check_ndim_shape(B, 1, 2, new_sizes_real);
1260 EXPECT_EQ(B.rows, new_sizes_real[0]);
1261 EXPECT_EQ(B.cols, new_sizes_real[1]);
1264 int new_sizes_mask[] = { 4, 0, 0, 2, 3 };
1265 int new_sizes_real[] = { 4, 6, 4, 2, 3 };
1266 ASSERT_NO_THROW(B = A.reshape(0, 5, new_sizes_mask));
1267 check_ndim_shape(B, 3, 5, new_sizes_real);
1270 int new_sizes_mask[] = { 1, 1 };
1271 ASSERT_ANY_THROW(A.reshape(0, 2, new_sizes_mask));
1274 int new_sizes_mask[] = { 4, 6, 3, 3, 0 };
1275 ASSERT_ANY_THROW(A.reshape(0, 5, new_sizes_mask));
1279 TEST(Core_Mat, push_back)
1281 Mat a = (Mat_<float>(1,2) << 3.4884074f, 1.4159607f);
1282 Mat b = (Mat_<float>(1,2) << 0.78737736f, 2.3456569f);
1286 ASSERT_EQ(2, a.cols);
1287 ASSERT_EQ(2, a.rows);
1289 ASSERT_FLOAT_EQ(3.4884074f, a.at<float>(0, 0));
1290 ASSERT_FLOAT_EQ(1.4159607f, a.at<float>(0, 1));
1291 ASSERT_FLOAT_EQ(0.78737736f, a.at<float>(1, 0));
1292 ASSERT_FLOAT_EQ(2.3456569f, a.at<float>(1, 1));
1294 Mat c = (Mat_<float>(2,2) << -0.88010466f, 0.3009364f, 2.22399974f, -5.45933905f);
1296 ASSERT_EQ(c.rows, a.cols);
1300 ASSERT_EQ(2, a.cols);
1301 ASSERT_EQ(4, a.rows);
1303 ASSERT_FLOAT_EQ(3.4884074f, a.at<float>(0, 0));
1304 ASSERT_FLOAT_EQ(1.4159607f, a.at<float>(0, 1));
1305 ASSERT_FLOAT_EQ(0.78737736f, a.at<float>(1, 0));
1306 ASSERT_FLOAT_EQ(2.3456569f, a.at<float>(1, 1));
1307 ASSERT_FLOAT_EQ(-0.88010466f, a.at<float>(2, 0));
1308 ASSERT_FLOAT_EQ(2.22399974f, a.at<float>(2, 1));
1309 ASSERT_FLOAT_EQ(0.3009364f, a.at<float>(3, 0));
1310 ASSERT_FLOAT_EQ(-5.45933905f, a.at<float>(3, 1));
1312 a.push_back(Mat::ones(2, 2, CV_32FC1));
1314 ASSERT_EQ(6, a.rows);
1316 for(int row=4; row<a.rows; row++) {
1318 for(int col=0; col<a.cols; col++) {
1320 ASSERT_FLOAT_EQ(1.f, a.at<float>(row, col));
1325 TEST(Core_Mat, copyNx1ToVector)
1327 cv::Mat_<uchar> src(5, 1);
1328 cv::Mat_<uchar> ref_dst8;
1329 cv::Mat_<ushort> ref_dst16;
1330 std::vector<uchar> dst8;
1331 std::vector<ushort> dst16;
1333 src << 1, 2, 3, 4, 5;
1335 src.copyTo(ref_dst8);
1338 ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), ref_dst8, cv::Mat_<uchar>(dst8));
1340 src.convertTo(ref_dst16, CV_16U);
1341 src.convertTo(dst16, CV_16U);
1343 ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), ref_dst16, cv::Mat_<ushort>(dst16));
1346 TEST(Core_Matx, fromMat_)
1348 Mat_<double> a = (Mat_<double>(2,2) << 10, 11, 12, 13);
1350 ASSERT_EQ( cvtest::norm(a, b, NORM_INF), 0.);
1355 TEST(Core_Matx, from_initializer_list)
1357 Mat_<double> a = (Mat_<double>(2,2) << 10, 11, 12, 13);
1358 Matx22d b = {10, 11, 12, 13};
1359 ASSERT_EQ( cvtest::norm(a, b, NORM_INF), 0.);
1362 TEST(Core_Mat, regression_9507)
1364 cv::Mat m = Mat::zeros(5, 5, CV_8UC3);
1366 EXPECT_EQ(25u, m2.total());
1371 TEST(Core_InputArray, empty)
1373 vector<vector<Point> > data;
1374 ASSERT_TRUE( _InputArray(data).empty() );
1377 TEST(Core_CopyMask, bug1918)
1379 Mat_<unsigned char> tmpSrc(100,100);
1381 Mat_<unsigned char> tmpMask(100,100);
1383 Mat_<unsigned char> tmpDst(100,100);
1385 tmpSrc.copyTo(tmpDst,tmpMask);
1386 ASSERT_EQ(sum(tmpDst)[0], 124*100*100);
1389 TEST(Core_SVD, orthogonality)
1391 for( int i = 0; i < 2; i++ )
1393 int type = i == 0 ? CV_32F : CV_64F;
1394 Mat mat_D(2, 2, type);
1397 SVD::compute(mat_D, mat_W, mat_U, noArray(), SVD::FULL_UV);
1399 ASSERT_LT(cvtest::norm(mat_U, Mat::eye(2, 2, type), NORM_INF), 1e-5);
1404 TEST(Core_SparseMat, footprint)
1407 int sz[] = { n, n };
1408 SparseMat m(2, sz, CV_64F);
1410 int nodeSize0 = (int)m.hdr->nodeSize;
1411 double dataSize0 = ((double)m.hdr->pool.size() + (double)m.hdr->hashtab.size()*sizeof(size_t))*1e-6;
1412 printf("before: node size=%d bytes, data size=%.0f Mbytes\n", nodeSize0, dataSize0);
1414 for (int i = 0; i < n; i++)
1416 m.ref<double>(i, i) = 1;
1419 double dataSize1 = ((double)m.hdr->pool.size() + (double)m.hdr->hashtab.size()*sizeof(size_t))*1e-6;
1420 double threshold = (n*nodeSize0*1.6 + n*2.*sizeof(size_t))*1e-6;
1421 printf("after: data size=%.0f Mbytes, threshold=%.0f MBytes\n", dataSize1, threshold);
1423 ASSERT_LE((int)m.hdr->nodeSize, 32);
1424 ASSERT_LE(dataSize1, threshold);
1428 // Can't fix without dirty hacks or broken user code (PR #4159)
1429 TEST(Core_Mat_vector, DISABLED_OutputArray_create_getMat)
1431 cv::Mat_<uchar> src_base(5, 1);
1432 std::vector<uchar> dst8;
1434 src_base << 1, 2, 3, 4, 5;
1437 OutputArray _dst(dst8);
1439 _dst.create(src.rows, src.cols, src.type());
1440 Mat dst = _dst.getMat();
1441 EXPECT_EQ(src.dims, dst.dims);
1442 EXPECT_EQ(src.cols, dst.cols);
1443 EXPECT_EQ(src.rows, dst.rows);
1447 TEST(Core_Mat_vector, copyTo_roi_column)
1449 cv::Mat_<uchar> src_base(5, 2);
1450 std::vector<uchar> dst1;
1452 src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
1454 Mat src_full(src_base);
1455 Mat src(src_full.col(0));
1456 #if 0 // Can't fix without dirty hacks or broken user code (PR #4159)
1457 OutputArray _dst(dst1);
1459 _dst.create(src.rows, src.cols, src.type());
1460 Mat dst = _dst.getMat();
1461 EXPECT_EQ(src.dims, dst.dims);
1462 EXPECT_EQ(src.cols, dst.cols);
1463 EXPECT_EQ(src.rows, dst.rows);
1467 std::vector<uchar> dst2;
1469 std::cout << "src = " << src << std::endl;
1470 std::cout << "dst = " << Mat(dst2) << std::endl;
1471 EXPECT_EQ((size_t)5, dst2.size());
1472 EXPECT_EQ(1, (int)dst2[0]);
1473 EXPECT_EQ(3, (int)dst2[1]);
1474 EXPECT_EQ(5, (int)dst2[2]);
1475 EXPECT_EQ(7, (int)dst2[3]);
1476 EXPECT_EQ(9, (int)dst2[4]);
1479 TEST(Core_Mat_vector, copyTo_roi_row)
1481 cv::Mat_<uchar> src_base(2, 5);
1482 std::vector<uchar> dst1;
1484 src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
1486 Mat src_full(src_base);
1487 Mat src(src_full.row(0));
1488 OutputArray _dst(dst1);
1490 _dst.create(src.rows, src.cols, src.type());
1491 Mat dst = _dst.getMat();
1492 EXPECT_EQ(src.dims, dst.dims);
1493 EXPECT_EQ(src.cols, dst.cols);
1494 EXPECT_EQ(src.rows, dst.rows);
1497 std::vector<uchar> dst2;
1499 std::cout << "src = " << src << std::endl;
1500 std::cout << "dst = " << Mat(dst2) << std::endl;
1501 EXPECT_EQ((size_t)5, dst2.size());
1502 EXPECT_EQ(1, (int)dst2[0]);
1503 EXPECT_EQ(2, (int)dst2[1]);
1504 EXPECT_EQ(3, (int)dst2[2]);
1505 EXPECT_EQ(4, (int)dst2[3]);
1506 EXPECT_EQ(5, (int)dst2[4]);
1509 TEST(Mat, regression_5991)
1512 Mat mat(3, sz, CV_32F, Scalar(1));
1513 ASSERT_NO_THROW(mat.convertTo(mat, CV_8U));
1514 EXPECT_EQ(sz[0], mat.size[0]);
1515 EXPECT_EQ(sz[1], mat.size[1]);
1516 EXPECT_EQ(sz[2], mat.size[2]);
1517 EXPECT_EQ(0, cvtest::norm(mat, Mat(3, sz, CV_8U, Scalar(1)), NORM_INF));
1520 TEST(Mat, regression_9720)
1522 Mat mat(1, 1, CV_32FC1);
1523 mat.at<float>(0) = 1.f;
1524 const float a = 0.1f;
1525 Mat me1 = (Mat)(mat.mul((a / mat)));
1526 Mat me2 = (Mat)(mat.mul((Mat)(a / mat)));
1527 Mat me3 = (Mat)(mat.mul((a * mat)));
1528 Mat me4 = (Mat)(mat.mul((Mat)(a * mat)));
1529 EXPECT_EQ(me1.at<float>(0), me2.at<float>(0));
1530 EXPECT_EQ(me3.at<float>(0), me4.at<float>(0));
1533 #ifdef OPENCV_TEST_BIGDATA
1534 TEST(Mat, regression_6696_BigData_8Gb)
1539 Mat destImageBGR = Mat(height, width, CV_8UC3, Scalar(1, 2, 3, 0));
1540 Mat destImageA = Mat(height, width, CV_8UC1, Scalar::all(4));
1543 split(destImageBGR, planes);
1544 planes.push_back(destImageA);
1545 merge(planes, destImageBGR);
1547 EXPECT_EQ(1, destImageBGR.at<Vec4b>(0)[0]);
1548 EXPECT_EQ(2, destImageBGR.at<Vec4b>(0)[1]);
1549 EXPECT_EQ(3, destImageBGR.at<Vec4b>(0)[2]);
1550 EXPECT_EQ(4, destImageBGR.at<Vec4b>(0)[3]);
1552 EXPECT_EQ(1, destImageBGR.at<Vec4b>(height-1, width-1)[0]);
1553 EXPECT_EQ(2, destImageBGR.at<Vec4b>(height-1, width-1)[1]);
1554 EXPECT_EQ(3, destImageBGR.at<Vec4b>(height-1, width-1)[2]);
1555 EXPECT_EQ(4, destImageBGR.at<Vec4b>(height-1, width-1)[3]);
1559 TEST(Reduce, regression_should_fail_bug_4594)
1561 cv::Mat src = cv::Mat::eye(4, 4, CV_8U);
1562 std::vector<int> dst;
1564 EXPECT_THROW(cv::reduce(src, dst, 0, CV_REDUCE_MIN, CV_32S), cv::Exception);
1565 EXPECT_THROW(cv::reduce(src, dst, 0, CV_REDUCE_MAX, CV_32S), cv::Exception);
1566 EXPECT_NO_THROW(cv::reduce(src, dst, 0, CV_REDUCE_SUM, CV_32S));
1567 EXPECT_NO_THROW(cv::reduce(src, dst, 0, CV_REDUCE_AVG, CV_32S));
1570 TEST(Mat, push_back_vector)
1572 cv::Mat result(1, 5, CV_32FC1);
1574 std::vector<float> vec1(result.cols + 1);
1575 std::vector<int> vec2(result.cols);
1577 EXPECT_THROW(result.push_back(vec1), cv::Exception);
1578 EXPECT_THROW(result.push_back(vec2), cv::Exception);
1580 vec1.resize(result.cols);
1582 for (int i = 0; i < 5; ++i)
1583 result.push_back(cv::Mat(vec1).reshape(1, 1));
1585 ASSERT_EQ(6, result.rows);
1588 TEST(Mat, regression_5917_clone_empty)
1591 Mat_<Point2f> source(5, 0);
1593 ASSERT_NO_THROW(cloned = source.clone());
1596 TEST(Mat, regression_7873_mat_vector_initialize)
1598 std::vector<int> dims;
1602 Mat multi_mat(dims, CV_32FC1, cv::Scalar(0));
1604 ASSERT_EQ(3, multi_mat.dims);
1605 ASSERT_EQ(12, multi_mat.size[0]);
1606 ASSERT_EQ(3, multi_mat.size[1]);
1607 ASSERT_EQ(2, multi_mat.size[2]);
1609 std::vector<Range> ranges;
1610 ranges.push_back(Range(1, 2));
1611 ranges.push_back(Range::all());
1612 ranges.push_back(Range::all());
1613 Mat sub_mat = multi_mat(ranges);
1615 ASSERT_EQ(3, sub_mat.dims);
1616 ASSERT_EQ(1, sub_mat.size[0]);
1617 ASSERT_EQ(3, sub_mat.size[1]);
1618 ASSERT_EQ(2, sub_mat.size[2]);
1621 TEST(Mat, regression_10507_mat_setTo)
1624 Mat test_mask(sz, CV_8UC1, cv::Scalar::all(255));
1625 test_mask.at<uchar>(1,0) = 0;
1626 test_mask.at<uchar>(0,1) = 0;
1627 for (int cn = 1; cn <= 4; cn++)
1629 cv::Mat A(sz, CV_MAKE_TYPE(CV_32F, cn), cv::Scalar::all(5));
1630 A.setTo(cv::Scalar::all(std::numeric_limits<float>::quiet_NaN()), test_mask);
1632 for (int y = 0; y < A.rows; y++)
1634 for (int x = 0; x < A.cols; x++)
1636 for (int c = 0; c < cn; c++)
1638 float v = A.ptr<float>(y, x)[c];
1639 nans += (v == v) ? 0 : 1;
1643 EXPECT_EQ(nans, cn * (sz.area() - 2)) << "A=" << A << std::endl << "mask=" << test_mask << std::endl;
1647 #ifdef CV_CXX_STD_ARRAY
1648 TEST(Core_Mat_array, outputArray_create_getMat)
1650 cv::Mat_<uchar> src_base(5, 1);
1651 std::array<uchar, 5> dst8;
1653 src_base << 1, 2, 3, 4, 5;
1656 OutputArray _dst(dst8);
1659 _dst.create(src.rows, src.cols, src.type());
1660 Mat dst = _dst.getMat();
1661 EXPECT_EQ(src.dims, dst.dims);
1662 EXPECT_EQ(src.cols, dst.cols);
1663 EXPECT_EQ(src.rows, dst.rows);
1667 TEST(Core_Mat_array, copyTo_roi_column)
1669 cv::Mat_<uchar> src_base(5, 2);
1671 src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
1673 Mat src_full(src_base);
1674 Mat src(src_full.col(0));
1676 std::array<uchar, 5> dst1;
1678 std::cout << "src = " << src << std::endl;
1679 std::cout << "dst = " << Mat(dst1) << std::endl;
1680 EXPECT_EQ((size_t)5, dst1.size());
1681 EXPECT_EQ(1, (int)dst1[0]);
1682 EXPECT_EQ(3, (int)dst1[1]);
1683 EXPECT_EQ(5, (int)dst1[2]);
1684 EXPECT_EQ(7, (int)dst1[3]);
1685 EXPECT_EQ(9, (int)dst1[4]);
1688 TEST(Core_Mat_array, copyTo_roi_row)
1690 cv::Mat_<uchar> src_base(2, 5);
1691 std::array<uchar, 5> dst1;
1693 src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
1695 Mat src_full(src_base);
1696 Mat src(src_full.row(0));
1697 OutputArray _dst(dst1);
1699 _dst.create(5, 1, src.type());
1700 Mat dst = _dst.getMat();
1701 EXPECT_EQ(src.dims, dst.dims);
1702 EXPECT_EQ(1, dst.cols);
1703 EXPECT_EQ(5, dst.rows);
1706 std::array<uchar, 5> dst2;
1708 std::cout << "src = " << src << std::endl;
1709 std::cout << "dst = " << Mat(dst2) << std::endl;
1710 EXPECT_EQ(1, (int)dst2[0]);
1711 EXPECT_EQ(2, (int)dst2[1]);
1712 EXPECT_EQ(3, (int)dst2[2]);
1713 EXPECT_EQ(4, (int)dst2[3]);
1714 EXPECT_EQ(5, (int)dst2[4]);
1717 TEST(Core_Mat_array, SplitMerge)
1719 std::array<cv::Mat, 3> src;
1720 for (size_t i = 0; i < src.size(); ++i)
1722 src[i] = Mat(10, 10, CV_8U, Scalar((double)(16 * (i + 1))));
1728 std::array<cv::Mat, 3> dst;
1731 for (size_t i = 0; i < dst.size(); ++i)
1733 EXPECT_EQ(0, cvtest::norm(src[i], dst[i], NORM_INF));
1738 TEST(Mat, regression_8680)
1740 Mat_<Point2i> mat(3,1);
1741 ASSERT_EQ(mat.channels(), 2);
1743 ASSERT_EQ(mat.channels(), 2);
1748 TEST(Mat_, range_based_for)
1750 Mat_<uchar> img = Mat_<uchar>::zeros(3, 3);
1752 for(auto& pixel : img)
1757 Mat_<uchar> ref(3, 3);
1758 ref.setTo(Scalar(1));
1759 ASSERT_DOUBLE_EQ(cvtest::norm(img, ref, NORM_INF), 0.);
1762 TEST(Mat, from_initializer_list)
1764 Mat A({1.f, 2.f, 3.f});
1765 Mat_<float> B(3, 1); B << 1, 2, 3;
1766 Mat_<float> C({3}, {1,2,3});
1768 ASSERT_EQ(A.type(), CV_32F);
1769 ASSERT_DOUBLE_EQ(cvtest::norm(A, B, NORM_INF), 0.);
1770 ASSERT_DOUBLE_EQ(cvtest::norm(A, C, NORM_INF), 0.);
1771 ASSERT_DOUBLE_EQ(cvtest::norm(B, C, NORM_INF), 0.);
1773 auto D = Mat_<double>({2, 3}, {1, 2, 3, 4, 5, 6});
1774 EXPECT_EQ(2, D.rows);
1775 EXPECT_EQ(3, D.cols);
1778 TEST(Mat_, from_initializer_list)
1780 Mat_<float> A = {1, 2, 3};
1781 Mat_<float> B(3, 1); B << 1, 2, 3;
1782 Mat_<float> C({3}, {1,2,3});
1784 ASSERT_DOUBLE_EQ(cvtest::norm(A, B, NORM_INF), 0.);
1785 ASSERT_DOUBLE_EQ(cvtest::norm(A, C, NORM_INF), 0.);
1786 ASSERT_DOUBLE_EQ(cvtest::norm(B, C, NORM_INF), 0.);
1790 TEST(Mat, template_based_ptr)
1792 Mat mat = (Mat_<float>(2, 2) << 11.0f, 22.0f, 33.0f, 44.0f);
1793 int idx[2] = {1, 0};
1794 ASSERT_FLOAT_EQ(33.0f, *(mat.ptr<float>(idx)));
1797 ASSERT_FLOAT_EQ(44.0f, *(mat.ptr<float>(idx)));
1800 TEST(Mat_, template_based_ptr)
1802 int dim[4] = {2, 2, 1, 2};
1803 Mat_<float> mat = (Mat_<float>(4, dim) << 11.0f, 22.0f, 33.0f, 44.0f,
1804 55.0f, 66.0f, 77.0f, 88.0f);
1805 int idx[4] = {1, 0, 0, 1};
1806 ASSERT_FLOAT_EQ(66.0f, *(mat.ptr<float>(idx)));
1812 BIGDATA_TEST(Mat, push_back_regression_4158) // memory usage: ~10.6 Gb
1816 Mat tail(100, 500000, CV_32FC2, Scalar(1, 2));
1818 tail.copyTo(result);
1819 for (int i = 1; i < 15; i++)
1821 result.push_back(tail);
1822 std::cout << "i = " << i << " result = " << result.size() << " used = " << (uint64)result.total()*result.elemSize()*(1.0 / (1 << 20)) << " Mb"
1823 << " allocated=" << (uint64)(result.datalimit - result.datastart)*(1.0 / (1 << 20)) << " Mb" << std::endl;
1825 for (int i = 0; i < 15; i++)
1827 Rect roi(0, tail.rows * i, tail.cols, tail.rows);
1828 int nz = countNonZero(result(roi).reshape(1) == 2);
1829 EXPECT_EQ(tail.total(), (size_t)nz) << "i=" << i;
1834 TEST(Core_Merge, hang_12171)
1836 Mat src1(4, 24, CV_8UC1, Scalar::all(1));
1837 Mat src2(4, 24, CV_8UC1, Scalar::all(2));
1838 Rect src_roi(0, 0, 23, 4);
1839 Mat src_channels[2] = { src1(src_roi), src2(src_roi) };
1840 Mat dst(4, 24, CV_8UC2, Scalar::all(5));
1841 Rect dst_roi(1, 0, 23, 4);
1842 cv::merge(src_channels, 2, dst(dst_roi));
1843 EXPECT_EQ(5, dst.ptr<uchar>()[0]);
1844 EXPECT_EQ(5, dst.ptr<uchar>()[1]);
1845 EXPECT_EQ(1, dst.ptr<uchar>()[2]);
1846 EXPECT_EQ(2, dst.ptr<uchar>()[3]);
1847 EXPECT_EQ(5, dst.ptr<uchar>(1)[0]);
1848 EXPECT_EQ(5, dst.ptr<uchar>(1)[1]);
1849 EXPECT_EQ(1, dst.ptr<uchar>(1)[2]);
1850 EXPECT_EQ(2, dst.ptr<uchar>(1)[3]);
1853 TEST(Core_Split, hang_12171)
1855 Mat src(4, 24, CV_8UC2, Scalar(1,2,3,4));
1856 Rect src_roi(0, 0, 23, 4);
1857 Mat dst1(4, 24, CV_8UC1, Scalar::all(5));
1858 Mat dst2(4, 24, CV_8UC1, Scalar::all(10));
1859 Rect dst_roi(0, 0, 23, 4);
1860 Mat dst[2] = { dst1(dst_roi), dst2(dst_roi) };
1861 cv::split(src(src_roi), dst);
1862 EXPECT_EQ(1, dst1.ptr<uchar>()[0]);
1863 EXPECT_EQ(1, dst1.ptr<uchar>()[1]);
1864 EXPECT_EQ(2, dst2.ptr<uchar>()[0]);
1865 EXPECT_EQ(2, dst2.ptr<uchar>()[1]);
1866 EXPECT_EQ(1, dst1.ptr<uchar>(1)[0]);
1867 EXPECT_EQ(1, dst1.ptr<uchar>(1)[1]);
1868 EXPECT_EQ(2, dst2.ptr<uchar>(1)[0]);
1869 EXPECT_EQ(2, dst2.ptr<uchar>(1)[1]);
1872 TEST(Core_Split, crash_12171)
1874 Mat src(4, 40, CV_8UC2, Scalar(1,2,3,4));
1875 Rect src_roi(0, 0, 39, 4);
1876 Mat dst1(4, 40, CV_8UC1, Scalar::all(5));
1877 Mat dst2(4, 40, CV_8UC1, Scalar::all(10));
1878 Rect dst_roi(0, 0, 39, 4);
1879 Mat dst[2] = { dst1(dst_roi), dst2(dst_roi) };
1880 cv::split(src(src_roi), dst);
1881 EXPECT_EQ(1, dst1.ptr<uchar>()[0]);
1882 EXPECT_EQ(1, dst1.ptr<uchar>()[1]);
1883 EXPECT_EQ(2, dst2.ptr<uchar>()[0]);
1884 EXPECT_EQ(2, dst2.ptr<uchar>()[1]);
1885 EXPECT_EQ(1, dst1.ptr<uchar>(1)[0]);
1886 EXPECT_EQ(1, dst1.ptr<uchar>(1)[1]);
1887 EXPECT_EQ(2, dst2.ptr<uchar>(1)[0]);
1888 EXPECT_EQ(2, dst2.ptr<uchar>(1)[1]);
1891 TEST(Core_Merge, bug_13544)
1893 Mat src1(2, 2, CV_8UC3, Scalar::all(1));
1894 Mat src2(2, 2, CV_8UC3, Scalar::all(2));
1895 Mat src3(2, 2, CV_8UC3, Scalar::all(3));
1896 Mat src_arr[] = { src1, src2, src3 };
1898 merge(src_arr, 3, dst);
1899 ASSERT_EQ(9, dst.channels()); // Avoid memory access out of buffer
1900 EXPECT_EQ(3, (int)dst.ptr<uchar>(0)[6]);
1901 EXPECT_EQ(3, (int)dst.ptr<uchar>(0)[7]);
1902 EXPECT_EQ(3, (int)dst.ptr<uchar>(0)[8]);
1903 EXPECT_EQ(1, (int)dst.ptr<uchar>(1)[0]);
1904 EXPECT_EQ(1, (int)dst.ptr<uchar>(1)[1]);
1905 EXPECT_EQ(1, (int)dst.ptr<uchar>(1)[2]);
1906 EXPECT_EQ(2, (int)dst.ptr<uchar>(1)[3]);
1907 EXPECT_EQ(2, (int)dst.ptr<uchar>(1)[4]);
1908 EXPECT_EQ(2, (int)dst.ptr<uchar>(1)[5]);
1909 EXPECT_EQ(3, (int)dst.ptr<uchar>(1)[6]);
1910 EXPECT_EQ(3, (int)dst.ptr<uchar>(1)[7]);
1911 EXPECT_EQ(3, (int)dst.ptr<uchar>(1)[8]);
1914 struct CustomType // like cv::Keypoint
1924 static void test_CustomType(InputArray src_, OutputArray dst_)
1926 Mat src = src_.getMat();
1927 ASSERT_EQ(sizeof(CustomType), src.elemSize());
1928 CV_CheckTypeEQ(src.type(), CV_MAKETYPE(CV_8U, sizeof(CustomType)), "");
1930 CustomType* kpt = NULL;
1932 Mat dst = dst_.getMat();
1933 for (size_t i = 0; i < dst.total(); i++)
1935 kpt = dst.ptr<CustomType>(0) + i;
1936 kpt->octave = (int)i;
1939 const int N = (int)src.total();
1940 dst_.create(1, N * 2, rawType<CustomType>());
1941 Mat dst = dst_.getMat();
1942 for (size_t i = N; i < dst.total(); i++)
1944 kpt = dst.ptr<CustomType>(0) + i;
1945 kpt->octave = -(int)i;
1947 #if 0 // Compilation error
1948 CustomType& kpt = dst.at<CustomType>(0, 5);
1952 TEST(Core_InputArray, support_CustomType)
1954 std::vector<CustomType> kp1(5);
1955 std::vector<CustomType> kp2(3);
1956 test_CustomType(rawIn(kp1), rawOut(kp2));
1957 ASSERT_EQ((size_t)10, kp2.size());
1958 for (int i = 0; i < 3; i++)
1960 EXPECT_EQ(i, kp2[i].octave);
1962 for (int i = 3; i < 5; i++)
1964 EXPECT_EQ(0, kp2[i].octave);
1966 for (int i = 5; i < 10; i++)
1968 EXPECT_EQ(-i, kp2[i].octave);
1973 TEST(Core_InputArray, fetch_MatExpr)
1975 Mat a(Size(10, 5), CV_32FC1, 5);
1976 Mat b(Size(10, 5), CV_32FC1, 2);
1977 MatExpr expr = a * b.t(); // gemm expression
1979 cv::add(expr, Scalar(1), dst); // invoke gemm() here
1980 void* expr_data = expr.a.data;
1981 Mat result = expr; // should not call gemm() here again
1982 EXPECT_EQ(expr_data, result.data); // expr data is reused
1983 EXPECT_EQ(dst.size(), result.size());
1987 TEST(Core_Vectors, issue_13078)
1989 float floats_[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
1990 std::vector<float> floats(floats_, floats_ + 8);
1991 std::vector<int> ints(4);
1993 Mat m(4, 1, CV_32FC1, floats.data(), sizeof(floats[0]) * 2);
1995 m.convertTo(ints, CV_32S);
1997 ASSERT_EQ(1, ints[0]);
1998 ASSERT_EQ(3, ints[1]);
1999 ASSERT_EQ(5, ints[2]);
2000 ASSERT_EQ(7, ints[3]);
2003 TEST(Core_Vectors, issue_13078_workaround)
2005 float floats_[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
2006 std::vector<float> floats(floats_, floats_ + 8);
2007 std::vector<int> ints(4);
2009 Mat m(4, 1, CV_32FC1, floats.data(), sizeof(floats[0]) * 2);
2011 m.convertTo(Mat(ints), CV_32S);
2013 ASSERT_EQ(1, ints[0]);
2014 ASSERT_EQ(3, ints[1]);
2015 ASSERT_EQ(5, ints[2]);
2016 ASSERT_EQ(7, ints[3]);
2019 TEST(Core_MatExpr, issue_13926)
2021 Mat M1 = (Mat_<double>(4,4,CV_64FC1) << 1, 2, 3, 4,
2026 Matx44d M2(1, 2, 3, 4,
2031 EXPECT_GE(1e-6, cvtest::norm(M1*M2, M1*M1, NORM_INF)) << Mat(M1*M2) << std::endl << Mat(M1*M1);
2032 EXPECT_GE(1e-6, cvtest::norm(M2*M1, M2*M2, NORM_INF)) << Mat(M2*M1) << std::endl << Mat(M2*M2);
2035 TEST(Core_MatExpr, issue_16655)
2037 Mat a(Size(5, 5), CV_32FC3, Scalar::all(1));
2038 Mat b(Size(5, 5), CV_32FC3, Scalar::all(2));
2039 MatExpr ab_expr = a != b;
2040 Mat ab_mat = ab_expr;
2041 EXPECT_EQ(CV_8UC3, ab_expr.type())
2042 << "MatExpr: CV_8UC3 != " << typeToString(ab_expr.type());
2043 EXPECT_EQ(CV_8UC3, ab_mat.type())
2044 << "Mat: CV_8UC3 != " << typeToString(ab_mat.type());
2047 TEST(Core_MatExpr, issue_16689)
2049 Mat a(Size(10, 5), CV_32FC1, 5);
2050 Mat b(Size(10, 5), CV_32FC1, 2);
2051 Mat bt(Size(5, 10), CV_32FC1, 3);
2053 MatExpr r = a * bt; // gemm
2054 EXPECT_EQ(Mat(r).size(), r.size()) << "[10x5] x [5x10] => [5x5]";
2057 MatExpr r = a * b.t(); // gemm
2058 EXPECT_EQ(Mat(r).size(), r.size()) << "[10x5] x [10x5].t() => [5x5]";
2061 MatExpr r = a.t() * b; // gemm
2062 EXPECT_EQ(Mat(r).size(), r.size()) << "[10x5].t() x [10x5] => [10x10]";
2065 MatExpr r = a.t() * bt.t(); // gemm
2066 EXPECT_EQ(Mat(r).size(), r.size()) << "[10x5].t() x [5x10].t() => [10x10]";
2071 TEST(Core_Eigen, eigen2cv_check_Mat_type)
2073 Mat A(4, 4, CV_32FC1, Scalar::all(0));
2074 Eigen::MatrixXf eigen_A;
2075 cv2eigen(A, eigen_A);
2078 EXPECT_NO_THROW(eigen2cv(eigen_A, f_mat));
2079 EXPECT_EQ(CV_32FC1, f_mat.type());
2082 EXPECT_ANY_THROW(eigen2cv(eigen_A, d_mat));
2083 //EXPECT_EQ(CV_64FC1, d_mat.type());
2085 #endif // HAVE_EIGEN
2087 #ifdef OPENCV_EIGEN_TENSOR_SUPPORT
2088 TEST(Core_Eigen, cv2eigen_check_tensor_conversion)
2090 Mat A(2, 3, CV_32FC3);
2092 for(int row=0; row<A.rows; row++)
2093 for(int col=0; col<A.cols; col++)
2094 for(int ch=0; ch<A.channels(); ch++)
2095 A.at<Vec3f>(row,col)[ch] = value++;
2097 Eigen::Tensor<float, 3, Eigen::RowMajor> row_tensor;
2098 cv2eigen(A, row_tensor);
2100 float* mat_ptr = (float*)A.data;
2101 float* tensor_ptr = row_tensor.data();
2102 for (int i=0; i< row_tensor.size(); i++)
2103 ASSERT_FLOAT_EQ(mat_ptr[i], tensor_ptr[i]);
2105 Eigen::Tensor<float, 3, Eigen::ColMajor> col_tensor;
2106 cv2eigen(A, col_tensor);
2108 for(int row=0; row<A.rows; row++)
2109 for(int col=0; col<A.cols; col++)
2110 for(int ch=0; ch<A.channels(); ch++)
2111 ASSERT_FLOAT_EQ(value++, col_tensor(row,col,ch));
2113 #endif // OPENCV_EIGEN_TENSOR_SUPPORT
2115 #ifdef OPENCV_EIGEN_TENSOR_SUPPORT
2116 TEST(Core_Eigen, eigen2cv_check_tensor_conversion)
2118 Eigen::Tensor<float, 3, Eigen::RowMajor> row_tensor(2,3,3);
2119 Eigen::Tensor<float, 3, Eigen::ColMajor> col_tensor(2,3,3);
2121 for(int row=0; row<row_tensor.dimension(0); row++)
2122 for(int col=0; col<row_tensor.dimension(1); col++)
2123 for(int ch=0; ch<row_tensor.dimension(2); ch++)
2125 row_tensor(row,col,ch) = value;
2126 col_tensor(row,col,ch) = value;
2131 eigen2cv(row_tensor, A);
2133 float* tensor_ptr = row_tensor.data();
2134 float* mat_ptr = (float*)A.data;
2135 for (int i=0; i< row_tensor.size(); i++)
2136 ASSERT_FLOAT_EQ(tensor_ptr[i], mat_ptr[i]);
2139 eigen2cv(col_tensor, B);
2142 for(int row=0; row<B.rows; row++)
2143 for(int col=0; col<B.cols; col++)
2144 for(int ch=0; ch<B.channels(); ch++)
2145 ASSERT_FLOAT_EQ(value++, B.at<Vec3f>(row,col)[ch]);
2147 #endif // OPENCV_EIGEN_TENSOR_SUPPORT
2149 #ifdef OPENCV_EIGEN_TENSOR_SUPPORT
2150 TEST(Core_Eigen, cv2eigen_tensormap_check_tensormap_access)
2152 float arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2153 Mat a_mat(2, 2, CV_32FC3, arr);
2154 Eigen::TensorMap<Eigen::Tensor<float, 3, Eigen::RowMajor>> a_tensor = cv2eigen_tensormap<float>(a_mat);
2156 for(int i=0; i<a_mat.rows; i++) {
2157 for (int j=0; j<a_mat.cols; j++) {
2158 for (int ch=0; ch<a_mat.channels(); ch++) {
2159 ASSERT_FLOAT_EQ(a_mat.at<Vec3f>(i,j)[ch], a_tensor(i,j,ch));
2160 ASSERT_EQ(&a_mat.at<Vec3f>(i,j)[ch], &a_tensor(i,j,ch));
2165 #endif // OPENCV_EIGEN_TENSOR_SUPPORT
2167 TEST(Mat, regression_12943) // memory usage: ~4.5 Gb
2169 applyTestTag(CV_TEST_TAG_MEMORY_6GB);
2171 const int width = 0x8000;
2172 const int height = 0x10001;
2174 cv::Mat src(height, width, CV_8UC1, Scalar::all(128));
2177 cv::flip(src, dst, 0);
2180 TEST(Mat, empty_iterator_16855)
2183 EXPECT_NO_THROW(m.begin<uchar>());
2184 EXPECT_NO_THROW(m.end<uchar>());
2185 EXPECT_TRUE(m.begin<uchar>() == m.end<uchar>());
2189 TEST(Mat, regression_18473)
2191 std::vector<int> sizes(3);
2195 #if 1 // with the fix
2196 std::vector<size_t> steps(2);
2197 steps[0] = 50*100*2;
2199 #else // without the fix
2200 std::vector<size_t> steps(3);
2201 steps[0] = 50*100*2;
2205 std::vector<short> data(20*50*100, 0); // 1Mb
2206 data[data.size() - 1] = 5;
2208 // param steps Array of ndims-1 steps
2209 Mat m(sizes, CV_16SC1, (void*)data.data(), (const size_t*)steps.data());
2211 ASSERT_FALSE(m.empty());
2212 EXPECT_EQ((int)5, (int)m.at<short>(19, 49, 99));