1 #include "test_precomp.hpp"
9 class Core_ReduceTest : public cvtest::BaseTest
15 int checkOp( const Mat& src, int dstType, int opType, const Mat& opRes, int dim );
16 int checkCase( int srcType, int dstType, int dim, Size sz );
17 int checkDim( int dim, Size sz );
18 int checkSize( Size sz );
22 void testReduce( const Mat& src, Mat& sum, Mat& avg, Mat& max, Mat& min, int dim )
24 assert( src.channels() == 1 );
27 sum.create( 1, src.cols, CV_64FC1 );
28 max.create( 1, src.cols, CV_64FC1 );
29 min.create( 1, src.cols, CV_64FC1 );
33 sum.create( src.rows, 1, CV_64FC1 );
34 max.create( src.rows, 1, CV_64FC1 );
35 min.create( src.rows, 1, CV_64FC1 );
38 max.setTo(Scalar(-DBL_MAX));
39 min.setTo(Scalar(DBL_MAX));
41 const Mat_<Type>& src_ = src;
42 Mat_<double>& sum_ = (Mat_<double>&)sum;
43 Mat_<double>& min_ = (Mat_<double>&)min;
44 Mat_<double>& max_ = (Mat_<double>&)max;
48 for( int ri = 0; ri < src.rows; ri++ )
50 for( int ci = 0; ci < src.cols; ci++ )
52 sum_(0, ci) += src_(ri, ci);
53 max_(0, ci) = std::max( max_(0, ci), (double)src_(ri, ci) );
54 min_(0, ci) = std::min( min_(0, ci), (double)src_(ri, ci) );
60 for( int ci = 0; ci < src.cols; ci++ )
62 for( int ri = 0; ri < src.rows; ri++ )
64 sum_(ri, 0) += src_(ri, ci);
65 max_(ri, 0) = std::max( max_(ri, 0), (double)src_(ri, ci) );
66 min_(ri, 0) = std::min( min_(ri, 0), (double)src_(ri, ci) );
70 sum.convertTo( avg, CV_64FC1 );
71 avg = avg * (1.0 / (dim==0 ? (double)src.rows : (double)src.cols));
74 void getMatTypeStr( int type, string& str)
76 str = type == CV_8UC1 ? "CV_8UC1" :
77 type == CV_8SC1 ? "CV_8SC1" :
78 type == CV_16UC1 ? "CV_16UC1" :
79 type == CV_16SC1 ? "CV_16SC1" :
80 type == CV_32SC1 ? "CV_32SC1" :
81 type == CV_32FC1 ? "CV_32FC1" :
82 type == CV_64FC1 ? "CV_64FC1" : "unsupported matrix type";
85 int Core_ReduceTest::checkOp( const Mat& src, int dstType, int opType, const Mat& opRes, int dim )
87 int srcType = src.type();
89 if( opType == CV_REDUCE_SUM || opType == CV_REDUCE_AVG )
91 if( srcType == CV_8U && (dstType == CV_32S || dstType == CV_32F || dstType == CV_64F) )
93 if( srcType == CV_16U && (dstType == CV_32F || dstType == CV_64F) )
95 if( srcType == CV_16S && (dstType == CV_32F || dstType == CV_64F) )
97 if( srcType == CV_32F && (dstType == CV_32F || dstType == CV_64F) )
99 if( srcType == CV_64F && dstType == CV_64F)
102 else if( opType == CV_REDUCE_MAX )
104 if( srcType == CV_8U && dstType == CV_8U )
106 if( srcType == CV_32F && dstType == CV_32F )
108 if( srcType == CV_64F && dstType == CV_64F )
111 else if( opType == CV_REDUCE_MIN )
113 if( srcType == CV_8U && dstType == CV_8U)
115 if( srcType == CV_32F && dstType == CV_32F)
117 if( srcType == CV_64F && dstType == CV_64F)
121 return cvtest::TS::OK;
124 if ( opType == CV_REDUCE_SUM || opType == CV_REDUCE_AVG )
126 if ( dstType == CV_32F )
128 else if( dstType == CV_64F )
130 else if ( dstType == CV_32S )
134 assert( opRes.type() == CV_64FC1 );
136 reduce( src, _dst, dim, opType, dstType );
137 _dst.convertTo( dst, CV_64FC1 );
139 absdiff( opRes,dst,diff );
141 if (dstType == CV_32F || dstType == CV_64F)
142 check = countNonZero(diff>eps*dst) > 0;
144 check = countNonZero(diff>eps) > 0;
148 const char* opTypeStr = opType == CV_REDUCE_SUM ? "CV_REDUCE_SUM" :
149 opType == CV_REDUCE_AVG ? "CV_REDUCE_AVG" :
150 opType == CV_REDUCE_MAX ? "CV_REDUCE_MAX" :
151 opType == CV_REDUCE_MIN ? "CV_REDUCE_MIN" : "unknown operation type";
152 string srcTypeStr, dstTypeStr;
153 getMatTypeStr( src.type(), srcTypeStr );
154 getMatTypeStr( dstType, dstTypeStr );
155 const char* dimStr = dim == 0 ? "ROWS" : "COLS";
157 sprintf( msg, "bad accuracy with srcType = %s, dstType = %s, opType = %s, dim = %s",
158 srcTypeStr.c_str(), dstTypeStr.c_str(), opTypeStr, dimStr );
159 ts->printf( cvtest::TS::LOG, msg );
160 return cvtest::TS::FAIL_BAD_ACCURACY;
162 return cvtest::TS::OK;
165 int Core_ReduceTest::checkCase( int srcType, int dstType, int dim, Size sz )
167 int code = cvtest::TS::OK, tempCode;
168 Mat src, sum, avg, max, min;
170 src.create( sz, srcType );
171 randu( src, Scalar(0), Scalar(100) );
173 if( srcType == CV_8UC1 )
174 testReduce<uchar>( src, sum, avg, max, min, dim );
175 else if( srcType == CV_8SC1 )
176 testReduce<char>( src, sum, avg, max, min, dim );
177 else if( srcType == CV_16UC1 )
178 testReduce<unsigned short int>( src, sum, avg, max, min, dim );
179 else if( srcType == CV_16SC1 )
180 testReduce<short int>( src, sum, avg, max, min, dim );
181 else if( srcType == CV_32SC1 )
182 testReduce<int>( src, sum, avg, max, min, dim );
183 else if( srcType == CV_32FC1 )
184 testReduce<float>( src, sum, avg, max, min, dim );
185 else if( srcType == CV_64FC1 )
186 testReduce<double>( src, sum, avg, max, min, dim );
191 tempCode = checkOp( src, dstType, CV_REDUCE_SUM, sum, dim );
192 code = tempCode != cvtest::TS::OK ? tempCode : code;
195 tempCode = checkOp( src, dstType, CV_REDUCE_AVG, avg, dim );
196 code = tempCode != cvtest::TS::OK ? tempCode : code;
199 tempCode = checkOp( src, dstType, CV_REDUCE_MAX, max, dim );
200 code = tempCode != cvtest::TS::OK ? tempCode : code;
203 tempCode = checkOp( src, dstType, CV_REDUCE_MIN, min, dim );
204 code = tempCode != cvtest::TS::OK ? tempCode : code;
209 int Core_ReduceTest::checkDim( int dim, Size sz )
211 int code = cvtest::TS::OK, tempCode;
214 tempCode = checkCase( CV_8UC1, CV_8UC1, dim, sz );
215 code = tempCode != cvtest::TS::OK ? tempCode : code;
217 tempCode = checkCase( CV_8UC1, CV_32SC1, dim, sz );
218 code = tempCode != cvtest::TS::OK ? tempCode : code;
220 tempCode = checkCase( CV_8UC1, CV_32FC1, dim, sz );
221 code = tempCode != cvtest::TS::OK ? tempCode : code;
223 tempCode = checkCase( CV_8UC1, CV_64FC1, dim, sz );
224 code = tempCode != cvtest::TS::OK ? tempCode : code;
227 tempCode = checkCase( CV_16UC1, CV_32FC1, dim, sz );
228 code = tempCode != cvtest::TS::OK ? tempCode : code;
230 tempCode = checkCase( CV_16UC1, CV_64FC1, dim, sz );
231 code = tempCode != cvtest::TS::OK ? tempCode : code;
234 tempCode = checkCase( CV_16SC1, CV_32FC1, dim, sz );
235 code = tempCode != cvtest::TS::OK ? tempCode : code;
237 tempCode = checkCase( CV_16SC1, CV_64FC1, dim, sz );
238 code = tempCode != cvtest::TS::OK ? tempCode : code;
241 tempCode = checkCase( CV_32FC1, CV_32FC1, dim, sz );
242 code = tempCode != cvtest::TS::OK ? tempCode : code;
244 tempCode = checkCase( CV_32FC1, CV_64FC1, dim, sz );
245 code = tempCode != cvtest::TS::OK ? tempCode : code;
248 tempCode = checkCase( CV_64FC1, CV_64FC1, dim, sz );
249 code = tempCode != cvtest::TS::OK ? tempCode : code;
254 int Core_ReduceTest::checkSize( Size sz )
256 int code = cvtest::TS::OK, tempCode;
258 tempCode = checkDim( 0, sz ); // rows
259 code = tempCode != cvtest::TS::OK ? tempCode : code;
261 tempCode = checkDim( 1, sz ); // cols
262 code = tempCode != cvtest::TS::OK ? tempCode : code;
267 void Core_ReduceTest::run( int )
269 int code = cvtest::TS::OK, tempCode;
271 tempCode = checkSize( Size(1,1) );
272 code = tempCode != cvtest::TS::OK ? tempCode : code;
274 tempCode = checkSize( Size(1,100) );
275 code = tempCode != cvtest::TS::OK ? tempCode : code;
277 tempCode = checkSize( Size(100,1) );
278 code = tempCode != cvtest::TS::OK ? tempCode : code;
280 tempCode = checkSize( Size(1000,500) );
281 code = tempCode != cvtest::TS::OK ? tempCode : code;
283 ts->set_failed_test_info( code );
289 class Core_PCATest : public cvtest::BaseTest
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);
304 RNG& rng = ts->get_rng();
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 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-6;
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 );
346 ts->printf( cvtest::TS::LOG, "bad accuracy of eigen(); err = %f\n", err );
347 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
351 // check pca eigenvalues
352 evalEps = 1e-6, evecEps = 1e-3;
353 err = cvtest::norm( rPCA.eigenvalues, subEval, NORM_L2 );
356 ts->printf( cvtest::TS::LOG, "pca.eigenvalues is incorrect (CV_PCA_DATA_AS_ROW); err = %f\n", err );
357 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
360 // check pca eigenvectors
361 for(int i = 0; i < subEvec.rows; i++)
363 Mat r0 = rPCA.eigenvectors.row(i);
364 Mat r1 = subEvec.row(i);
365 err = cvtest::norm( r0, r1, CV_L2 );
369 double err2 = cvtest::norm(r0, r1, CV_L2);
373 absdiff(rPCA.eigenvectors, subEvec, tmp);
374 double mval = 0; Point mloc;
375 minMaxLoc(tmp, 0, &mval, 0, &mloc);
377 ts->printf( cvtest::TS::LOG, "pca.eigenvectors is incorrect (CV_PCA_DATA_AS_ROW); err = %f\n", err );
378 ts->printf( cvtest::TS::LOG, "max diff is %g at (i=%d, j=%d) (%g vs %g)\n",
379 mval, mloc.y, mloc.x, rPCA.eigenvectors.at<float>(mloc.y, mloc.x),
380 subEvec.at<float>(mloc.y, mloc.x));
381 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
387 prjEps = 1.265, backPrjEps = 1.265;
388 for( int i = 0; i < rTestPoints.rows; i++ )
391 Mat subEvec_t = subEvec.t();
392 Mat prj = rTestPoints.row(i) - avg; prj *= subEvec_t;
393 err = cvtest::norm(rPrjTestPoints.row(i), prj, CV_RELATIVE_L2);
396 ts->printf( cvtest::TS::LOG, "bad accuracy of project() (CV_PCA_DATA_AS_ROW); err = %f\n", err );
397 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
400 // check pca backProject
401 Mat backPrj = rPrjTestPoints.row(i) * subEvec + avg;
402 err = cvtest::norm( rBackPrjTestPoints.row(i), backPrj, CV_RELATIVE_L2 );
403 if( err > backPrjEps )
405 ts->printf( cvtest::TS::LOG, "bad accuracy of backProject() (CV_PCA_DATA_AS_ROW); err = %f\n", err );
406 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
411 // 2. check C++ PCA & COL
412 cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, maxComponents );
413 diffPrjEps = 1, diffBackPrjEps = 1;
414 Mat ocvPrjTestPoints = cPCA.project(rTestPoints.t());
415 err = cvtest::norm(cv::abs(ocvPrjTestPoints), cv::abs(rPrjTestPoints.t()), CV_RELATIVE_L2 );
416 if( err > diffPrjEps )
418 ts->printf( cvtest::TS::LOG, "bad accuracy of project() (CV_PCA_DATA_AS_COL); err = %f\n", err );
419 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
422 err = cvtest::norm(cPCA.backProject(ocvPrjTestPoints), rBackPrjTestPoints.t(), CV_RELATIVE_L2 );
423 if( err > diffBackPrjEps )
425 ts->printf( cvtest::TS::LOG, "bad accuracy of backProject() (CV_PCA_DATA_AS_COL); err = %f\n", err );
426 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
430 // 3. check C++ PCA w/retainedVariance
431 cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, retainedVariance );
432 diffPrjEps = 1, diffBackPrjEps = 1;
433 Mat rvPrjTestPoints = cPCA.project(rTestPoints.t());
435 if( cPCA.eigenvectors.rows > maxComponents)
436 err = cvtest::norm(cv::abs(rvPrjTestPoints.rowRange(0,maxComponents)), cv::abs(rPrjTestPoints.t()), CV_RELATIVE_L2 );
438 err = cvtest::norm(cv::abs(rvPrjTestPoints), cv::abs(rPrjTestPoints.colRange(0,cPCA.eigenvectors.rows).t()), CV_RELATIVE_L2 );
440 if( err > diffPrjEps )
442 ts->printf( cvtest::TS::LOG, "bad accuracy of project() (CV_PCA_DATA_AS_COL); retainedVariance=0.95; err = %f\n", err );
443 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
446 err = cvtest::norm(cPCA.backProject(rvPrjTestPoints), rBackPrjTestPoints.t(), CV_RELATIVE_L2 );
447 if( err > diffBackPrjEps )
449 ts->printf( cvtest::TS::LOG, "bad accuracy of backProject() (CV_PCA_DATA_AS_COL); retainedVariance=0.95; err = %f\n", err );
450 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
455 // 4. check C PCA & ROW
457 _testPoints = rTestPoints;
461 prjTestPoints.create(rTestPoints.rows, maxComponents, rTestPoints.type() );
462 backPrjTestPoints.create(rPoints.size(), rPoints.type() );
463 _prjTestPoints = prjTestPoints;
464 _backPrjTestPoints = backPrjTestPoints;
466 cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_ROW );
467 cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );
468 cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );
470 err = cvtest::norm(prjTestPoints, rPrjTestPoints, CV_RELATIVE_L2);
471 if( err > diffPrjEps )
473 ts->printf( cvtest::TS::LOG, "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_ROW); err = %f\n", err );
474 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
477 err = cvtest::norm(backPrjTestPoints, rBackPrjTestPoints, CV_RELATIVE_L2);
478 if( err > diffBackPrjEps )
480 ts->printf( cvtest::TS::LOG, "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_ROW); err = %f\n", err );
481 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
485 // 5. check C PCA & COL
487 _testPoints = cTestPoints;
488 avg = avg.t(); _avg = avg;
489 eval = eval.t(); _eval = eval;
490 evec = evec.t(); _evec = evec;
491 prjTestPoints = prjTestPoints.t(); _prjTestPoints = prjTestPoints;
492 backPrjTestPoints = backPrjTestPoints.t(); _backPrjTestPoints = backPrjTestPoints;
494 cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_COL );
495 cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );
496 cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );
498 err = cvtest::norm(cv::abs(prjTestPoints), cv::abs(rPrjTestPoints.t()), CV_RELATIVE_L2 );
499 if( err > diffPrjEps )
501 ts->printf( cvtest::TS::LOG, "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_COL); err = %f\n", err );
502 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
505 err = cvtest::norm(backPrjTestPoints, rBackPrjTestPoints.t(), CV_RELATIVE_L2);
506 if( err > diffBackPrjEps )
508 ts->printf( cvtest::TS::LOG, "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_COL); err = %f\n", err );
509 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
513 // Test read and write
514 FileStorage fs( "PCA_store.yml", FileStorage::WRITE );
519 fs.open( "PCA_store.yml", FileStorage::READ );
520 lPCA.read( fs.root() );
521 err = cvtest::norm( rPCA.eigenvectors, lPCA.eigenvectors, CV_RELATIVE_L2 );
524 ts->printf( cvtest::TS::LOG, "bad accuracy of write/load functions (YML); err = %f\n", err );
525 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
527 err = cvtest::norm( rPCA.eigenvalues, lPCA.eigenvalues, CV_RELATIVE_L2 );
530 ts->printf( cvtest::TS::LOG, "bad accuracy of write/load functions (YML); err = %f\n", err );
531 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
533 err = cvtest::norm( rPCA.mean, lPCA.mean, CV_RELATIVE_L2 );
536 ts->printf( cvtest::TS::LOG, "bad accuracy of write/load functions (YML); err = %f\n", err );
537 ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
542 class Core_ArrayOpTest : public cvtest::BaseTest
552 Core_ArrayOpTest::Core_ArrayOpTest()
555 Core_ArrayOpTest::~Core_ArrayOpTest() {}
557 static string idx2string(const int* idx, int dims)
561 for( int k = 0; k < dims; k++ )
563 sprintf(ptr, "%4d ", idx[k]);
570 static const int* string2idx(const string& s, int* idx, int dims)
572 const char* ptr = s.c_str();
573 for( int k = 0; k < dims; k++ )
576 sscanf(ptr, "%d%n", idx + k, &n);
582 static double getValue(SparseMat& M, const int* idx, RNG& rng)
585 size_t hv = 0, *phv = 0;
586 if( (unsigned)rng % 2 )
588 hv = d == 2 ? M.hash(idx[0], idx[1]) :
589 d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
593 const uchar* ptr = d == 2 ? M.ptr(idx[0], idx[1], false, phv) :
594 d == 3 ? M.ptr(idx[0], idx[1], idx[2], false, phv) :
595 M.ptr(idx, false, phv);
596 return !ptr ? 0 : M.type() == CV_32F ? *(float*)ptr : M.type() == CV_64F ? *(double*)ptr : 0;
599 static double getValue(const CvSparseMat* M, const int* idx)
602 const uchar* ptr = cvPtrND(M, idx, &type, 0);
603 return !ptr ? 0 : type == CV_32F ? *(float*)ptr : type == CV_64F ? *(double*)ptr : 0;
606 static void eraseValue(SparseMat& M, const int* idx, RNG& rng)
609 size_t hv = 0, *phv = 0;
610 if( (unsigned)rng % 2 )
612 hv = d == 2 ? M.hash(idx[0], idx[1]) :
613 d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
618 M.erase(idx[0], idx[1], phv);
620 M.erase(idx[0], idx[1], idx[2], phv);
625 static void eraseValue(CvSparseMat* M, const int* idx)
630 static void setValue(SparseMat& M, const int* idx, double value, RNG& rng)
633 size_t hv = 0, *phv = 0;
634 if( (unsigned)rng % 2 )
636 hv = d == 2 ? M.hash(idx[0], idx[1]) :
637 d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
641 uchar* ptr = d == 2 ? M.ptr(idx[0], idx[1], true, phv) :
642 d == 3 ? M.ptr(idx[0], idx[1], idx[2], true, phv) :
643 M.ptr(idx, true, phv);
644 if( M.type() == CV_32F )
645 *(float*)ptr = (float)value;
646 else if( M.type() == CV_64F )
647 *(double*)ptr = value;
649 CV_Error(CV_StsUnsupportedFormat, "");
652 template<typename Pixel>
653 struct InitializerFunctor{
654 /// Initializer for cv::Mat::forEach test
655 void operator()(Pixel & pixel, const int * idx) const {
662 template<typename Pixel>
663 struct InitializerFunctor5D{
664 /// Initializer for cv::Mat::forEach test (5 dimensional case)
665 void operator()(Pixel & pixel, const int * idx) const {
674 template<typename Pixel>
677 void operator()(const Pixel &, const int *) const {}
681 void Core_ArrayOpTest::run( int /* start_from */)
685 // dense matrix operations
687 int sz3[] = {5, 10, 15};
688 MatND A(3, sz3, CV_32F), B(3, sz3, CV_16SC4);
689 CvMatND matA = A, matB = B;
691 rng.fill(A, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10));
692 rng.fill(B, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10));
694 int idx0[] = {3,4,5}, idx1[] = {0, 9, 7};
696 Scalar val1(-1000, 30, 3, 8);
697 cvSetRealND(&matA, idx0, val0);
698 cvSetReal3D(&matA, idx1[0], idx1[1], idx1[2], -val0);
699 cvSetND(&matB, idx0, val1);
700 cvSet3D(&matB, idx1[0], idx1[1], idx1[2], -val1);
701 Ptr<CvMatND> matC(cvCloneMatND(&matB));
703 if( A.at<float>(idx0[0], idx0[1], idx0[2]) != val0 ||
704 A.at<float>(idx1[0], idx1[1], idx1[2]) != -val0 ||
705 cvGetReal3D(&matA, idx0[0], idx0[1], idx0[2]) != val0 ||
706 cvGetRealND(&matA, idx1) != -val0 ||
708 Scalar(B.at<Vec4s>(idx0[0], idx0[1], idx0[2])) != val1 ||
709 Scalar(B.at<Vec4s>(idx1[0], idx1[1], idx1[2])) != -val1 ||
710 Scalar(cvGet3D(matC, idx0[0], idx0[1], idx0[2])) != val1 ||
711 Scalar(cvGetND(matC, idx1)) != -val1 )
713 ts->printf(cvtest::TS::LOG, "one of cvSetReal3D, cvSetRealND, cvSet3D, cvSetND "
714 "or the corresponding *Get* functions is not correct\n");
718 // test cv::Mat::forEach
720 const int dims[3] = { 101, 107, 7 };
721 typedef cv::Point3i Pixel;
723 cv::Mat a = cv::Mat::zeros(3, dims, CV_32SC3);
724 InitializerFunctor<Pixel> initializer;
726 a.forEach<Pixel>(initializer);
729 bool error_reported = false;
730 for (int i0 = 0; i0 < dims[0]; ++i0) {
731 for (int i1 = 0; i1 < dims[1]; ++i1) {
732 for (int i2 = 0; i2 < dims[2]; ++i2) {
733 Pixel& pixel = a.at<Pixel>(i0, i1, i2);
734 if (pixel.x != i0 || pixel.y != i1 || pixel.z != i2) {
735 if (!error_reported) {
736 ts->printf(cvtest::TS::LOG, "forEach is not correct.\n"
737 "First error detected at (%d, %d, %d).\n", pixel.x, pixel.y, pixel.z);
738 error_reported = true;
749 for (size_t i = 0; i < sizeof(dims) / sizeof(dims[0]); ++i) {
750 total2 += ((dims[i] - 1) * dims[i] / 2) * dims[0] * dims[1] * dims[2] / dims[i];
752 if (total != total2) {
753 ts->printf(cvtest::TS::LOG, "forEach is not correct because total is invalid.\n");
758 // test cv::Mat::forEach
759 // with a matrix that has more dimensions than columns
760 // See https://github.com/opencv/opencv/issues/8447
762 const int dims[5] = { 2, 2, 2, 2, 2 };
763 typedef cv::Vec<int, 5> Pixel;
765 cv::Mat a = cv::Mat::zeros(5, dims, CV_32SC(5));
766 InitializerFunctor5D<Pixel> initializer;
768 a.forEach<Pixel>(initializer);
771 bool error_reported = false;
772 for (int i0 = 0; i0 < dims[0]; ++i0) {
773 for (int i1 = 0; i1 < dims[1]; ++i1) {
774 for (int i2 = 0; i2 < dims[2]; ++i2) {
775 for (int i3 = 0; i3 < dims[3]; ++i3) {
776 for (int i4 = 0; i4 < dims[4]; ++i4) {
777 const int i[5] = { i0, i1, i2, i3, i4 };
778 Pixel& pixel = a.at<Pixel>(i);
779 if (pixel[0] != i0 || pixel[1] != i1 || pixel[2] != i2 || pixel[3] != i3 || pixel[4] != i4) {
780 if (!error_reported) {
781 ts->printf(cvtest::TS::LOG, "forEach is not correct.\n"
782 "First error detected at position (%d, %d, %d, %d, %d), got value (%d, %d, %d, %d, %d).\n",
784 pixel[0], pixel[1], pixel[2], pixel[3], pixel[4]);
785 error_reported = true;
800 for (size_t i = 0; i < sizeof(dims) / sizeof(dims[0]); ++i) {
801 total2 += ((dims[i] - 1) * dims[i] / 2) * dims[0] * dims[1] * dims[2] * dims[3] * dims[4] / dims[i];
803 if (total != total2) {
804 ts->printf(cvtest::TS::LOG, "forEach is not correct because total is invalid.\n");
809 // test const cv::Mat::forEach
811 const Mat a(10, 10, CV_32SC3);
812 Mat b(10, 10, CV_32SC3);
814 a.forEach<Point3i>(EmptyFunctor<Point3i>());
815 b.forEach<Point3i>(EmptyFunctor<const Point3i>());
816 c.forEach<Point3i>(EmptyFunctor<Point3i>());
817 // tests compilation, no runtime check is needed
821 const int MAX_DIM = 5, MAX_DIM_SZ = 10;
822 // sparse matrix operations
823 for( int si = 0; si < 10; si++ )
825 int depth = (unsigned)rng % 2 == 0 ? CV_32F : CV_64F;
826 int dims = ((unsigned)rng % MAX_DIM) + 1;
827 int i, k, size[MAX_DIM]={0}, idx[MAX_DIM]={0};
828 vector<string> all_idxs;
829 vector<double> all_vals;
830 vector<double> all_vals2;
831 string sidx, min_sidx, max_sidx;
832 double min_val=0, max_val=0;
835 for( k = 0; k < dims; k++ )
837 size[k] = ((unsigned)rng % MAX_DIM_SZ) + 1;
840 SparseMat M( dims, size, depth );
841 map<string, double> M0;
843 int nz0 = (unsigned)rng % max(p/5,10);
844 nz0 = min(max(nz0, 1), p);
845 all_vals.resize(nz0);
846 all_vals2.resize(nz0);
847 Mat_<double> _all_vals(all_vals), _all_vals2(all_vals2);
848 rng.fill(_all_vals, CV_RAND_UNI, Scalar(-1000), Scalar(1000));
849 if( depth == CV_32F )
852 _all_vals.convertTo(_all_vals_f, CV_32F);
853 _all_vals_f.convertTo(_all_vals, CV_64F);
855 _all_vals.convertTo(_all_vals2, _all_vals2.type(), 2);
856 if( depth == CV_32F )
859 _all_vals2.convertTo(_all_vals2_f, CV_32F);
860 _all_vals2_f.convertTo(_all_vals2, CV_64F);
863 minMaxLoc(_all_vals, &min_val, &max_val);
864 double _norm0 = cvtest::norm(_all_vals, CV_C);
865 double _norm1 = cvtest::norm(_all_vals, CV_L1);
866 double _norm2 = cvtest::norm(_all_vals, CV_L2);
868 for( i = 0; i < nz0; i++ )
872 for( k = 0; k < dims; k++ )
873 idx[k] = (unsigned)rng % size[k];
874 sidx = idx2string(idx, dims);
875 if( M0.count(sidx) == 0 )
878 all_idxs.push_back(sidx);
879 M0[sidx] = all_vals[i];
880 if( all_vals[i] == min_val )
882 if( all_vals[i] == max_val )
884 setValue(M, idx, all_vals[i], rng);
885 double v = getValue(M, idx, rng);
886 if( v != all_vals[i] )
888 ts->printf(cvtest::TS::LOG, "%d. immediately after SparseMat[%s]=%.20g the current value is %.20g\n",
889 i, sidx.c_str(), all_vals[i], v);
895 Ptr<CvSparseMat> M2(cvCreateSparseMat(M));
898 SparseMat M3; SparseMat(Md).convertTo(M3, Md.type(), 2);
900 int nz1 = (int)M.nzcount(), nz2 = (int)M3.nzcount();
901 double norm0 = norm(M, CV_C);
902 double norm1 = norm(M, CV_L1);
903 double norm2 = norm(M, CV_L2);
904 double eps = depth == CV_32F ? FLT_EPSILON*100 : DBL_EPSILON*1000;
906 if( nz1 != nz0 || nz2 != nz0)
909 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",
914 if( fabs(norm0 - _norm0) > fabs(_norm0)*eps ||
915 fabs(norm1 - _norm1) > fabs(_norm1)*eps ||
916 fabs(norm2 - _norm2) > fabs(_norm2)*eps )
919 ts->printf(cvtest::TS::LOG, "%d: The norms are different: %.20g/%.20g/%.20g vs %.20g/%.20g/%.20g\n",
920 si, norm0, norm1, norm2, _norm0, _norm1, _norm2 );
924 int n = (unsigned)rng % max(p/5,10);
925 n = min(max(n, 1), p) + nz0;
927 for( i = 0; i < n; i++ )
929 double val1, val2, val3, val0;
933 string2idx(sidx, idx, dims);
938 for( k = 0; k < dims; k++ )
939 idx[k] = (unsigned)rng % size[k];
940 sidx = idx2string(idx, dims);
943 val1 = getValue(M, idx, rng);
944 val2 = getValue(M2, idx);
945 val3 = getValue(M3, idx, rng);
947 if( val1 != val0 || val2 != val0 || fabs(val3 - val0*2) > fabs(val0*2)*FLT_EPSILON )
950 ts->printf(cvtest::TS::LOG, "SparseMat M[%s] = %g/%g/%g (while it should be %g)\n", sidx.c_str(), val1, val2, val3, val0 );
955 for( i = 0; i < n; i++ )
961 string2idx(sidx, idx, dims);
965 for( k = 0; k < dims; k++ )
966 idx[k] = (unsigned)rng % size[k];
967 sidx = idx2string(idx, dims);
969 eraseValue(M, idx, rng);
971 val1 = getValue(M, idx, rng);
972 val2 = getValue(M2, idx);
973 if( val1 != 0 || val2 != 0 )
976 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 );
981 int nz = (int)M.nzcount();
985 ts->printf(cvtest::TS::LOG, "The number of non-zero elements after removing all the elements = %d (while it should be 0)\n", nz );
989 int idx1[MAX_DIM], idx2[MAX_DIM];
990 double val1 = 0, val2 = 0;
992 minMaxLoc(M3, &val1, &val2, idx1, idx2);
993 string s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims);
994 if( val1 != min_val || val2 != max_val || s1 != min_sidx || s2 != max_sidx )
997 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"
998 "(%g, %g, %s, %s) vs (%g, %g, %s, %s)\n", si, val1, val2, s1.c_str(), s2.c_str(),
999 min_val, max_val, min_sidx.c_str(), max_sidx.c_str());
1003 minMaxIdx(Md, &val1, &val2, idx1, idx2);
1004 s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims);
1005 if( (min_val < 0 && (val1 != min_val || s1 != min_sidx)) ||
1006 (max_val > 0 && (val2 != max_val || s2 != max_sidx)) )
1009 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"
1010 "(%g, %g, %s, %s) vs (%g, %g, %s, %s)\n", si, val1, val2, s1.c_str(), s2.c_str(),
1011 min_val, max_val, min_sidx.c_str(), max_sidx.c_str());
1016 ts->set_failed_test_info(errcount == 0 ? cvtest::TS::OK : cvtest::TS::FAIL_INVALID_OUTPUT);
1020 template <class ElemType>
1021 int calcDiffElemCountImpl(const vector<Mat>& mv, const Mat& m)
1023 int diffElemCount = 0;
1024 const int mChannels = m.channels();
1025 for(int y = 0; y < m.rows; y++)
1027 for(int x = 0; x < m.cols; x++)
1029 const ElemType* mElem = &m.at<ElemType>(y,x*mChannels);
1031 for(size_t i = 0; i < mv.size(); i++)
1033 const size_t mvChannel = mv[i].channels();
1034 const ElemType* mvElem = &mv[i].at<ElemType>(y,x*(int)mvChannel);
1035 for(size_t li = 0; li < mvChannel; li++)
1036 if(mElem[loc + li] != mvElem[li])
1040 CV_Assert(loc == (size_t)mChannels);
1043 return diffElemCount;
1047 int calcDiffElemCount(const vector<Mat>& mv, const Mat& m)
1049 int depth = m.depth();
1053 return calcDiffElemCountImpl<uchar>(mv, m);
1055 return calcDiffElemCountImpl<char>(mv, m);
1057 return calcDiffElemCountImpl<unsigned short>(mv, m);
1059 return calcDiffElemCountImpl<short int>(mv, m);
1061 return calcDiffElemCountImpl<int>(mv, m);
1063 return calcDiffElemCountImpl<float>(mv, m);
1065 return calcDiffElemCountImpl<double>(mv, m);
1071 class Core_MergeSplitBaseTest : public cvtest::BaseTest
1074 virtual int run_case(int depth, size_t channels, const Size& size, RNG& rng) = 0;
1076 virtual void run(int)
1079 // mv is vector<Mat>
1080 const int minMSize = 1;
1081 const int maxMSize = 100;
1082 const size_t maxMvSize = 10;
1084 RNG& rng = theRNG();
1085 Size mSize(rng.uniform(minMSize, maxMSize), rng.uniform(minMSize, maxMSize));
1086 size_t mvSize = rng.uniform(1, maxMvSize);
1088 int res = cvtest::TS::OK, curRes = res;
1089 curRes = run_case(CV_8U, mvSize, mSize, rng);
1090 res = curRes != cvtest::TS::OK ? curRes : res;
1092 curRes = run_case(CV_8S, mvSize, mSize, rng);
1093 res = curRes != cvtest::TS::OK ? curRes : res;
1095 curRes = run_case(CV_16U, mvSize, mSize, rng);
1096 res = curRes != cvtest::TS::OK ? curRes : res;
1098 curRes = run_case(CV_16S, mvSize, mSize, rng);
1099 res = curRes != cvtest::TS::OK ? curRes : res;
1101 curRes = run_case(CV_32S, mvSize, mSize, rng);
1102 res = curRes != cvtest::TS::OK ? curRes : res;
1104 curRes = run_case(CV_32F, mvSize, mSize, rng);
1105 res = curRes != cvtest::TS::OK ? curRes : res;
1107 curRes = run_case(CV_64F, mvSize, mSize, rng);
1108 res = curRes != cvtest::TS::OK ? curRes : res;
1110 ts->set_failed_test_info(res);
1114 class Core_MergeTest : public Core_MergeSplitBaseTest
1118 ~Core_MergeTest() {}
1121 virtual int run_case(int depth, size_t matCount, const Size& size, RNG& rng)
1123 const int maxMatChannels = 10;
1125 vector<Mat> src(matCount);
1127 for(size_t i = 0; i < src.size(); i++)
1129 Mat m(size, CV_MAKETYPE(depth, rng.uniform(1,maxMatChannels)));
1130 rng.fill(m, RNG::UNIFORM, 0, 100, true);
1131 channels += m.channels();
1139 stringstream commonLog;
1140 commonLog << "Depth " << depth << " :";
1141 if(dst.depth() != depth)
1143 ts->printf(cvtest::TS::LOG, "%s incorrect depth of dst (%d instead of %d)\n",
1144 commonLog.str().c_str(), dst.depth(), depth);
1145 return cvtest::TS::FAIL_INVALID_OUTPUT;
1147 if(dst.size() != size)
1149 ts->printf(cvtest::TS::LOG, "%s incorrect size of dst (%d x %d instead of %d x %d)\n",
1150 commonLog.str().c_str(), dst.rows, dst.cols, size.height, size.width);
1151 return cvtest::TS::FAIL_INVALID_OUTPUT;
1153 if(dst.channels() != channels)
1155 ts->printf(cvtest::TS::LOG, "%s: incorrect channels count of dst (%d instead of %d)\n",
1156 commonLog.str().c_str(), dst.channels(), channels);
1157 return cvtest::TS::FAIL_INVALID_OUTPUT;
1160 int diffElemCount = calcDiffElemCount(src, dst);
1161 if(diffElemCount > 0)
1163 ts->printf(cvtest::TS::LOG, "%s: there are incorrect elements in dst (part of them is %f)\n",
1164 commonLog.str().c_str(), static_cast<float>(diffElemCount)/(channels*size.area()));
1165 return cvtest::TS::FAIL_INVALID_OUTPUT;
1168 return cvtest::TS::OK;
1172 class Core_SplitTest : public Core_MergeSplitBaseTest
1176 ~Core_SplitTest() {}
1179 virtual int run_case(int depth, size_t channels, const Size& size, RNG& rng)
1181 Mat src(size, CV_MAKETYPE(depth, (int)channels));
1182 rng.fill(src, RNG::UNIFORM, 0, 100, true);
1188 stringstream commonLog;
1189 commonLog << "Depth " << depth << " :";
1190 if(dst.size() != channels)
1192 ts->printf(cvtest::TS::LOG, "%s incorrect count of matrices in dst (%d instead of %d)\n",
1193 commonLog.str().c_str(), dst.size(), channels);
1194 return cvtest::TS::FAIL_INVALID_OUTPUT;
1196 for(size_t i = 0; i < dst.size(); i++)
1198 if(dst[i].size() != size)
1200 ts->printf(cvtest::TS::LOG, "%s incorrect size of dst[%d] (%d x %d instead of %d x %d)\n",
1201 commonLog.str().c_str(), i, dst[i].rows, dst[i].cols, size.height, size.width);
1202 return cvtest::TS::FAIL_INVALID_OUTPUT;
1204 if(dst[i].depth() != depth)
1206 ts->printf(cvtest::TS::LOG, "%s: incorrect depth of dst[%d] (%d instead of %d)\n",
1207 commonLog.str().c_str(), i, dst[i].depth(), depth);
1208 return cvtest::TS::FAIL_INVALID_OUTPUT;
1210 if(dst[i].channels() != 1)
1212 ts->printf(cvtest::TS::LOG, "%s: incorrect channels count of dst[%d] (%d instead of %d)\n",
1213 commonLog.str().c_str(), i, dst[i].channels(), 1);
1214 return cvtest::TS::FAIL_INVALID_OUTPUT;
1218 int diffElemCount = calcDiffElemCount(dst, src);
1219 if(diffElemCount > 0)
1221 ts->printf(cvtest::TS::LOG, "%s: there are incorrect elements in dst (part of them is %f)\n",
1222 commonLog.str().c_str(), static_cast<float>(diffElemCount)/(channels*size.area()));
1223 return cvtest::TS::FAIL_INVALID_OUTPUT;
1226 return cvtest::TS::OK;
1230 TEST(Core_PCA, accuracy) { Core_PCATest test; test.safe_run(); }
1231 TEST(Core_Reduce, accuracy) { Core_ReduceTest test; test.safe_run(); }
1232 TEST(Core_Array, basic_operations) { Core_ArrayOpTest test; test.safe_run(); }
1234 TEST(Core_Merge, shape_operations) { Core_MergeTest test; test.safe_run(); }
1235 TEST(Core_Split, shape_operations) { Core_SplitTest test; test.safe_run(); }
1238 TEST(Core_IOArray, submat_assignment)
1240 Mat1f A = Mat1f::zeros(2,2);
1241 Mat1f B = Mat1f::ones(1,3);
1243 EXPECT_THROW( B.colRange(0,3).copyTo(A.row(0)), cv::Exception );
1245 EXPECT_NO_THROW( B.colRange(0,2).copyTo(A.row(0)) );
1247 EXPECT_EQ( 1.0f, A(0,0) );
1248 EXPECT_EQ( 1.0f, A(0,1) );
1251 void OutputArray_create1(OutputArray m) { m.create(1, 2, CV_32S); }
1252 void OutputArray_create2(OutputArray m) { m.create(1, 3, CV_32F); }
1254 TEST(Core_IOArray, submat_create)
1256 Mat1f A = Mat1f::zeros(2,2);
1258 EXPECT_THROW( OutputArray_create1(A.row(0)), cv::Exception );
1259 EXPECT_THROW( OutputArray_create2(A.row(0)), cv::Exception );
1262 TEST(Core_Mat, issue4457_pass_null_ptr)
1264 ASSERT_ANY_THROW(cv::Mat mask(45, 45, CV_32F, 0));
1267 TEST(Core_Mat, reshape_1942)
1269 cv::Mat A = (cv::Mat_<float>(2,3) << 3.4884074, 1.4159607, 0.78737736, 2.3456569, -0.88010466, 0.3009364);
1272 cv::Mat_<float> M = A.reshape(3);
1278 static void check_ndim_shape(const cv::Mat &mat, int cn, int ndims, const int *sizes)
1280 EXPECT_EQ(mat.channels(), cn);
1281 EXPECT_EQ(mat.dims, ndims);
1283 if (mat.dims != ndims)
1286 for (int i = 0; i < ndims; i++)
1287 EXPECT_EQ(mat.size[i], sizes[i]);
1290 TEST(Core_Mat, reshape_ndims_2)
1292 const cv::Mat A(8, 16, CV_8UC3);
1296 int new_sizes_mask[] = { 0, 3, 4, 4 };
1297 int new_sizes_real[] = { 8, 3, 4, 4 };
1298 ASSERT_NO_THROW(B = A.reshape(1, 4, new_sizes_mask));
1299 check_ndim_shape(B, 1, 4, new_sizes_real);
1302 int new_sizes[] = { 16, 8 };
1303 ASSERT_NO_THROW(B = A.reshape(0, 2, new_sizes));
1304 check_ndim_shape(B, 3, 2, new_sizes);
1305 EXPECT_EQ(B.rows, new_sizes[0]);
1306 EXPECT_EQ(B.cols, new_sizes[1]);
1309 int new_sizes[] = { 2, 5, 1, 3 };
1310 cv::Mat A_sliced = A(cv::Range::all(), cv::Range(0, 15));
1311 ASSERT_ANY_THROW(A_sliced.reshape(4, 4, new_sizes));
1315 TEST(Core_Mat, reshape_ndims_4)
1317 const int sizes[] = { 2, 6, 4, 12 };
1318 const cv::Mat A(4, sizes, CV_8UC3);
1322 int new_sizes_mask[] = { 0, 864 };
1323 int new_sizes_real[] = { 2, 864 };
1324 ASSERT_NO_THROW(B = A.reshape(1, 2, new_sizes_mask));
1325 check_ndim_shape(B, 1, 2, new_sizes_real);
1326 EXPECT_EQ(B.rows, new_sizes_real[0]);
1327 EXPECT_EQ(B.cols, new_sizes_real[1]);
1330 int new_sizes_mask[] = { 4, 0, 0, 2, 3 };
1331 int new_sizes_real[] = { 4, 6, 4, 2, 3 };
1332 ASSERT_NO_THROW(B = A.reshape(0, 5, new_sizes_mask));
1333 check_ndim_shape(B, 3, 5, new_sizes_real);
1336 int new_sizes_mask[] = { 1, 1 };
1337 ASSERT_ANY_THROW(A.reshape(0, 2, new_sizes_mask));
1340 int new_sizes_mask[] = { 4, 6, 3, 3, 0 };
1341 ASSERT_ANY_THROW(A.reshape(0, 5, new_sizes_mask));
1345 TEST(Core_Mat, push_back)
1347 Mat a = (Mat_<float>(1,2) << 3.4884074f, 1.4159607f);
1348 Mat b = (Mat_<float>(1,2) << 0.78737736f, 2.3456569f);
1352 ASSERT_EQ(2, a.cols);
1353 ASSERT_EQ(2, a.rows);
1355 ASSERT_FLOAT_EQ(3.4884074f, a.at<float>(0, 0));
1356 ASSERT_FLOAT_EQ(1.4159607f, a.at<float>(0, 1));
1357 ASSERT_FLOAT_EQ(0.78737736f, a.at<float>(1, 0));
1358 ASSERT_FLOAT_EQ(2.3456569f, a.at<float>(1, 1));
1360 Mat c = (Mat_<float>(2,2) << -0.88010466f, 0.3009364f, 2.22399974f, -5.45933905f);
1362 ASSERT_EQ(c.rows, a.cols);
1366 ASSERT_EQ(2, a.cols);
1367 ASSERT_EQ(4, a.rows);
1369 ASSERT_FLOAT_EQ(3.4884074f, a.at<float>(0, 0));
1370 ASSERT_FLOAT_EQ(1.4159607f, a.at<float>(0, 1));
1371 ASSERT_FLOAT_EQ(0.78737736f, a.at<float>(1, 0));
1372 ASSERT_FLOAT_EQ(2.3456569f, a.at<float>(1, 1));
1373 ASSERT_FLOAT_EQ(-0.88010466f, a.at<float>(2, 0));
1374 ASSERT_FLOAT_EQ(2.22399974f, a.at<float>(2, 1));
1375 ASSERT_FLOAT_EQ(0.3009364f, a.at<float>(3, 0));
1376 ASSERT_FLOAT_EQ(-5.45933905f, a.at<float>(3, 1));
1378 a.push_back(Mat::ones(2, 2, CV_32FC1));
1380 ASSERT_EQ(6, a.rows);
1382 for(int row=4; row<a.rows; row++) {
1384 for(int col=0; col<a.cols; col++) {
1386 ASSERT_FLOAT_EQ(1.f, a.at<float>(row, col));
1391 TEST(Core_Mat, copyNx1ToVector)
1393 cv::Mat_<uchar> src(5, 1);
1394 cv::Mat_<uchar> ref_dst8;
1395 cv::Mat_<ushort> ref_dst16;
1396 std::vector<uchar> dst8;
1397 std::vector<ushort> dst16;
1399 src << 1, 2, 3, 4, 5;
1401 src.copyTo(ref_dst8);
1404 ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), ref_dst8, cv::Mat_<uchar>(dst8));
1406 src.convertTo(ref_dst16, CV_16U);
1407 src.convertTo(dst16, CV_16U);
1409 ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), ref_dst16, cv::Mat_<ushort>(dst16));
1412 TEST(Core_Matx, fromMat_)
1414 Mat_<double> a = (Mat_<double>(2,2) << 10, 11, 12, 13);
1416 ASSERT_EQ( cvtest::norm(a, b, NORM_INF), 0.);
1421 TEST(Core_Matx, from_initializer_list)
1423 Mat_<double> a = (Mat_<double>(2,2) << 10, 11, 12, 13);
1424 Matx22d b = {10, 11, 12, 13};
1425 ASSERT_EQ( cvtest::norm(a, b, NORM_INF), 0.);
1428 TEST(Core_Mat, regression_9507)
1430 cv::Mat m = Mat::zeros(5, 5, CV_8UC3);
1432 EXPECT_EQ(25u, m2.total());
1437 TEST(Core_InputArray, empty)
1439 vector<vector<Point> > data;
1440 ASSERT_TRUE( _InputArray(data).empty() );
1443 TEST(Core_CopyMask, bug1918)
1445 Mat_<unsigned char> tmpSrc(100,100);
1447 Mat_<unsigned char> tmpMask(100,100);
1449 Mat_<unsigned char> tmpDst(100,100);
1451 tmpSrc.copyTo(tmpDst,tmpMask);
1452 ASSERT_EQ(sum(tmpDst)[0], 124*100*100);
1455 TEST(Core_SVD, orthogonality)
1457 for( int i = 0; i < 2; i++ )
1459 int type = i == 0 ? CV_32F : CV_64F;
1460 Mat mat_D(2, 2, type);
1463 SVD::compute(mat_D, mat_W, mat_U, noArray(), SVD::FULL_UV);
1465 ASSERT_LT(norm(mat_U, Mat::eye(2, 2, type), NORM_INF), 1e-5);
1470 TEST(Core_SparseMat, footprint)
1473 int sz[] = { n, n };
1474 SparseMat m(2, sz, CV_64F);
1476 int nodeSize0 = (int)m.hdr->nodeSize;
1477 double dataSize0 = ((double)m.hdr->pool.size() + (double)m.hdr->hashtab.size()*sizeof(size_t))*1e-6;
1478 printf("before: node size=%d bytes, data size=%.0f Mbytes\n", nodeSize0, dataSize0);
1480 for (int i = 0; i < n; i++)
1482 m.ref<double>(i, i) = 1;
1485 double dataSize1 = ((double)m.hdr->pool.size() + (double)m.hdr->hashtab.size()*sizeof(size_t))*1e-6;
1486 double threshold = (n*nodeSize0*1.6 + n*2.*sizeof(size_t))*1e-6;
1487 printf("after: data size=%.0f Mbytes, threshold=%.0f MBytes\n", dataSize1, threshold);
1489 ASSERT_LE((int)m.hdr->nodeSize, 32);
1490 ASSERT_LE(dataSize1, threshold);
1494 // Can't fix without dirty hacks or broken user code (PR #4159)
1495 TEST(Core_Mat_vector, DISABLED_OutputArray_create_getMat)
1497 cv::Mat_<uchar> src_base(5, 1);
1498 std::vector<uchar> dst8;
1500 src_base << 1, 2, 3, 4, 5;
1503 OutputArray _dst(dst8);
1505 _dst.create(src.rows, src.cols, src.type());
1506 Mat dst = _dst.getMat();
1507 EXPECT_EQ(src.dims, dst.dims);
1508 EXPECT_EQ(src.cols, dst.cols);
1509 EXPECT_EQ(src.rows, dst.rows);
1513 TEST(Core_Mat_vector, copyTo_roi_column)
1515 cv::Mat_<uchar> src_base(5, 2);
1516 std::vector<uchar> dst1;
1518 src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
1520 Mat src_full(src_base);
1521 Mat src(src_full.col(0));
1522 #if 0 // Can't fix without dirty hacks or broken user code (PR #4159)
1523 OutputArray _dst(dst1);
1525 _dst.create(src.rows, src.cols, src.type());
1526 Mat dst = _dst.getMat();
1527 EXPECT_EQ(src.dims, dst.dims);
1528 EXPECT_EQ(src.cols, dst.cols);
1529 EXPECT_EQ(src.rows, dst.rows);
1533 std::vector<uchar> dst2;
1535 std::cout << "src = " << src << std::endl;
1536 std::cout << "dst = " << Mat(dst2) << std::endl;
1537 EXPECT_EQ((size_t)5, dst2.size());
1538 EXPECT_EQ(1, (int)dst2[0]);
1539 EXPECT_EQ(3, (int)dst2[1]);
1540 EXPECT_EQ(5, (int)dst2[2]);
1541 EXPECT_EQ(7, (int)dst2[3]);
1542 EXPECT_EQ(9, (int)dst2[4]);
1545 TEST(Core_Mat_vector, copyTo_roi_row)
1547 cv::Mat_<uchar> src_base(2, 5);
1548 std::vector<uchar> dst1;
1550 src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
1552 Mat src_full(src_base);
1553 Mat src(src_full.row(0));
1554 OutputArray _dst(dst1);
1556 _dst.create(src.rows, src.cols, src.type());
1557 Mat dst = _dst.getMat();
1558 EXPECT_EQ(src.dims, dst.dims);
1559 EXPECT_EQ(src.cols, dst.cols);
1560 EXPECT_EQ(src.rows, dst.rows);
1563 std::vector<uchar> dst2;
1565 std::cout << "src = " << src << std::endl;
1566 std::cout << "dst = " << Mat(dst2) << std::endl;
1567 EXPECT_EQ((size_t)5, dst2.size());
1568 EXPECT_EQ(1, (int)dst2[0]);
1569 EXPECT_EQ(2, (int)dst2[1]);
1570 EXPECT_EQ(3, (int)dst2[2]);
1571 EXPECT_EQ(4, (int)dst2[3]);
1572 EXPECT_EQ(5, (int)dst2[4]);
1575 TEST(Mat, regression_5991)
1578 Mat mat(3, sz, CV_32F, Scalar(1));
1579 ASSERT_NO_THROW(mat.convertTo(mat, CV_8U));
1580 EXPECT_EQ(sz[0], mat.size[0]);
1581 EXPECT_EQ(sz[1], mat.size[1]);
1582 EXPECT_EQ(sz[2], mat.size[2]);
1583 EXPECT_EQ(0, cvtest::norm(mat, Mat(3, sz, CV_8U, Scalar(1)), NORM_INF));
1586 #ifdef OPENCV_TEST_BIGDATA
1587 TEST(Mat, regression_6696_BigData_8Gb)
1592 Mat destImageBGR = Mat(height, width, CV_8UC3, Scalar(1, 2, 3, 0));
1593 Mat destImageA = Mat(height, width, CV_8UC1, Scalar::all(4));
1596 split(destImageBGR, planes);
1597 planes.push_back(destImageA);
1598 merge(planes, destImageBGR);
1600 EXPECT_EQ(1, destImageBGR.at<Vec4b>(0)[0]);
1601 EXPECT_EQ(2, destImageBGR.at<Vec4b>(0)[1]);
1602 EXPECT_EQ(3, destImageBGR.at<Vec4b>(0)[2]);
1603 EXPECT_EQ(4, destImageBGR.at<Vec4b>(0)[3]);
1605 EXPECT_EQ(1, destImageBGR.at<Vec4b>(height-1, width-1)[0]);
1606 EXPECT_EQ(2, destImageBGR.at<Vec4b>(height-1, width-1)[1]);
1607 EXPECT_EQ(3, destImageBGR.at<Vec4b>(height-1, width-1)[2]);
1608 EXPECT_EQ(4, destImageBGR.at<Vec4b>(height-1, width-1)[3]);
1612 TEST(Reduce, regression_should_fail_bug_4594)
1614 cv::Mat src = cv::Mat::eye(4, 4, CV_8U);
1615 std::vector<int> dst;
1617 EXPECT_THROW(cv::reduce(src, dst, 0, CV_REDUCE_MIN, CV_32S), cv::Exception);
1618 EXPECT_THROW(cv::reduce(src, dst, 0, CV_REDUCE_MAX, CV_32S), cv::Exception);
1619 EXPECT_NO_THROW(cv::reduce(src, dst, 0, CV_REDUCE_SUM, CV_32S));
1620 EXPECT_NO_THROW(cv::reduce(src, dst, 0, CV_REDUCE_AVG, CV_32S));
1623 TEST(Mat, push_back_vector)
1625 cv::Mat result(1, 5, CV_32FC1);
1627 std::vector<float> vec1(result.cols + 1);
1628 std::vector<int> vec2(result.cols);
1630 EXPECT_THROW(result.push_back(vec1), cv::Exception);
1631 EXPECT_THROW(result.push_back(vec2), cv::Exception);
1633 vec1.resize(result.cols);
1635 for (int i = 0; i < 5; ++i)
1636 result.push_back(cv::Mat(vec1).reshape(1, 1));
1638 ASSERT_EQ(6, result.rows);
1641 TEST(Mat, regression_5917_clone_empty)
1644 Mat_<Point2f> source(5, 0);
1646 ASSERT_NO_THROW(cloned = source.clone());
1649 TEST(Mat, regression_7873_mat_vector_initialize)
1651 std::vector<int> dims;
1655 Mat multi_mat(dims, CV_32FC1, cv::Scalar(0));
1657 ASSERT_EQ(3, multi_mat.dims);
1658 ASSERT_EQ(12, multi_mat.size[0]);
1659 ASSERT_EQ(3, multi_mat.size[1]);
1660 ASSERT_EQ(2, multi_mat.size[2]);
1662 std::vector<Range> ranges;
1663 ranges.push_back(Range(1, 2));
1664 ranges.push_back(Range::all());
1665 ranges.push_back(Range::all());
1666 Mat sub_mat = multi_mat(ranges);
1668 ASSERT_EQ(3, sub_mat.dims);
1669 ASSERT_EQ(1, sub_mat.size[0]);
1670 ASSERT_EQ(3, sub_mat.size[1]);
1671 ASSERT_EQ(2, sub_mat.size[2]);
1674 #ifdef CV_CXX_STD_ARRAY
1675 TEST(Core_Mat_array, outputArray_create_getMat)
1677 cv::Mat_<uchar> src_base(5, 1);
1678 std::array<uchar, 5> dst8;
1680 src_base << 1, 2, 3, 4, 5;
1683 OutputArray _dst(dst8);
1686 _dst.create(src.rows, src.cols, src.type());
1687 Mat dst = _dst.getMat();
1688 EXPECT_EQ(src.dims, dst.dims);
1689 EXPECT_EQ(src.cols, dst.cols);
1690 EXPECT_EQ(src.rows, dst.rows);
1694 TEST(Core_Mat_array, copyTo_roi_column)
1696 cv::Mat_<uchar> src_base(5, 2);
1698 src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
1700 Mat src_full(src_base);
1701 Mat src(src_full.col(0));
1703 std::array<uchar, 5> dst1;
1705 std::cout << "src = " << src << std::endl;
1706 std::cout << "dst = " << Mat(dst1) << std::endl;
1707 EXPECT_EQ((size_t)5, dst1.size());
1708 EXPECT_EQ(1, (int)dst1[0]);
1709 EXPECT_EQ(3, (int)dst1[1]);
1710 EXPECT_EQ(5, (int)dst1[2]);
1711 EXPECT_EQ(7, (int)dst1[3]);
1712 EXPECT_EQ(9, (int)dst1[4]);
1715 TEST(Core_Mat_array, copyTo_roi_row)
1717 cv::Mat_<uchar> src_base(2, 5);
1718 std::array<uchar, 5> dst1;
1720 src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
1722 Mat src_full(src_base);
1723 Mat src(src_full.row(0));
1724 OutputArray _dst(dst1);
1726 _dst.create(5, 1, src.type());
1727 Mat dst = _dst.getMat();
1728 EXPECT_EQ(src.dims, dst.dims);
1729 EXPECT_EQ(1, dst.cols);
1730 EXPECT_EQ(5, dst.rows);
1733 std::array<uchar, 5> dst2;
1735 std::cout << "src = " << src << std::endl;
1736 std::cout << "dst = " << Mat(dst2) << std::endl;
1737 EXPECT_EQ(1, (int)dst2[0]);
1738 EXPECT_EQ(2, (int)dst2[1]);
1739 EXPECT_EQ(3, (int)dst2[2]);
1740 EXPECT_EQ(4, (int)dst2[3]);
1741 EXPECT_EQ(5, (int)dst2[4]);
1744 TEST(Core_Mat_array, SplitMerge)
1746 std::array<cv::Mat, 3> src;
1747 for(size_t i=0; i<src.size(); ++i) {
1748 src[i].create(10, 10, CV_8U);
1755 std::array<cv::Mat, 3> dst;
1759 for(size_t i=0; i<dst.size(); ++i) {
1760 absdiff(src[i], dst[i], diff);
1761 EXPECT_EQ(0, countNonZero(diff));
1766 TEST(Mat, regression_8680)
1768 Mat_<Point2i> mat(3,1);
1769 ASSERT_EQ(mat.channels(), 2);
1771 ASSERT_EQ(mat.channels(), 2);
1776 TEST(Mat_, range_based_for)
1778 Mat_<uchar> img = Mat_<uchar>::zeros(3, 3);
1780 for(auto& pixel : img)
1785 Mat_<uchar> ref(3, 3);
1786 ref.setTo(Scalar(1));
1787 ASSERT_DOUBLE_EQ(norm(img, ref), 0.);
1790 TEST(Mat, from_initializer_list)
1792 Mat A({1.f, 2.f, 3.f});
1793 Mat_<float> B(3, 1); B << 1, 2, 3;
1795 ASSERT_EQ(A.type(), CV_32F);
1796 ASSERT_DOUBLE_EQ(norm(A, B, NORM_INF), 0.);
1799 TEST(Mat_, from_initializer_list)
1801 Mat_<float> A = {1, 2, 3};
1802 Mat_<float> B(3, 1); B << 1, 2, 3;
1804 ASSERT_DOUBLE_EQ(norm(A, B, NORM_INF), 0.);