test_mat.cpp 76 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452
  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"
  5. #ifdef HAVE_EIGEN
  6. #include <Eigen/Core>
  7. #include <Eigen/Dense>
  8. #include "opencv2/core/eigen.hpp"
  9. #endif
  10. #include "opencv2/core/cuda.hpp"
  11. namespace opencv_test { namespace {
  12. class Core_ReduceTest : public cvtest::BaseTest
  13. {
  14. public:
  15. Core_ReduceTest() {}
  16. protected:
  17. void run( int);
  18. int checkOp( const Mat& src, int dstType, int opType, const Mat& opRes, int dim );
  19. int checkCase( int srcType, int dstType, int dim, Size sz );
  20. int checkDim( int dim, Size sz );
  21. int checkSize( Size sz );
  22. };
  23. template<class Type>
  24. void testReduce( const Mat& src, Mat& sum, Mat& avg, Mat& max, Mat& min, int dim )
  25. {
  26. CV_Assert( src.channels() == 1 );
  27. if( dim == 0 ) // row
  28. {
  29. sum.create( 1, src.cols, CV_64FC1 );
  30. max.create( 1, src.cols, CV_64FC1 );
  31. min.create( 1, src.cols, CV_64FC1 );
  32. }
  33. else
  34. {
  35. sum.create( src.rows, 1, CV_64FC1 );
  36. max.create( src.rows, 1, CV_64FC1 );
  37. min.create( src.rows, 1, CV_64FC1 );
  38. }
  39. sum.setTo(Scalar(0));
  40. max.setTo(Scalar(-DBL_MAX));
  41. min.setTo(Scalar(DBL_MAX));
  42. const Mat_<Type>& src_ = src;
  43. Mat_<double>& sum_ = (Mat_<double>&)sum;
  44. Mat_<double>& min_ = (Mat_<double>&)min;
  45. Mat_<double>& max_ = (Mat_<double>&)max;
  46. if( dim == 0 )
  47. {
  48. for( int ri = 0; ri < src.rows; ri++ )
  49. {
  50. for( int ci = 0; ci < src.cols; ci++ )
  51. {
  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) );
  55. }
  56. }
  57. }
  58. else
  59. {
  60. for( int ci = 0; ci < src.cols; ci++ )
  61. {
  62. for( int ri = 0; ri < src.rows; ri++ )
  63. {
  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) );
  67. }
  68. }
  69. }
  70. sum.convertTo( avg, CV_64FC1 );
  71. avg = avg * (1.0 / (dim==0 ? (double)src.rows : (double)src.cols));
  72. }
  73. void getMatTypeStr( int type, string& str)
  74. {
  75. str = type == CV_8UC1 ? "CV_8UC1" :
  76. type == CV_8SC1 ? "CV_8SC1" :
  77. type == CV_16UC1 ? "CV_16UC1" :
  78. type == CV_16SC1 ? "CV_16SC1" :
  79. type == CV_32SC1 ? "CV_32SC1" :
  80. type == CV_32FC1 ? "CV_32FC1" :
  81. type == CV_64FC1 ? "CV_64FC1" : "unsupported matrix type";
  82. }
  83. int Core_ReduceTest::checkOp( const Mat& src, int dstType, int opType, const Mat& opRes, int dim )
  84. {
  85. int srcType = src.type();
  86. bool support = false;
  87. if( opType == REDUCE_SUM || opType == REDUCE_AVG )
  88. {
  89. if( srcType == CV_8U && (dstType == CV_32S || dstType == CV_32F || dstType == CV_64F) )
  90. support = true;
  91. if( srcType == CV_16U && (dstType == CV_32F || dstType == CV_64F) )
  92. support = true;
  93. if( srcType == CV_16S && (dstType == CV_32F || dstType == CV_64F) )
  94. support = true;
  95. if( srcType == CV_32F && (dstType == CV_32F || dstType == CV_64F) )
  96. support = true;
  97. if( srcType == CV_64F && dstType == CV_64F)
  98. support = true;
  99. }
  100. else if( opType == REDUCE_MAX )
  101. {
  102. if( srcType == CV_8U && dstType == CV_8U )
  103. support = true;
  104. if( srcType == CV_32F && dstType == CV_32F )
  105. support = true;
  106. if( srcType == CV_64F && dstType == CV_64F )
  107. support = true;
  108. }
  109. else if( opType == REDUCE_MIN )
  110. {
  111. if( srcType == CV_8U && dstType == CV_8U)
  112. support = true;
  113. if( srcType == CV_32F && dstType == CV_32F)
  114. support = true;
  115. if( srcType == CV_64F && dstType == CV_64F)
  116. support = true;
  117. }
  118. if( !support )
  119. return cvtest::TS::OK;
  120. double eps = 0.0;
  121. if ( opType == REDUCE_SUM || opType == REDUCE_AVG )
  122. {
  123. if ( dstType == CV_32F )
  124. eps = 1.e-5;
  125. else if( dstType == CV_64F )
  126. eps = 1.e-8;
  127. else if ( dstType == CV_32S )
  128. eps = 0.6;
  129. }
  130. CV_Assert( opRes.type() == CV_64FC1 );
  131. Mat _dst, dst, diff;
  132. cv::reduce( src, _dst, dim, opType, dstType );
  133. _dst.convertTo( dst, CV_64FC1 );
  134. absdiff( opRes,dst,diff );
  135. bool check = false;
  136. if (dstType == CV_32F || dstType == CV_64F)
  137. check = countNonZero(diff>eps*dst) > 0;
  138. else
  139. check = countNonZero(diff>eps) > 0;
  140. if( check )
  141. {
  142. char msg[100];
  143. const char* opTypeStr = opType == REDUCE_SUM ? "REDUCE_SUM" :
  144. opType == REDUCE_AVG ? "REDUCE_AVG" :
  145. opType == REDUCE_MAX ? "REDUCE_MAX" :
  146. opType == REDUCE_MIN ? "REDUCE_MIN" : "unknown operation type";
  147. string srcTypeStr, dstTypeStr;
  148. getMatTypeStr( src.type(), srcTypeStr );
  149. getMatTypeStr( dstType, dstTypeStr );
  150. const char* dimStr = dim == 0 ? "ROWS" : "COLS";
  151. sprintf( msg, "bad accuracy with srcType = %s, dstType = %s, opType = %s, dim = %s",
  152. srcTypeStr.c_str(), dstTypeStr.c_str(), opTypeStr, dimStr );
  153. ts->printf( cvtest::TS::LOG, msg );
  154. return cvtest::TS::FAIL_BAD_ACCURACY;
  155. }
  156. return cvtest::TS::OK;
  157. }
  158. int Core_ReduceTest::checkCase( int srcType, int dstType, int dim, Size sz )
  159. {
  160. int code = cvtest::TS::OK, tempCode;
  161. Mat src, sum, avg, max, min;
  162. src.create( sz, srcType );
  163. randu( src, Scalar(0), Scalar(100) );
  164. if( srcType == CV_8UC1 )
  165. testReduce<uchar>( src, sum, avg, max, min, dim );
  166. else if( srcType == CV_8SC1 )
  167. testReduce<char>( src, sum, avg, max, min, dim );
  168. else if( srcType == CV_16UC1 )
  169. testReduce<unsigned short int>( src, sum, avg, max, min, dim );
  170. else if( srcType == CV_16SC1 )
  171. testReduce<short int>( src, sum, avg, max, min, dim );
  172. else if( srcType == CV_32SC1 )
  173. testReduce<int>( src, sum, avg, max, min, dim );
  174. else if( srcType == CV_32FC1 )
  175. testReduce<float>( src, sum, avg, max, min, dim );
  176. else if( srcType == CV_64FC1 )
  177. testReduce<double>( src, sum, avg, max, min, dim );
  178. else
  179. CV_Assert( 0 );
  180. // 1. sum
  181. tempCode = checkOp( src, dstType, REDUCE_SUM, sum, dim );
  182. code = tempCode != cvtest::TS::OK ? tempCode : code;
  183. // 2. avg
  184. tempCode = checkOp( src, dstType, REDUCE_AVG, avg, dim );
  185. code = tempCode != cvtest::TS::OK ? tempCode : code;
  186. // 3. max
  187. tempCode = checkOp( src, dstType, REDUCE_MAX, max, dim );
  188. code = tempCode != cvtest::TS::OK ? tempCode : code;
  189. // 4. min
  190. tempCode = checkOp( src, dstType, REDUCE_MIN, min, dim );
  191. code = tempCode != cvtest::TS::OK ? tempCode : code;
  192. return code;
  193. }
  194. int Core_ReduceTest::checkDim( int dim, Size sz )
  195. {
  196. int code = cvtest::TS::OK, tempCode;
  197. // CV_8UC1
  198. tempCode = checkCase( CV_8UC1, CV_8UC1, dim, sz );
  199. code = tempCode != cvtest::TS::OK ? tempCode : code;
  200. tempCode = checkCase( CV_8UC1, CV_32SC1, dim, sz );
  201. code = tempCode != cvtest::TS::OK ? tempCode : code;
  202. tempCode = checkCase( CV_8UC1, CV_32FC1, dim, sz );
  203. code = tempCode != cvtest::TS::OK ? tempCode : code;
  204. tempCode = checkCase( CV_8UC1, CV_64FC1, dim, sz );
  205. code = tempCode != cvtest::TS::OK ? tempCode : code;
  206. // CV_16UC1
  207. tempCode = checkCase( CV_16UC1, CV_32FC1, dim, sz );
  208. code = tempCode != cvtest::TS::OK ? tempCode : code;
  209. tempCode = checkCase( CV_16UC1, CV_64FC1, dim, sz );
  210. code = tempCode != cvtest::TS::OK ? tempCode : code;
  211. // CV_16SC1
  212. tempCode = checkCase( CV_16SC1, CV_32FC1, dim, sz );
  213. code = tempCode != cvtest::TS::OK ? tempCode : code;
  214. tempCode = checkCase( CV_16SC1, CV_64FC1, dim, sz );
  215. code = tempCode != cvtest::TS::OK ? tempCode : code;
  216. // CV_32FC1
  217. tempCode = checkCase( CV_32FC1, CV_32FC1, dim, sz );
  218. code = tempCode != cvtest::TS::OK ? tempCode : code;
  219. tempCode = checkCase( CV_32FC1, CV_64FC1, dim, sz );
  220. code = tempCode != cvtest::TS::OK ? tempCode : code;
  221. // CV_64FC1
  222. tempCode = checkCase( CV_64FC1, CV_64FC1, dim, sz );
  223. code = tempCode != cvtest::TS::OK ? tempCode : code;
  224. return code;
  225. }
  226. int Core_ReduceTest::checkSize( Size sz )
  227. {
  228. int code = cvtest::TS::OK, tempCode;
  229. tempCode = checkDim( 0, sz ); // rows
  230. code = tempCode != cvtest::TS::OK ? tempCode : code;
  231. tempCode = checkDim( 1, sz ); // cols
  232. code = tempCode != cvtest::TS::OK ? tempCode : code;
  233. return code;
  234. }
  235. void Core_ReduceTest::run( int )
  236. {
  237. int code = cvtest::TS::OK, tempCode;
  238. tempCode = checkSize( Size(1,1) );
  239. code = tempCode != cvtest::TS::OK ? tempCode : code;
  240. tempCode = checkSize( Size(1,100) );
  241. code = tempCode != cvtest::TS::OK ? tempCode : code;
  242. tempCode = checkSize( Size(100,1) );
  243. code = tempCode != cvtest::TS::OK ? tempCode : code;
  244. tempCode = checkSize( Size(1000,500) );
  245. code = tempCode != cvtest::TS::OK ? tempCode : code;
  246. ts->set_failed_test_info( code );
  247. }
  248. #define CHECK_C
  249. TEST(Core_PCA, accuracy)
  250. {
  251. const Size sz(200, 500);
  252. double diffPrjEps, diffBackPrjEps,
  253. prjEps, backPrjEps,
  254. evalEps, evecEps;
  255. int maxComponents = 100;
  256. double retainedVariance = 0.95;
  257. Mat rPoints(sz, CV_32FC1), rTestPoints(sz, CV_32FC1);
  258. RNG rng(12345);
  259. rng.fill( rPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) );
  260. rng.fill( rTestPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) );
  261. PCA rPCA( rPoints, Mat(), CV_PCA_DATA_AS_ROW, maxComponents ), cPCA;
  262. // 1. check C++ PCA & ROW
  263. Mat rPrjTestPoints = rPCA.project( rTestPoints );
  264. Mat rBackPrjTestPoints = rPCA.backProject( rPrjTestPoints );
  265. Mat avg(1, sz.width, CV_32FC1 );
  266. cv::reduce( rPoints, avg, 0, REDUCE_AVG );
  267. Mat Q = rPoints - repeat( avg, rPoints.rows, 1 ), Qt = Q.t(), eval, evec;
  268. Q = Qt * Q;
  269. Q = Q /(float)rPoints.rows;
  270. eigen( Q, eval, evec );
  271. /*SVD svd(Q);
  272. evec = svd.vt;
  273. eval = svd.w;*/
  274. Mat subEval( maxComponents, 1, eval.type(), eval.ptr() ),
  275. subEvec( maxComponents, evec.cols, evec.type(), evec.ptr() );
  276. #ifdef CHECK_C
  277. Mat prjTestPoints, backPrjTestPoints, cPoints = rPoints.t(), cTestPoints = rTestPoints.t();
  278. CvMat _points, _testPoints, _avg, _eval, _evec, _prjTestPoints, _backPrjTestPoints;
  279. #endif
  280. // check eigen()
  281. double eigenEps = 1e-4;
  282. double err;
  283. for(int i = 0; i < Q.rows; i++ )
  284. {
  285. Mat v = evec.row(i).t();
  286. Mat Qv = Q * v;
  287. Mat lv = eval.at<float>(i,0) * v;
  288. err = cvtest::norm(Qv, lv, NORM_L2 | NORM_RELATIVE);
  289. EXPECT_LE(err, eigenEps) << "bad accuracy of eigen(); i = " << i;
  290. }
  291. // check pca eigenvalues
  292. evalEps = 1e-5, evecEps = 5e-3;
  293. err = cvtest::norm(rPCA.eigenvalues, subEval, NORM_L2 | NORM_RELATIVE);
  294. EXPECT_LE(err , evalEps) << "pca.eigenvalues is incorrect (CV_PCA_DATA_AS_ROW)";
  295. // check pca eigenvectors
  296. for(int i = 0; i < subEvec.rows; i++)
  297. {
  298. Mat r0 = rPCA.eigenvectors.row(i);
  299. Mat r1 = subEvec.row(i);
  300. // eigenvectors have normalized length, but both directions v and -v are valid
  301. double err1 = cvtest::norm(r0, r1, NORM_L2 | NORM_RELATIVE);
  302. double err2 = cvtest::norm(r0, -r1, NORM_L2 | NORM_RELATIVE);
  303. err = std::min(err1, err2);
  304. if (err > evecEps)
  305. {
  306. Mat tmp;
  307. absdiff(rPCA.eigenvectors, subEvec, tmp);
  308. double mval = 0; Point mloc;
  309. minMaxLoc(tmp, 0, &mval, 0, &mloc);
  310. EXPECT_LE(err, evecEps) << "pca.eigenvectors is incorrect (CV_PCA_DATA_AS_ROW) at " << i << " "
  311. << cv::format("max diff is %g at (i=%d, j=%d) (%g vs %g)\n",
  312. mval, mloc.y, mloc.x, rPCA.eigenvectors.at<float>(mloc.y, mloc.x),
  313. subEvec.at<float>(mloc.y, mloc.x))
  314. << "r0=" << r0 << std::endl
  315. << "r1=" << r1 << std::endl
  316. << "err1=" << err1 << " err2=" << err2
  317. ;
  318. }
  319. }
  320. prjEps = 1.265, backPrjEps = 1.265;
  321. for( int i = 0; i < rTestPoints.rows; i++ )
  322. {
  323. // check pca project
  324. Mat subEvec_t = subEvec.t();
  325. Mat prj = rTestPoints.row(i) - avg; prj *= subEvec_t;
  326. err = cvtest::norm(rPrjTestPoints.row(i), prj, NORM_L2 | NORM_RELATIVE);
  327. if (err < prjEps)
  328. {
  329. EXPECT_LE(err, prjEps) << "bad accuracy of project() (CV_PCA_DATA_AS_ROW)";
  330. continue;
  331. }
  332. // check pca backProject
  333. Mat backPrj = rPrjTestPoints.row(i) * subEvec + avg;
  334. err = cvtest::norm(rBackPrjTestPoints.row(i), backPrj, NORM_L2 | NORM_RELATIVE);
  335. if (err > backPrjEps)
  336. {
  337. EXPECT_LE(err, backPrjEps) << "bad accuracy of backProject() (CV_PCA_DATA_AS_ROW)";
  338. continue;
  339. }
  340. }
  341. // 2. check C++ PCA & COL
  342. cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, maxComponents );
  343. diffPrjEps = 1, diffBackPrjEps = 1;
  344. Mat ocvPrjTestPoints = cPCA.project(rTestPoints.t());
  345. err = cvtest::norm(cv::abs(ocvPrjTestPoints), cv::abs(rPrjTestPoints.t()), NORM_L2 | NORM_RELATIVE);
  346. ASSERT_LE(err, diffPrjEps) << "bad accuracy of project() (CV_PCA_DATA_AS_COL)";
  347. err = cvtest::norm(cPCA.backProject(ocvPrjTestPoints), rBackPrjTestPoints.t(), NORM_L2 | NORM_RELATIVE);
  348. ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of backProject() (CV_PCA_DATA_AS_COL)";
  349. // 3. check C++ PCA w/retainedVariance
  350. cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, retainedVariance );
  351. diffPrjEps = 1, diffBackPrjEps = 1;
  352. Mat rvPrjTestPoints = cPCA.project(rTestPoints.t());
  353. if( cPCA.eigenvectors.rows > maxComponents)
  354. err = cvtest::norm(cv::abs(rvPrjTestPoints.rowRange(0,maxComponents)), cv::abs(rPrjTestPoints.t()), NORM_L2 | NORM_RELATIVE);
  355. else
  356. err = cvtest::norm(cv::abs(rvPrjTestPoints), cv::abs(rPrjTestPoints.colRange(0,cPCA.eigenvectors.rows).t()), NORM_L2 | NORM_RELATIVE);
  357. ASSERT_LE(err, diffPrjEps) << "bad accuracy of project() (CV_PCA_DATA_AS_COL); retainedVariance=" << retainedVariance;
  358. err = cvtest::norm(cPCA.backProject(rvPrjTestPoints), rBackPrjTestPoints.t(), NORM_L2 | NORM_RELATIVE);
  359. ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of backProject() (CV_PCA_DATA_AS_COL); retainedVariance=" << retainedVariance;
  360. #ifdef CHECK_C
  361. // 4. check C PCA & ROW
  362. _points = cvMat(rPoints);
  363. _testPoints = cvMat(rTestPoints);
  364. _avg = cvMat(avg);
  365. _eval = cvMat(eval);
  366. _evec = cvMat(evec);
  367. prjTestPoints.create(rTestPoints.rows, maxComponents, rTestPoints.type() );
  368. backPrjTestPoints.create(rPoints.size(), rPoints.type() );
  369. _prjTestPoints = cvMat(prjTestPoints);
  370. _backPrjTestPoints = cvMat(backPrjTestPoints);
  371. cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_ROW );
  372. cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );
  373. cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );
  374. err = cvtest::norm(prjTestPoints, rPrjTestPoints, NORM_L2 | NORM_RELATIVE);
  375. ASSERT_LE(err, diffPrjEps) << "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_ROW)";
  376. err = cvtest::norm(backPrjTestPoints, rBackPrjTestPoints, NORM_L2 | NORM_RELATIVE);
  377. ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_ROW)";
  378. // 5. check C PCA & COL
  379. _points = cvMat(cPoints);
  380. _testPoints = cvMat(cTestPoints);
  381. avg = avg.t(); _avg = cvMat(avg);
  382. eval = eval.t(); _eval = cvMat(eval);
  383. evec = evec.t(); _evec = cvMat(evec);
  384. prjTestPoints = prjTestPoints.t(); _prjTestPoints = cvMat(prjTestPoints);
  385. backPrjTestPoints = backPrjTestPoints.t(); _backPrjTestPoints = cvMat(backPrjTestPoints);
  386. cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_COL );
  387. cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );
  388. cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );
  389. err = cvtest::norm(cv::abs(prjTestPoints), cv::abs(rPrjTestPoints.t()), NORM_L2 | NORM_RELATIVE);
  390. ASSERT_LE(err, diffPrjEps) << "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_COL)";
  391. err = cvtest::norm(backPrjTestPoints, rBackPrjTestPoints.t(), NORM_L2 | NORM_RELATIVE);
  392. ASSERT_LE(err, diffBackPrjEps) << "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_COL)";
  393. #endif
  394. // Test read and write
  395. FileStorage fs( "PCA_store.yml", FileStorage::WRITE );
  396. rPCA.write( fs );
  397. fs.release();
  398. PCA lPCA;
  399. fs.open( "PCA_store.yml", FileStorage::READ );
  400. lPCA.read( fs.root() );
  401. err = cvtest::norm(rPCA.eigenvectors, lPCA.eigenvectors, NORM_L2 | NORM_RELATIVE);
  402. EXPECT_LE(err, 0) << "bad accuracy of write/load functions (YML)";
  403. err = cvtest::norm(rPCA.eigenvalues, lPCA.eigenvalues, NORM_L2 | NORM_RELATIVE);
  404. EXPECT_LE(err, 0) << "bad accuracy of write/load functions (YML)";
  405. err = cvtest::norm(rPCA.mean, lPCA.mean, NORM_L2 | NORM_RELATIVE);
  406. EXPECT_LE(err, 0) << "bad accuracy of write/load functions (YML)";
  407. }
  408. class Core_ArrayOpTest : public cvtest::BaseTest
  409. {
  410. public:
  411. Core_ArrayOpTest();
  412. ~Core_ArrayOpTest();
  413. protected:
  414. void run(int);
  415. };
  416. Core_ArrayOpTest::Core_ArrayOpTest()
  417. {
  418. }
  419. Core_ArrayOpTest::~Core_ArrayOpTest() {}
  420. static string idx2string(const int* idx, int dims)
  421. {
  422. char buf[256];
  423. char* ptr = buf;
  424. for( int k = 0; k < dims; k++ )
  425. {
  426. sprintf(ptr, "%4d ", idx[k]);
  427. ptr += strlen(ptr);
  428. }
  429. ptr[-1] = '\0';
  430. return string(buf);
  431. }
  432. static const int* string2idx(const string& s, int* idx, int dims)
  433. {
  434. const char* ptr = s.c_str();
  435. for( int k = 0; k < dims; k++ )
  436. {
  437. int n = 0;
  438. sscanf(ptr, "%d%n", idx + k, &n);
  439. ptr += n;
  440. }
  441. return idx;
  442. }
  443. static double getValue(SparseMat& M, const int* idx, RNG& rng)
  444. {
  445. int d = M.dims();
  446. size_t hv = 0, *phv = 0;
  447. if( (unsigned)rng % 2 )
  448. {
  449. hv = d == 2 ? M.hash(idx[0], idx[1]) :
  450. d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
  451. phv = &hv;
  452. }
  453. const uchar* ptr = d == 2 ? M.ptr(idx[0], idx[1], false, phv) :
  454. d == 3 ? M.ptr(idx[0], idx[1], idx[2], false, phv) :
  455. M.ptr(idx, false, phv);
  456. return !ptr ? 0 : M.type() == CV_32F ? *(float*)ptr : M.type() == CV_64F ? *(double*)ptr : 0;
  457. }
  458. static double getValue(const CvSparseMat* M, const int* idx)
  459. {
  460. int type = 0;
  461. const uchar* ptr = cvPtrND(M, idx, &type, 0);
  462. return !ptr ? 0 : type == CV_32F ? *(float*)ptr : type == CV_64F ? *(double*)ptr : 0;
  463. }
  464. static void eraseValue(SparseMat& M, const int* idx, RNG& rng)
  465. {
  466. int d = M.dims();
  467. size_t hv = 0, *phv = 0;
  468. if( (unsigned)rng % 2 )
  469. {
  470. hv = d == 2 ? M.hash(idx[0], idx[1]) :
  471. d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
  472. phv = &hv;
  473. }
  474. if( d == 2 )
  475. M.erase(idx[0], idx[1], phv);
  476. else if( d == 3 )
  477. M.erase(idx[0], idx[1], idx[2], phv);
  478. else
  479. M.erase(idx, phv);
  480. }
  481. static void eraseValue(CvSparseMat* M, const int* idx)
  482. {
  483. cvClearND(M, idx);
  484. }
  485. static void setValue(SparseMat& M, const int* idx, double value, RNG& rng)
  486. {
  487. int d = M.dims();
  488. size_t hv = 0, *phv = 0;
  489. if( (unsigned)rng % 2 )
  490. {
  491. hv = d == 2 ? M.hash(idx[0], idx[1]) :
  492. d == 3 ? M.hash(idx[0], idx[1], idx[2]) : M.hash(idx);
  493. phv = &hv;
  494. }
  495. uchar* ptr = d == 2 ? M.ptr(idx[0], idx[1], true, phv) :
  496. d == 3 ? M.ptr(idx[0], idx[1], idx[2], true, phv) :
  497. M.ptr(idx, true, phv);
  498. if( M.type() == CV_32F )
  499. *(float*)ptr = (float)value;
  500. else if( M.type() == CV_64F )
  501. *(double*)ptr = value;
  502. else
  503. CV_Error(CV_StsUnsupportedFormat, "");
  504. }
  505. template<typename Pixel>
  506. struct InitializerFunctor{
  507. /// Initializer for cv::Mat::forEach test
  508. void operator()(Pixel & pixel, const int * idx) const {
  509. pixel.x = idx[0];
  510. pixel.y = idx[1];
  511. pixel.z = idx[2];
  512. }
  513. };
  514. template<typename Pixel>
  515. struct InitializerFunctor5D{
  516. /// Initializer for cv::Mat::forEach test (5 dimensional case)
  517. void operator()(Pixel & pixel, const int * idx) const {
  518. pixel[0] = idx[0];
  519. pixel[1] = idx[1];
  520. pixel[2] = idx[2];
  521. pixel[3] = idx[3];
  522. pixel[4] = idx[4];
  523. }
  524. };
  525. template<typename Pixel>
  526. struct EmptyFunctor
  527. {
  528. void operator()(const Pixel &, const int *) const {}
  529. };
  530. void Core_ArrayOpTest::run( int /* start_from */)
  531. {
  532. int errcount = 0;
  533. // dense matrix operations
  534. {
  535. int sz3[] = {5, 10, 15};
  536. MatND A(3, sz3, CV_32F), B(3, sz3, CV_16SC4);
  537. CvMatND matA = cvMatND(A), matB = cvMatND(B);
  538. RNG rng;
  539. rng.fill(A, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10));
  540. rng.fill(B, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10));
  541. int idx0[] = {3,4,5}, idx1[] = {0, 9, 7};
  542. float val0 = 130;
  543. Scalar val1(-1000, 30, 3, 8);
  544. cvSetRealND(&matA, idx0, val0);
  545. cvSetReal3D(&matA, idx1[0], idx1[1], idx1[2], -val0);
  546. cvSetND(&matB, idx0, cvScalar(val1));
  547. cvSet3D(&matB, idx1[0], idx1[1], idx1[2], cvScalar(-val1));
  548. Ptr<CvMatND> matC(cvCloneMatND(&matB));
  549. if( A.at<float>(idx0[0], idx0[1], idx0[2]) != val0 ||
  550. A.at<float>(idx1[0], idx1[1], idx1[2]) != -val0 ||
  551. cvGetReal3D(&matA, idx0[0], idx0[1], idx0[2]) != val0 ||
  552. cvGetRealND(&matA, idx1) != -val0 ||
  553. Scalar(B.at<Vec4s>(idx0[0], idx0[1], idx0[2])) != val1 ||
  554. Scalar(B.at<Vec4s>(idx1[0], idx1[1], idx1[2])) != -val1 ||
  555. Scalar(cvGet3D(matC, idx0[0], idx0[1], idx0[2])) != val1 ||
  556. Scalar(cvGetND(matC, idx1)) != -val1 )
  557. {
  558. ts->printf(cvtest::TS::LOG, "one of cvSetReal3D, cvSetRealND, cvSet3D, cvSetND "
  559. "or the corresponding *Get* functions is not correct\n");
  560. errcount++;
  561. }
  562. }
  563. // test cv::Mat::forEach
  564. {
  565. const int dims[3] = { 101, 107, 7 };
  566. typedef cv::Point3i Pixel;
  567. cv::Mat a = cv::Mat::zeros(3, dims, CV_32SC3);
  568. InitializerFunctor<Pixel> initializer;
  569. a.forEach<Pixel>(initializer);
  570. uint64 total = 0;
  571. bool error_reported = false;
  572. for (int i0 = 0; i0 < dims[0]; ++i0) {
  573. for (int i1 = 0; i1 < dims[1]; ++i1) {
  574. for (int i2 = 0; i2 < dims[2]; ++i2) {
  575. Pixel& pixel = a.at<Pixel>(i0, i1, i2);
  576. if (pixel.x != i0 || pixel.y != i1 || pixel.z != i2) {
  577. if (!error_reported) {
  578. ts->printf(cvtest::TS::LOG, "forEach is not correct.\n"
  579. "First error detected at (%d, %d, %d).\n", pixel.x, pixel.y, pixel.z);
  580. error_reported = true;
  581. }
  582. errcount++;
  583. }
  584. total += pixel.x;
  585. total += pixel.y;
  586. total += pixel.z;
  587. }
  588. }
  589. }
  590. uint64 total2 = 0;
  591. for (size_t i = 0; i < sizeof(dims) / sizeof(dims[0]); ++i) {
  592. total2 += ((dims[i] - 1) * dims[i] / 2) * dims[0] * dims[1] * dims[2] / dims[i];
  593. }
  594. if (total != total2) {
  595. ts->printf(cvtest::TS::LOG, "forEach is not correct because total is invalid.\n");
  596. errcount++;
  597. }
  598. }
  599. // test cv::Mat::forEach
  600. // with a matrix that has more dimensions than columns
  601. // See https://github.com/opencv/opencv/issues/8447
  602. {
  603. const int dims[5] = { 2, 2, 2, 2, 2 };
  604. typedef cv::Vec<int, 5> Pixel;
  605. cv::Mat a = cv::Mat::zeros(5, dims, CV_32SC(5));
  606. InitializerFunctor5D<Pixel> initializer;
  607. a.forEach<Pixel>(initializer);
  608. uint64 total = 0;
  609. bool error_reported = false;
  610. for (int i0 = 0; i0 < dims[0]; ++i0) {
  611. for (int i1 = 0; i1 < dims[1]; ++i1) {
  612. for (int i2 = 0; i2 < dims[2]; ++i2) {
  613. for (int i3 = 0; i3 < dims[3]; ++i3) {
  614. for (int i4 = 0; i4 < dims[4]; ++i4) {
  615. const int i[5] = { i0, i1, i2, i3, i4 };
  616. Pixel& pixel = a.at<Pixel>(i);
  617. if (pixel[0] != i0 || pixel[1] != i1 || pixel[2] != i2 || pixel[3] != i3 || pixel[4] != i4) {
  618. if (!error_reported) {
  619. ts->printf(cvtest::TS::LOG, "forEach is not correct.\n"
  620. "First error detected at position (%d, %d, %d, %d, %d), got value (%d, %d, %d, %d, %d).\n",
  621. i0, i1, i2, i3, i4,
  622. pixel[0], pixel[1], pixel[2], pixel[3], pixel[4]);
  623. error_reported = true;
  624. }
  625. errcount++;
  626. }
  627. total += pixel[0];
  628. total += pixel[1];
  629. total += pixel[2];
  630. total += pixel[3];
  631. total += pixel[4];
  632. }
  633. }
  634. }
  635. }
  636. }
  637. uint64 total2 = 0;
  638. for (size_t i = 0; i < sizeof(dims) / sizeof(dims[0]); ++i) {
  639. total2 += ((dims[i] - 1) * dims[i] / 2) * dims[0] * dims[1] * dims[2] * dims[3] * dims[4] / dims[i];
  640. }
  641. if (total != total2) {
  642. ts->printf(cvtest::TS::LOG, "forEach is not correct because total is invalid.\n");
  643. errcount++;
  644. }
  645. }
  646. // test const cv::Mat::forEach
  647. {
  648. const Mat a(10, 10, CV_32SC3);
  649. Mat b(10, 10, CV_32SC3);
  650. const Mat & c = b;
  651. a.forEach<Point3i>(EmptyFunctor<Point3i>());
  652. b.forEach<Point3i>(EmptyFunctor<const Point3i>());
  653. c.forEach<Point3i>(EmptyFunctor<Point3i>());
  654. // tests compilation, no runtime check is needed
  655. }
  656. RNG rng;
  657. const int MAX_DIM = 5, MAX_DIM_SZ = 10;
  658. // sparse matrix operations
  659. for( int si = 0; si < 10; si++ )
  660. {
  661. int depth = (unsigned)rng % 2 == 0 ? CV_32F : CV_64F;
  662. int dims = ((unsigned)rng % MAX_DIM) + 1;
  663. int i, k, size[MAX_DIM]={0}, idx[MAX_DIM]={0};
  664. vector<string> all_idxs;
  665. vector<double> all_vals;
  666. vector<double> all_vals2;
  667. string sidx, min_sidx, max_sidx;
  668. double min_val=0, max_val=0;
  669. int p = 1;
  670. for( k = 0; k < dims; k++ )
  671. {
  672. size[k] = ((unsigned)rng % MAX_DIM_SZ) + 1;
  673. p *= size[k];
  674. }
  675. SparseMat M( dims, size, depth );
  676. map<string, double> M0;
  677. int nz0 = (unsigned)rng % std::max(p/5,10);
  678. nz0 = std::min(std::max(nz0, 1), p);
  679. all_vals.resize(nz0);
  680. all_vals2.resize(nz0);
  681. Mat_<double> _all_vals(all_vals), _all_vals2(all_vals2);
  682. rng.fill(_all_vals, CV_RAND_UNI, Scalar(-1000), Scalar(1000));
  683. if( depth == CV_32F )
  684. {
  685. Mat _all_vals_f;
  686. _all_vals.convertTo(_all_vals_f, CV_32F);
  687. _all_vals_f.convertTo(_all_vals, CV_64F);
  688. }
  689. _all_vals.convertTo(_all_vals2, _all_vals2.type(), 2);
  690. if( depth == CV_32F )
  691. {
  692. Mat _all_vals2_f;
  693. _all_vals2.convertTo(_all_vals2_f, CV_32F);
  694. _all_vals2_f.convertTo(_all_vals2, CV_64F);
  695. }
  696. minMaxLoc(_all_vals, &min_val, &max_val);
  697. double _norm0 = cv/*test*/::norm(_all_vals, CV_C);
  698. double _norm1 = cv/*test*/::norm(_all_vals, CV_L1);
  699. double _norm2 = cv/*test*/::norm(_all_vals, CV_L2);
  700. for( i = 0; i < nz0; i++ )
  701. {
  702. for(;;)
  703. {
  704. for( k = 0; k < dims; k++ )
  705. idx[k] = (unsigned)rng % size[k];
  706. sidx = idx2string(idx, dims);
  707. if( M0.count(sidx) == 0 )
  708. break;
  709. }
  710. all_idxs.push_back(sidx);
  711. M0[sidx] = all_vals[i];
  712. if( all_vals[i] == min_val )
  713. min_sidx = sidx;
  714. if( all_vals[i] == max_val )
  715. max_sidx = sidx;
  716. setValue(M, idx, all_vals[i], rng);
  717. double v = getValue(M, idx, rng);
  718. if( v != all_vals[i] )
  719. {
  720. ts->printf(cvtest::TS::LOG, "%d. immediately after SparseMat[%s]=%.20g the current value is %.20g\n",
  721. i, sidx.c_str(), all_vals[i], v);
  722. errcount++;
  723. break;
  724. }
  725. }
  726. Ptr<CvSparseMat> M2(cvCreateSparseMat(M));
  727. MatND Md;
  728. M.copyTo(Md);
  729. SparseMat M3; SparseMat(Md).convertTo(M3, Md.type(), 2);
  730. int nz1 = (int)M.nzcount(), nz2 = (int)M3.nzcount();
  731. double norm0 = cv/*test*/::norm(M, CV_C);
  732. double norm1 = cv/*test*/::norm(M, CV_L1);
  733. double norm2 = cv/*test*/::norm(M, CV_L2);
  734. double eps = depth == CV_32F ? FLT_EPSILON*100 : DBL_EPSILON*1000;
  735. if( nz1 != nz0 || nz2 != nz0)
  736. {
  737. errcount++;
  738. 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",
  739. si, nz1, nz2, nz0 );
  740. break;
  741. }
  742. if( fabs(norm0 - _norm0) > fabs(_norm0)*eps ||
  743. fabs(norm1 - _norm1) > fabs(_norm1)*eps ||
  744. fabs(norm2 - _norm2) > fabs(_norm2)*eps )
  745. {
  746. errcount++;
  747. ts->printf(cvtest::TS::LOG, "%d: The norms are different: %.20g/%.20g/%.20g vs %.20g/%.20g/%.20g\n",
  748. si, norm0, norm1, norm2, _norm0, _norm1, _norm2 );
  749. break;
  750. }
  751. int n = (unsigned)rng % std::max(p/5,10);
  752. n = std::min(std::max(n, 1), p) + nz0;
  753. for( i = 0; i < n; i++ )
  754. {
  755. double val1, val2, val3, val0;
  756. if(i < nz0)
  757. {
  758. sidx = all_idxs[i];
  759. string2idx(sidx, idx, dims);
  760. val0 = all_vals[i];
  761. }
  762. else
  763. {
  764. for( k = 0; k < dims; k++ )
  765. idx[k] = (unsigned)rng % size[k];
  766. sidx = idx2string(idx, dims);
  767. val0 = M0[sidx];
  768. }
  769. val1 = getValue(M, idx, rng);
  770. val2 = getValue(M2, idx);
  771. val3 = getValue(M3, idx, rng);
  772. if( val1 != val0 || val2 != val0 || fabs(val3 - val0*2) > fabs(val0*2)*FLT_EPSILON )
  773. {
  774. errcount++;
  775. ts->printf(cvtest::TS::LOG, "SparseMat M[%s] = %g/%g/%g (while it should be %g)\n", sidx.c_str(), val1, val2, val3, val0 );
  776. break;
  777. }
  778. }
  779. for( i = 0; i < n; i++ )
  780. {
  781. double val1, val2;
  782. if(i < nz0)
  783. {
  784. sidx = all_idxs[i];
  785. string2idx(sidx, idx, dims);
  786. }
  787. else
  788. {
  789. for( k = 0; k < dims; k++ )
  790. idx[k] = (unsigned)rng % size[k];
  791. sidx = idx2string(idx, dims);
  792. }
  793. eraseValue(M, idx, rng);
  794. eraseValue(M2, idx);
  795. val1 = getValue(M, idx, rng);
  796. val2 = getValue(M2, idx);
  797. if( val1 != 0 || val2 != 0 )
  798. {
  799. errcount++;
  800. 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 );
  801. break;
  802. }
  803. }
  804. int nz = (int)M.nzcount();
  805. if( nz != 0 )
  806. {
  807. errcount++;
  808. ts->printf(cvtest::TS::LOG, "The number of non-zero elements after removing all the elements = %d (while it should be 0)\n", nz );
  809. break;
  810. }
  811. int idx1[MAX_DIM], idx2[MAX_DIM];
  812. double val1 = 0, val2 = 0;
  813. M3 = SparseMat(Md);
  814. cv::minMaxLoc(M3, &val1, &val2, idx1, idx2);
  815. string s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims);
  816. if( val1 != min_val || val2 != max_val || s1 != min_sidx || s2 != max_sidx )
  817. {
  818. errcount++;
  819. 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"
  820. "(%g, %g, %s, %s) vs (%g, %g, %s, %s)\n", si, val1, val2, s1.c_str(), s2.c_str(),
  821. min_val, max_val, min_sidx.c_str(), max_sidx.c_str());
  822. break;
  823. }
  824. cv::minMaxIdx(Md, &val1, &val2, idx1, idx2);
  825. s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims);
  826. if( (min_val < 0 && (val1 != min_val || s1 != min_sidx)) ||
  827. (max_val > 0 && (val2 != max_val || s2 != max_sidx)) )
  828. {
  829. errcount++;
  830. 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"
  831. "(%g, %g, %s, %s) vs (%g, %g, %s, %s)\n", si, val1, val2, s1.c_str(), s2.c_str(),
  832. min_val, max_val, min_sidx.c_str(), max_sidx.c_str());
  833. break;
  834. }
  835. }
  836. ts->set_failed_test_info(errcount == 0 ? cvtest::TS::OK : cvtest::TS::FAIL_INVALID_OUTPUT);
  837. }
  838. template <class T>
  839. int calcDiffElemCountImpl(const vector<Mat>& mv, const Mat& m)
  840. {
  841. int diffElemCount = 0;
  842. const int mChannels = m.channels();
  843. for(int y = 0; y < m.rows; y++)
  844. {
  845. for(int x = 0; x < m.cols; x++)
  846. {
  847. const T* mElem = &m.at<T>(y, x*mChannels);
  848. size_t loc = 0;
  849. for(size_t i = 0; i < mv.size(); i++)
  850. {
  851. const size_t mvChannel = mv[i].channels();
  852. const T* mvElem = &mv[i].at<T>(y, x*(int)mvChannel);
  853. for(size_t li = 0; li < mvChannel; li++)
  854. if(mElem[loc + li] != mvElem[li])
  855. diffElemCount++;
  856. loc += mvChannel;
  857. }
  858. CV_Assert(loc == (size_t)mChannels);
  859. }
  860. }
  861. return diffElemCount;
  862. }
  863. static
  864. int calcDiffElemCount(const vector<Mat>& mv, const Mat& m)
  865. {
  866. int depth = m.depth();
  867. switch (depth)
  868. {
  869. case CV_8U:
  870. return calcDiffElemCountImpl<uchar>(mv, m);
  871. case CV_8S:
  872. return calcDiffElemCountImpl<char>(mv, m);
  873. case CV_16U:
  874. return calcDiffElemCountImpl<unsigned short>(mv, m);
  875. case CV_16S:
  876. return calcDiffElemCountImpl<short int>(mv, m);
  877. case CV_32S:
  878. return calcDiffElemCountImpl<int>(mv, m);
  879. case CV_32F:
  880. return calcDiffElemCountImpl<float>(mv, m);
  881. case CV_64F:
  882. return calcDiffElemCountImpl<double>(mv, m);
  883. }
  884. return INT_MAX;
  885. }
  886. class Core_MergeSplitBaseTest : public cvtest::BaseTest
  887. {
  888. protected:
  889. virtual int run_case(int depth, size_t channels, const Size& size, RNG& rng) = 0;
  890. virtual void run(int)
  891. {
  892. // m is Mat
  893. // mv is vector<Mat>
  894. const int minMSize = 1;
  895. const int maxMSize = 100;
  896. const size_t maxMvSize = 10;
  897. RNG& rng = theRNG();
  898. Size mSize(rng.uniform(minMSize, maxMSize), rng.uniform(minMSize, maxMSize));
  899. size_t mvSize = rng.uniform(1, maxMvSize);
  900. int res = cvtest::TS::OK;
  901. int curRes = run_case(CV_8U, mvSize, mSize, rng);
  902. res = curRes != cvtest::TS::OK ? curRes : res;
  903. curRes = run_case(CV_8S, mvSize, mSize, rng);
  904. res = curRes != cvtest::TS::OK ? curRes : res;
  905. curRes = run_case(CV_16U, mvSize, mSize, rng);
  906. res = curRes != cvtest::TS::OK ? curRes : res;
  907. curRes = run_case(CV_16S, mvSize, mSize, rng);
  908. res = curRes != cvtest::TS::OK ? curRes : res;
  909. curRes = run_case(CV_32S, mvSize, mSize, rng);
  910. res = curRes != cvtest::TS::OK ? curRes : res;
  911. curRes = run_case(CV_32F, mvSize, mSize, rng);
  912. res = curRes != cvtest::TS::OK ? curRes : res;
  913. curRes = run_case(CV_64F, mvSize, mSize, rng);
  914. res = curRes != cvtest::TS::OK ? curRes : res;
  915. ts->set_failed_test_info(res);
  916. }
  917. };
  918. class Core_MergeTest : public Core_MergeSplitBaseTest
  919. {
  920. public:
  921. Core_MergeTest() {}
  922. ~Core_MergeTest() {}
  923. protected:
  924. virtual int run_case(int depth, size_t matCount, const Size& size, RNG& rng)
  925. {
  926. const int maxMatChannels = 10;
  927. vector<Mat> src(matCount);
  928. int channels = 0;
  929. for(size_t i = 0; i < src.size(); i++)
  930. {
  931. Mat m(size, CV_MAKETYPE(depth, rng.uniform(1,maxMatChannels)));
  932. rng.fill(m, RNG::UNIFORM, 0, 100, true);
  933. channels += m.channels();
  934. src[i] = m;
  935. }
  936. Mat dst;
  937. merge(src, dst);
  938. // check result
  939. std::stringstream commonLog;
  940. commonLog << "Depth " << depth << " :";
  941. if(dst.depth() != depth)
  942. {
  943. ts->printf(cvtest::TS::LOG, "%s incorrect depth of dst (%d instead of %d)\n",
  944. commonLog.str().c_str(), dst.depth(), depth);
  945. return cvtest::TS::FAIL_INVALID_OUTPUT;
  946. }
  947. if(dst.size() != size)
  948. {
  949. ts->printf(cvtest::TS::LOG, "%s incorrect size of dst (%d x %d instead of %d x %d)\n",
  950. commonLog.str().c_str(), dst.rows, dst.cols, size.height, size.width);
  951. return cvtest::TS::FAIL_INVALID_OUTPUT;
  952. }
  953. if(dst.channels() != channels)
  954. {
  955. ts->printf(cvtest::TS::LOG, "%s: incorrect channels count of dst (%d instead of %d)\n",
  956. commonLog.str().c_str(), dst.channels(), channels);
  957. return cvtest::TS::FAIL_INVALID_OUTPUT;
  958. }
  959. int diffElemCount = calcDiffElemCount(src, dst);
  960. if(diffElemCount > 0)
  961. {
  962. ts->printf(cvtest::TS::LOG, "%s: there are incorrect elements in dst (part of them is %f)\n",
  963. commonLog.str().c_str(), static_cast<float>(diffElemCount)/(channels*size.area()));
  964. return cvtest::TS::FAIL_INVALID_OUTPUT;
  965. }
  966. return cvtest::TS::OK;
  967. }
  968. };
  969. class Core_SplitTest : public Core_MergeSplitBaseTest
  970. {
  971. public:
  972. Core_SplitTest() {}
  973. ~Core_SplitTest() {}
  974. protected:
  975. virtual int run_case(int depth, size_t channels, const Size& size, RNG& rng)
  976. {
  977. Mat src(size, CV_MAKETYPE(depth, (int)channels));
  978. rng.fill(src, RNG::UNIFORM, 0, 100, true);
  979. vector<Mat> dst;
  980. split(src, dst);
  981. // check result
  982. std::stringstream commonLog;
  983. commonLog << "Depth " << depth << " :";
  984. if(dst.size() != channels)
  985. {
  986. ts->printf(cvtest::TS::LOG, "%s incorrect count of matrices in dst (%d instead of %d)\n",
  987. commonLog.str().c_str(), dst.size(), channels);
  988. return cvtest::TS::FAIL_INVALID_OUTPUT;
  989. }
  990. for(size_t i = 0; i < dst.size(); i++)
  991. {
  992. if(dst[i].size() != size)
  993. {
  994. ts->printf(cvtest::TS::LOG, "%s incorrect size of dst[%d] (%d x %d instead of %d x %d)\n",
  995. commonLog.str().c_str(), i, dst[i].rows, dst[i].cols, size.height, size.width);
  996. return cvtest::TS::FAIL_INVALID_OUTPUT;
  997. }
  998. if(dst[i].depth() != depth)
  999. {
  1000. ts->printf(cvtest::TS::LOG, "%s: incorrect depth of dst[%d] (%d instead of %d)\n",
  1001. commonLog.str().c_str(), i, dst[i].depth(), depth);
  1002. return cvtest::TS::FAIL_INVALID_OUTPUT;
  1003. }
  1004. if(dst[i].channels() != 1)
  1005. {
  1006. ts->printf(cvtest::TS::LOG, "%s: incorrect channels count of dst[%d] (%d instead of %d)\n",
  1007. commonLog.str().c_str(), i, dst[i].channels(), 1);
  1008. return cvtest::TS::FAIL_INVALID_OUTPUT;
  1009. }
  1010. }
  1011. int diffElemCount = calcDiffElemCount(dst, src);
  1012. if(diffElemCount > 0)
  1013. {
  1014. ts->printf(cvtest::TS::LOG, "%s: there are incorrect elements in dst (part of them is %f)\n",
  1015. commonLog.str().c_str(), static_cast<float>(diffElemCount)/(channels*size.area()));
  1016. return cvtest::TS::FAIL_INVALID_OUTPUT;
  1017. }
  1018. return cvtest::TS::OK;
  1019. }
  1020. };
  1021. TEST(Core_Reduce, accuracy) { Core_ReduceTest test; test.safe_run(); }
  1022. TEST(Core_Array, basic_operations) { Core_ArrayOpTest test; test.safe_run(); }
  1023. TEST(Core_Merge, shape_operations) { Core_MergeTest test; test.safe_run(); }
  1024. TEST(Core_Split, shape_operations) { Core_SplitTest test; test.safe_run(); }
  1025. TEST(Core_IOArray, submat_assignment)
  1026. {
  1027. Mat1f A = Mat1f::zeros(2,2);
  1028. Mat1f B = Mat1f::ones(1,3);
  1029. EXPECT_THROW( B.colRange(0,3).copyTo(A.row(0)), cv::Exception );
  1030. EXPECT_NO_THROW( B.colRange(0,2).copyTo(A.row(0)) );
  1031. EXPECT_EQ( 1.0f, A(0,0) );
  1032. EXPECT_EQ( 1.0f, A(0,1) );
  1033. }
  1034. void OutputArray_create1(OutputArray m) { m.create(1, 2, CV_32S); }
  1035. void OutputArray_create2(OutputArray m) { m.create(1, 3, CV_32F); }
  1036. TEST(Core_IOArray, submat_create)
  1037. {
  1038. Mat1f A = Mat1f::zeros(2,2);
  1039. EXPECT_THROW( OutputArray_create1(A.row(0)), cv::Exception );
  1040. EXPECT_THROW( OutputArray_create2(A.row(0)), cv::Exception );
  1041. }
  1042. TEST(Core_Mat, issue4457_pass_null_ptr)
  1043. {
  1044. ASSERT_ANY_THROW(cv::Mat mask(45, 45, CV_32F, 0));
  1045. }
  1046. TEST(Core_Mat, reshape_1942)
  1047. {
  1048. cv::Mat A = (cv::Mat_<float>(2,3) << 3.4884074, 1.4159607, 0.78737736, 2.3456569, -0.88010466, 0.3009364);
  1049. int cn = 0;
  1050. ASSERT_NO_THROW(
  1051. cv::Mat_<float> M = A.reshape(3);
  1052. cn = M.channels();
  1053. );
  1054. ASSERT_EQ(1, cn);
  1055. }
  1056. static void check_ndim_shape(const cv::Mat &mat, int cn, int ndims, const int *sizes)
  1057. {
  1058. EXPECT_EQ(mat.channels(), cn);
  1059. EXPECT_EQ(mat.dims, ndims);
  1060. if (mat.dims != ndims)
  1061. return;
  1062. for (int i = 0; i < ndims; i++)
  1063. EXPECT_EQ(mat.size[i], sizes[i]);
  1064. }
  1065. TEST(Core_Mat, reshape_ndims_2)
  1066. {
  1067. const cv::Mat A(8, 16, CV_8UC3);
  1068. cv::Mat B;
  1069. {
  1070. int new_sizes_mask[] = { 0, 3, 4, 4 };
  1071. int new_sizes_real[] = { 8, 3, 4, 4 };
  1072. ASSERT_NO_THROW(B = A.reshape(1, 4, new_sizes_mask));
  1073. check_ndim_shape(B, 1, 4, new_sizes_real);
  1074. }
  1075. {
  1076. int new_sizes[] = { 16, 8 };
  1077. ASSERT_NO_THROW(B = A.reshape(0, 2, new_sizes));
  1078. check_ndim_shape(B, 3, 2, new_sizes);
  1079. EXPECT_EQ(B.rows, new_sizes[0]);
  1080. EXPECT_EQ(B.cols, new_sizes[1]);
  1081. }
  1082. {
  1083. int new_sizes[] = { 2, 5, 1, 3 };
  1084. cv::Mat A_sliced = A(cv::Range::all(), cv::Range(0, 15));
  1085. ASSERT_ANY_THROW(A_sliced.reshape(4, 4, new_sizes));
  1086. }
  1087. }
  1088. TEST(Core_Mat, reshape_ndims_4)
  1089. {
  1090. const int sizes[] = { 2, 6, 4, 12 };
  1091. const cv::Mat A(4, sizes, CV_8UC3);
  1092. cv::Mat B;
  1093. {
  1094. int new_sizes_mask[] = { 0, 864 };
  1095. int new_sizes_real[] = { 2, 864 };
  1096. ASSERT_NO_THROW(B = A.reshape(1, 2, new_sizes_mask));
  1097. check_ndim_shape(B, 1, 2, new_sizes_real);
  1098. EXPECT_EQ(B.rows, new_sizes_real[0]);
  1099. EXPECT_EQ(B.cols, new_sizes_real[1]);
  1100. }
  1101. {
  1102. int new_sizes_mask[] = { 4, 0, 0, 2, 3 };
  1103. int new_sizes_real[] = { 4, 6, 4, 2, 3 };
  1104. ASSERT_NO_THROW(B = A.reshape(0, 5, new_sizes_mask));
  1105. check_ndim_shape(B, 3, 5, new_sizes_real);
  1106. }
  1107. {
  1108. int new_sizes_mask[] = { 1, 1 };
  1109. ASSERT_ANY_THROW(A.reshape(0, 2, new_sizes_mask));
  1110. }
  1111. {
  1112. int new_sizes_mask[] = { 4, 6, 3, 3, 0 };
  1113. ASSERT_ANY_THROW(A.reshape(0, 5, new_sizes_mask));
  1114. }
  1115. }
  1116. TEST(Core_Mat, push_back)
  1117. {
  1118. Mat a = (Mat_<float>(1,2) << 3.4884074f, 1.4159607f);
  1119. Mat b = (Mat_<float>(1,2) << 0.78737736f, 2.3456569f);
  1120. a.push_back(b);
  1121. ASSERT_EQ(2, a.cols);
  1122. ASSERT_EQ(2, a.rows);
  1123. ASSERT_FLOAT_EQ(3.4884074f, a.at<float>(0, 0));
  1124. ASSERT_FLOAT_EQ(1.4159607f, a.at<float>(0, 1));
  1125. ASSERT_FLOAT_EQ(0.78737736f, a.at<float>(1, 0));
  1126. ASSERT_FLOAT_EQ(2.3456569f, a.at<float>(1, 1));
  1127. Mat c = (Mat_<float>(2,2) << -0.88010466f, 0.3009364f, 2.22399974f, -5.45933905f);
  1128. ASSERT_EQ(c.rows, a.cols);
  1129. a.push_back(c.t());
  1130. ASSERT_EQ(2, a.cols);
  1131. ASSERT_EQ(4, a.rows);
  1132. ASSERT_FLOAT_EQ(3.4884074f, a.at<float>(0, 0));
  1133. ASSERT_FLOAT_EQ(1.4159607f, a.at<float>(0, 1));
  1134. ASSERT_FLOAT_EQ(0.78737736f, a.at<float>(1, 0));
  1135. ASSERT_FLOAT_EQ(2.3456569f, a.at<float>(1, 1));
  1136. ASSERT_FLOAT_EQ(-0.88010466f, a.at<float>(2, 0));
  1137. ASSERT_FLOAT_EQ(2.22399974f, a.at<float>(2, 1));
  1138. ASSERT_FLOAT_EQ(0.3009364f, a.at<float>(3, 0));
  1139. ASSERT_FLOAT_EQ(-5.45933905f, a.at<float>(3, 1));
  1140. a.push_back(Mat::ones(2, 2, CV_32FC1));
  1141. ASSERT_EQ(6, a.rows);
  1142. for(int row=4; row<a.rows; row++) {
  1143. for(int col=0; col<a.cols; col++) {
  1144. ASSERT_FLOAT_EQ(1.f, a.at<float>(row, col));
  1145. }
  1146. }
  1147. }
  1148. TEST(Core_Mat, copyNx1ToVector)
  1149. {
  1150. cv::Mat_<uchar> src(5, 1);
  1151. cv::Mat_<uchar> ref_dst8;
  1152. cv::Mat_<ushort> ref_dst16;
  1153. std::vector<uchar> dst8;
  1154. std::vector<ushort> dst16;
  1155. src << 1, 2, 3, 4, 5;
  1156. src.copyTo(ref_dst8);
  1157. src.copyTo(dst8);
  1158. ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), ref_dst8, cv::Mat_<uchar>(dst8));
  1159. src.convertTo(ref_dst16, CV_16U);
  1160. src.convertTo(dst16, CV_16U);
  1161. ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), ref_dst16, cv::Mat_<ushort>(dst16));
  1162. }
  1163. TEST(Core_Matx, fromMat_)
  1164. {
  1165. Mat_<double> a = (Mat_<double>(2,2) << 10, 11, 12, 13);
  1166. Matx22d b(a);
  1167. ASSERT_EQ( cvtest::norm(a, b, NORM_INF), 0.);
  1168. }
  1169. TEST(Core_Matx, from_initializer_list)
  1170. {
  1171. Mat_<double> a = (Mat_<double>(2,2) << 10, 11, 12, 13);
  1172. Matx22d b = {10, 11, 12, 13};
  1173. ASSERT_EQ( cvtest::norm(a, b, NORM_INF), 0.);
  1174. }
  1175. TEST(Core_Mat, regression_9507)
  1176. {
  1177. cv::Mat m = Mat::zeros(5, 5, CV_8UC3);
  1178. cv::Mat m2{m};
  1179. EXPECT_EQ(25u, m2.total());
  1180. }
  1181. TEST(Core_InputArray, empty)
  1182. {
  1183. vector<vector<Point> > data;
  1184. ASSERT_TRUE( _InputArray(data).empty() );
  1185. }
  1186. TEST(Core_CopyMask, bug1918)
  1187. {
  1188. Mat_<unsigned char> tmpSrc(100,100);
  1189. tmpSrc = 124;
  1190. Mat_<unsigned char> tmpMask(100,100);
  1191. tmpMask = 255;
  1192. Mat_<unsigned char> tmpDst(100,100);
  1193. tmpDst = 2;
  1194. tmpSrc.copyTo(tmpDst,tmpMask);
  1195. ASSERT_EQ(sum(tmpDst)[0], 124*100*100);
  1196. }
  1197. TEST(Core_SVD, orthogonality)
  1198. {
  1199. for( int i = 0; i < 2; i++ )
  1200. {
  1201. int type = i == 0 ? CV_32F : CV_64F;
  1202. Mat mat_D(2, 2, type);
  1203. mat_D.setTo(88.);
  1204. Mat mat_U, mat_W;
  1205. SVD::compute(mat_D, mat_W, mat_U, noArray(), SVD::FULL_UV);
  1206. mat_U *= mat_U.t();
  1207. ASSERT_LT(cvtest::norm(mat_U, Mat::eye(2, 2, type), NORM_INF), 1e-5);
  1208. }
  1209. }
  1210. TEST(Core_SparseMat, footprint)
  1211. {
  1212. int n = 1000000;
  1213. int sz[] = { n, n };
  1214. SparseMat m(2, sz, CV_64F);
  1215. int nodeSize0 = (int)m.hdr->nodeSize;
  1216. double dataSize0 = ((double)m.hdr->pool.size() + (double)m.hdr->hashtab.size()*sizeof(size_t))*1e-6;
  1217. printf("before: node size=%d bytes, data size=%.0f Mbytes\n", nodeSize0, dataSize0);
  1218. for (int i = 0; i < n; i++)
  1219. {
  1220. m.ref<double>(i, i) = 1;
  1221. }
  1222. double dataSize1 = ((double)m.hdr->pool.size() + (double)m.hdr->hashtab.size()*sizeof(size_t))*1e-6;
  1223. double threshold = (n*nodeSize0*1.6 + n*2.*sizeof(size_t))*1e-6;
  1224. printf("after: data size=%.0f Mbytes, threshold=%.0f MBytes\n", dataSize1, threshold);
  1225. ASSERT_LE((int)m.hdr->nodeSize, 32);
  1226. ASSERT_LE(dataSize1, threshold);
  1227. }
  1228. // Can't fix without dirty hacks or broken user code (PR #4159)
  1229. TEST(Core_Mat_vector, DISABLED_OutputArray_create_getMat)
  1230. {
  1231. cv::Mat_<uchar> src_base(5, 1);
  1232. std::vector<uchar> dst8;
  1233. src_base << 1, 2, 3, 4, 5;
  1234. Mat src(src_base);
  1235. OutputArray _dst(dst8);
  1236. {
  1237. _dst.create(src.rows, src.cols, src.type());
  1238. Mat dst = _dst.getMat();
  1239. EXPECT_EQ(src.dims, dst.dims);
  1240. EXPECT_EQ(src.cols, dst.cols);
  1241. EXPECT_EQ(src.rows, dst.rows);
  1242. }
  1243. }
  1244. TEST(Core_Mat_vector, copyTo_roi_column)
  1245. {
  1246. cv::Mat_<uchar> src_base(5, 2);
  1247. std::vector<uchar> dst1;
  1248. src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
  1249. Mat src_full(src_base);
  1250. Mat src(src_full.col(0));
  1251. #if 0 // Can't fix without dirty hacks or broken user code (PR #4159)
  1252. OutputArray _dst(dst1);
  1253. {
  1254. _dst.create(src.rows, src.cols, src.type());
  1255. Mat dst = _dst.getMat();
  1256. EXPECT_EQ(src.dims, dst.dims);
  1257. EXPECT_EQ(src.cols, dst.cols);
  1258. EXPECT_EQ(src.rows, dst.rows);
  1259. }
  1260. #endif
  1261. std::vector<uchar> dst2;
  1262. src.copyTo(dst2);
  1263. std::cout << "src = " << src << std::endl;
  1264. std::cout << "dst = " << Mat(dst2) << std::endl;
  1265. EXPECT_EQ((size_t)5, dst2.size());
  1266. EXPECT_EQ(1, (int)dst2[0]);
  1267. EXPECT_EQ(3, (int)dst2[1]);
  1268. EXPECT_EQ(5, (int)dst2[2]);
  1269. EXPECT_EQ(7, (int)dst2[3]);
  1270. EXPECT_EQ(9, (int)dst2[4]);
  1271. }
  1272. TEST(Core_Mat_vector, copyTo_roi_row)
  1273. {
  1274. cv::Mat_<uchar> src_base(2, 5);
  1275. std::vector<uchar> dst1;
  1276. src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
  1277. Mat src_full(src_base);
  1278. Mat src(src_full.row(0));
  1279. OutputArray _dst(dst1);
  1280. {
  1281. _dst.create(src.rows, src.cols, src.type());
  1282. Mat dst = _dst.getMat();
  1283. EXPECT_EQ(src.dims, dst.dims);
  1284. EXPECT_EQ(src.cols, dst.cols);
  1285. EXPECT_EQ(src.rows, dst.rows);
  1286. }
  1287. std::vector<uchar> dst2;
  1288. src.copyTo(dst2);
  1289. std::cout << "src = " << src << std::endl;
  1290. std::cout << "dst = " << Mat(dst2) << std::endl;
  1291. EXPECT_EQ((size_t)5, dst2.size());
  1292. EXPECT_EQ(1, (int)dst2[0]);
  1293. EXPECT_EQ(2, (int)dst2[1]);
  1294. EXPECT_EQ(3, (int)dst2[2]);
  1295. EXPECT_EQ(4, (int)dst2[3]);
  1296. EXPECT_EQ(5, (int)dst2[4]);
  1297. }
  1298. TEST(Mat, regression_5991)
  1299. {
  1300. int sz[] = {2,3,2};
  1301. Mat mat(3, sz, CV_32F, Scalar(1));
  1302. ASSERT_NO_THROW(mat.convertTo(mat, CV_8U));
  1303. EXPECT_EQ(sz[0], mat.size[0]);
  1304. EXPECT_EQ(sz[1], mat.size[1]);
  1305. EXPECT_EQ(sz[2], mat.size[2]);
  1306. EXPECT_EQ(0, cvtest::norm(mat, Mat(3, sz, CV_8U, Scalar(1)), NORM_INF));
  1307. }
  1308. TEST(Mat, regression_9720)
  1309. {
  1310. Mat mat(1, 1, CV_32FC1);
  1311. mat.at<float>(0) = 1.f;
  1312. const float a = 0.1f;
  1313. Mat me1 = (Mat)(mat.mul((a / mat)));
  1314. Mat me2 = (Mat)(mat.mul((Mat)(a / mat)));
  1315. Mat me3 = (Mat)(mat.mul((a * mat)));
  1316. Mat me4 = (Mat)(mat.mul((Mat)(a * mat)));
  1317. EXPECT_EQ(me1.at<float>(0), me2.at<float>(0));
  1318. EXPECT_EQ(me3.at<float>(0), me4.at<float>(0));
  1319. }
  1320. #ifdef OPENCV_TEST_BIGDATA
  1321. TEST(Mat, regression_6696_BigData_8Gb)
  1322. {
  1323. int width = 60000;
  1324. int height = 10000;
  1325. Mat destImageBGR = Mat(height, width, CV_8UC3, Scalar(1, 2, 3, 0));
  1326. Mat destImageA = Mat(height, width, CV_8UC1, Scalar::all(4));
  1327. vector<Mat> planes;
  1328. split(destImageBGR, planes);
  1329. planes.push_back(destImageA);
  1330. merge(planes, destImageBGR);
  1331. EXPECT_EQ(1, destImageBGR.at<Vec4b>(0)[0]);
  1332. EXPECT_EQ(2, destImageBGR.at<Vec4b>(0)[1]);
  1333. EXPECT_EQ(3, destImageBGR.at<Vec4b>(0)[2]);
  1334. EXPECT_EQ(4, destImageBGR.at<Vec4b>(0)[3]);
  1335. EXPECT_EQ(1, destImageBGR.at<Vec4b>(height-1, width-1)[0]);
  1336. EXPECT_EQ(2, destImageBGR.at<Vec4b>(height-1, width-1)[1]);
  1337. EXPECT_EQ(3, destImageBGR.at<Vec4b>(height-1, width-1)[2]);
  1338. EXPECT_EQ(4, destImageBGR.at<Vec4b>(height-1, width-1)[3]);
  1339. }
  1340. #endif
  1341. TEST(Reduce, regression_should_fail_bug_4594)
  1342. {
  1343. cv::Mat src = cv::Mat::eye(4, 4, CV_8U);
  1344. std::vector<int> dst;
  1345. EXPECT_THROW(cv::reduce(src, dst, 0, REDUCE_MIN, CV_32S), cv::Exception);
  1346. EXPECT_THROW(cv::reduce(src, dst, 0, REDUCE_MAX, CV_32S), cv::Exception);
  1347. EXPECT_NO_THROW(cv::reduce(src, dst, 0, REDUCE_SUM, CV_32S));
  1348. EXPECT_NO_THROW(cv::reduce(src, dst, 0, REDUCE_AVG, CV_32S));
  1349. }
  1350. TEST(Mat, push_back_vector)
  1351. {
  1352. cv::Mat result(1, 5, CV_32FC1);
  1353. std::vector<float> vec1(result.cols + 1);
  1354. std::vector<int> vec2(result.cols);
  1355. EXPECT_THROW(result.push_back(vec1), cv::Exception);
  1356. EXPECT_THROW(result.push_back(vec2), cv::Exception);
  1357. vec1.resize(result.cols);
  1358. for (int i = 0; i < 5; ++i)
  1359. result.push_back(cv::Mat(vec1).reshape(1, 1));
  1360. ASSERT_EQ(6, result.rows);
  1361. }
  1362. TEST(Mat, regression_5917_clone_empty)
  1363. {
  1364. Mat cloned;
  1365. Mat_<Point2f> source(5, 0);
  1366. ASSERT_NO_THROW(cloned = source.clone());
  1367. }
  1368. TEST(Mat, regression_7873_mat_vector_initialize)
  1369. {
  1370. std::vector<int> dims;
  1371. dims.push_back(12);
  1372. dims.push_back(3);
  1373. dims.push_back(2);
  1374. Mat multi_mat(dims, CV_32FC1, cv::Scalar(0));
  1375. ASSERT_EQ(3, multi_mat.dims);
  1376. ASSERT_EQ(12, multi_mat.size[0]);
  1377. ASSERT_EQ(3, multi_mat.size[1]);
  1378. ASSERT_EQ(2, multi_mat.size[2]);
  1379. std::vector<Range> ranges;
  1380. ranges.push_back(Range(1, 2));
  1381. ranges.push_back(Range::all());
  1382. ranges.push_back(Range::all());
  1383. Mat sub_mat = multi_mat(ranges);
  1384. ASSERT_EQ(3, sub_mat.dims);
  1385. ASSERT_EQ(1, sub_mat.size[0]);
  1386. ASSERT_EQ(3, sub_mat.size[1]);
  1387. ASSERT_EQ(2, sub_mat.size[2]);
  1388. }
  1389. TEST(Mat, regression_10507_mat_setTo)
  1390. {
  1391. Size sz(6, 4);
  1392. Mat test_mask(sz, CV_8UC1, cv::Scalar::all(255));
  1393. test_mask.at<uchar>(1,0) = 0;
  1394. test_mask.at<uchar>(0,1) = 0;
  1395. for (int cn = 1; cn <= 4; cn++)
  1396. {
  1397. cv::Mat A(sz, CV_MAKE_TYPE(CV_32F, cn), cv::Scalar::all(5));
  1398. A.setTo(cv::Scalar::all(std::numeric_limits<float>::quiet_NaN()), test_mask);
  1399. int nans = 0;
  1400. for (int y = 0; y < A.rows; y++)
  1401. {
  1402. for (int x = 0; x < A.cols; x++)
  1403. {
  1404. for (int c = 0; c < cn; c++)
  1405. {
  1406. float v = A.ptr<float>(y, x)[c];
  1407. nans += (v == v) ? 0 : 1;
  1408. }
  1409. }
  1410. }
  1411. EXPECT_EQ(nans, cn * (sz.area() - 2)) << "A=" << A << std::endl << "mask=" << test_mask << std::endl;
  1412. }
  1413. }
  1414. TEST(Core_Mat_array, outputArray_create_getMat)
  1415. {
  1416. cv::Mat_<uchar> src_base(5, 1);
  1417. std::array<uchar, 5> dst8;
  1418. src_base << 1, 2, 3, 4, 5;
  1419. Mat src(src_base);
  1420. OutputArray _dst(dst8);
  1421. {
  1422. _dst.create(src.rows, src.cols, src.type());
  1423. Mat dst = _dst.getMat();
  1424. EXPECT_EQ(src.dims, dst.dims);
  1425. EXPECT_EQ(src.cols, dst.cols);
  1426. EXPECT_EQ(src.rows, dst.rows);
  1427. }
  1428. }
  1429. TEST(Core_Mat_array, copyTo_roi_column)
  1430. {
  1431. cv::Mat_<uchar> src_base(5, 2);
  1432. src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
  1433. Mat src_full(src_base);
  1434. Mat src(src_full.col(0));
  1435. std::array<uchar, 5> dst1;
  1436. src.copyTo(dst1);
  1437. std::cout << "src = " << src << std::endl;
  1438. std::cout << "dst = " << Mat(dst1) << std::endl;
  1439. EXPECT_EQ((size_t)5, dst1.size());
  1440. EXPECT_EQ(1, (int)dst1[0]);
  1441. EXPECT_EQ(3, (int)dst1[1]);
  1442. EXPECT_EQ(5, (int)dst1[2]);
  1443. EXPECT_EQ(7, (int)dst1[3]);
  1444. EXPECT_EQ(9, (int)dst1[4]);
  1445. }
  1446. TEST(Core_Mat_array, copyTo_roi_row)
  1447. {
  1448. cv::Mat_<uchar> src_base(2, 5);
  1449. std::array<uchar, 5> dst1;
  1450. src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
  1451. Mat src_full(src_base);
  1452. Mat src(src_full.row(0));
  1453. OutputArray _dst(dst1);
  1454. {
  1455. _dst.create(5, 1, src.type());
  1456. Mat dst = _dst.getMat();
  1457. EXPECT_EQ(src.dims, dst.dims);
  1458. EXPECT_EQ(1, dst.cols);
  1459. EXPECT_EQ(5, dst.rows);
  1460. }
  1461. std::array<uchar, 5> dst2;
  1462. src.copyTo(dst2);
  1463. std::cout << "src = " << src << std::endl;
  1464. std::cout << "dst = " << Mat(dst2) << std::endl;
  1465. EXPECT_EQ(1, (int)dst2[0]);
  1466. EXPECT_EQ(2, (int)dst2[1]);
  1467. EXPECT_EQ(3, (int)dst2[2]);
  1468. EXPECT_EQ(4, (int)dst2[3]);
  1469. EXPECT_EQ(5, (int)dst2[4]);
  1470. }
  1471. TEST(Core_Mat_array, SplitMerge)
  1472. {
  1473. std::array<cv::Mat, 3> src;
  1474. for (size_t i = 0; i < src.size(); ++i)
  1475. {
  1476. src[i] = Mat(10, 10, CV_8U, Scalar((double)(16 * (i + 1))));
  1477. }
  1478. Mat merged;
  1479. merge(src, merged);
  1480. std::array<cv::Mat, 3> dst;
  1481. split(merged, dst);
  1482. for (size_t i = 0; i < dst.size(); ++i)
  1483. {
  1484. EXPECT_EQ(0, cvtest::norm(src[i], dst[i], NORM_INF));
  1485. }
  1486. }
  1487. TEST(Mat, regression_8680)
  1488. {
  1489. Mat_<Point2i> mat(3,1);
  1490. ASSERT_EQ(mat.channels(), 2);
  1491. mat.release();
  1492. ASSERT_EQ(mat.channels(), 2);
  1493. }
  1494. TEST(Mat_, range_based_for)
  1495. {
  1496. Mat_<uchar> img = Mat_<uchar>::zeros(3, 3);
  1497. for(auto& pixel : img)
  1498. {
  1499. pixel = 1;
  1500. }
  1501. Mat_<uchar> ref(3, 3);
  1502. ref.setTo(Scalar(1));
  1503. ASSERT_DOUBLE_EQ(cvtest::norm(img, ref, NORM_INF), 0.);
  1504. }
  1505. TEST(Mat, from_initializer_list)
  1506. {
  1507. Mat A({1.f, 2.f, 3.f});
  1508. Mat_<float> B(3, 1); B << 1, 2, 3;
  1509. Mat_<float> C({3}, {1,2,3});
  1510. ASSERT_EQ(A.type(), CV_32F);
  1511. ASSERT_DOUBLE_EQ(cvtest::norm(A, B, NORM_INF), 0.);
  1512. ASSERT_DOUBLE_EQ(cvtest::norm(A, C, NORM_INF), 0.);
  1513. ASSERT_DOUBLE_EQ(cvtest::norm(B, C, NORM_INF), 0.);
  1514. auto D = Mat_<double>({2, 3}, {1, 2, 3, 4, 5, 6});
  1515. EXPECT_EQ(2, D.rows);
  1516. EXPECT_EQ(3, D.cols);
  1517. }
  1518. TEST(Mat_, from_initializer_list)
  1519. {
  1520. Mat_<float> A = {1, 2, 3};
  1521. Mat_<float> B(3, 1); B << 1, 2, 3;
  1522. Mat_<float> C({3}, {1,2,3});
  1523. ASSERT_DOUBLE_EQ(cvtest::norm(A, B, NORM_INF), 0.);
  1524. ASSERT_DOUBLE_EQ(cvtest::norm(A, C, NORM_INF), 0.);
  1525. ASSERT_DOUBLE_EQ(cvtest::norm(B, C, NORM_INF), 0.);
  1526. }
  1527. TEST(Mat, template_based_ptr)
  1528. {
  1529. Mat mat = (Mat_<float>(2, 2) << 11.0f, 22.0f, 33.0f, 44.0f);
  1530. int idx[2] = {1, 0};
  1531. ASSERT_FLOAT_EQ(33.0f, *(mat.ptr<float>(idx)));
  1532. idx[0] = 1;
  1533. idx[1] = 1;
  1534. ASSERT_FLOAT_EQ(44.0f, *(mat.ptr<float>(idx)));
  1535. }
  1536. TEST(Mat_, template_based_ptr)
  1537. {
  1538. int dim[4] = {2, 2, 1, 2};
  1539. Mat_<float> mat = (Mat_<float>(4, dim) << 11.0f, 22.0f, 33.0f, 44.0f,
  1540. 55.0f, 66.0f, 77.0f, 88.0f);
  1541. int idx[4] = {1, 0, 0, 1};
  1542. ASSERT_FLOAT_EQ(66.0f, *(mat.ptr<float>(idx)));
  1543. }
  1544. BIGDATA_TEST(Mat, push_back_regression_4158) // memory usage: ~10.6 Gb
  1545. {
  1546. Mat result;
  1547. Mat tail(100, 500000, CV_32FC2, Scalar(1, 2));
  1548. tail.copyTo(result);
  1549. for (int i = 1; i < 15; i++)
  1550. {
  1551. result.push_back(tail);
  1552. std::cout << "i = " << i << " result = " << result.size() << " used = " << (uint64)result.total()*result.elemSize()*(1.0 / (1 << 20)) << " Mb"
  1553. << " allocated=" << (uint64)(result.datalimit - result.datastart)*(1.0 / (1 << 20)) << " Mb" << std::endl;
  1554. }
  1555. for (int i = 0; i < 15; i++)
  1556. {
  1557. Rect roi(0, tail.rows * i, tail.cols, tail.rows);
  1558. int nz = countNonZero(result(roi).reshape(1) == 2);
  1559. EXPECT_EQ(tail.total(), (size_t)nz) << "i=" << i;
  1560. }
  1561. }
  1562. TEST(Core_Merge, hang_12171)
  1563. {
  1564. Mat src1(4, 24, CV_8UC1, Scalar::all(1));
  1565. Mat src2(4, 24, CV_8UC1, Scalar::all(2));
  1566. Rect src_roi(0, 0, 23, 4);
  1567. Mat src_channels[2] = { src1(src_roi), src2(src_roi) };
  1568. Mat dst(4, 24, CV_8UC2, Scalar::all(5));
  1569. Rect dst_roi(1, 0, 23, 4);
  1570. cv::merge(src_channels, 2, dst(dst_roi));
  1571. EXPECT_EQ(5, dst.ptr<uchar>()[0]);
  1572. EXPECT_EQ(5, dst.ptr<uchar>()[1]);
  1573. EXPECT_EQ(1, dst.ptr<uchar>()[2]);
  1574. EXPECT_EQ(2, dst.ptr<uchar>()[3]);
  1575. EXPECT_EQ(5, dst.ptr<uchar>(1)[0]);
  1576. EXPECT_EQ(5, dst.ptr<uchar>(1)[1]);
  1577. EXPECT_EQ(1, dst.ptr<uchar>(1)[2]);
  1578. EXPECT_EQ(2, dst.ptr<uchar>(1)[3]);
  1579. }
  1580. TEST(Core_Split, hang_12171)
  1581. {
  1582. Mat src(4, 24, CV_8UC2, Scalar(1,2,3,4));
  1583. Rect src_roi(0, 0, 23, 4);
  1584. Mat dst1(4, 24, CV_8UC1, Scalar::all(5));
  1585. Mat dst2(4, 24, CV_8UC1, Scalar::all(10));
  1586. Rect dst_roi(0, 0, 23, 4);
  1587. Mat dst[2] = { dst1(dst_roi), dst2(dst_roi) };
  1588. cv::split(src(src_roi), dst);
  1589. EXPECT_EQ(1, dst1.ptr<uchar>()[0]);
  1590. EXPECT_EQ(1, dst1.ptr<uchar>()[1]);
  1591. EXPECT_EQ(2, dst2.ptr<uchar>()[0]);
  1592. EXPECT_EQ(2, dst2.ptr<uchar>()[1]);
  1593. EXPECT_EQ(1, dst1.ptr<uchar>(1)[0]);
  1594. EXPECT_EQ(1, dst1.ptr<uchar>(1)[1]);
  1595. EXPECT_EQ(2, dst2.ptr<uchar>(1)[0]);
  1596. EXPECT_EQ(2, dst2.ptr<uchar>(1)[1]);
  1597. }
  1598. TEST(Core_Split, crash_12171)
  1599. {
  1600. Mat src(4, 40, CV_8UC2, Scalar(1,2,3,4));
  1601. Rect src_roi(0, 0, 39, 4);
  1602. Mat dst1(4, 40, CV_8UC1, Scalar::all(5));
  1603. Mat dst2(4, 40, CV_8UC1, Scalar::all(10));
  1604. Rect dst_roi(0, 0, 39, 4);
  1605. Mat dst[2] = { dst1(dst_roi), dst2(dst_roi) };
  1606. cv::split(src(src_roi), dst);
  1607. EXPECT_EQ(1, dst1.ptr<uchar>()[0]);
  1608. EXPECT_EQ(1, dst1.ptr<uchar>()[1]);
  1609. EXPECT_EQ(2, dst2.ptr<uchar>()[0]);
  1610. EXPECT_EQ(2, dst2.ptr<uchar>()[1]);
  1611. EXPECT_EQ(1, dst1.ptr<uchar>(1)[0]);
  1612. EXPECT_EQ(1, dst1.ptr<uchar>(1)[1]);
  1613. EXPECT_EQ(2, dst2.ptr<uchar>(1)[0]);
  1614. EXPECT_EQ(2, dst2.ptr<uchar>(1)[1]);
  1615. }
  1616. TEST(Core_Merge, bug_13544)
  1617. {
  1618. Mat src1(2, 2, CV_8UC3, Scalar::all(1));
  1619. Mat src2(2, 2, CV_8UC3, Scalar::all(2));
  1620. Mat src3(2, 2, CV_8UC3, Scalar::all(3));
  1621. Mat src_arr[] = { src1, src2, src3 };
  1622. Mat dst;
  1623. merge(src_arr, 3, dst);
  1624. ASSERT_EQ(9, dst.channels()); // Avoid memory access out of buffer
  1625. EXPECT_EQ(3, (int)dst.ptr<uchar>(0)[6]);
  1626. EXPECT_EQ(3, (int)dst.ptr<uchar>(0)[7]);
  1627. EXPECT_EQ(3, (int)dst.ptr<uchar>(0)[8]);
  1628. EXPECT_EQ(1, (int)dst.ptr<uchar>(1)[0]);
  1629. EXPECT_EQ(1, (int)dst.ptr<uchar>(1)[1]);
  1630. EXPECT_EQ(1, (int)dst.ptr<uchar>(1)[2]);
  1631. EXPECT_EQ(2, (int)dst.ptr<uchar>(1)[3]);
  1632. EXPECT_EQ(2, (int)dst.ptr<uchar>(1)[4]);
  1633. EXPECT_EQ(2, (int)dst.ptr<uchar>(1)[5]);
  1634. EXPECT_EQ(3, (int)dst.ptr<uchar>(1)[6]);
  1635. EXPECT_EQ(3, (int)dst.ptr<uchar>(1)[7]);
  1636. EXPECT_EQ(3, (int)dst.ptr<uchar>(1)[8]);
  1637. }
  1638. struct CustomType // like cv::Keypoint
  1639. {
  1640. Point2f pt;
  1641. float size;
  1642. float angle;
  1643. float response;
  1644. int octave;
  1645. int class_id;
  1646. };
  1647. static void test_CustomType(InputArray src_, OutputArray dst_)
  1648. {
  1649. Mat src = src_.getMat();
  1650. ASSERT_EQ(sizeof(CustomType), src.elemSize());
  1651. CV_CheckTypeEQ(src.type(), CV_MAKETYPE(CV_8U, sizeof(CustomType)), "");
  1652. CustomType* kpt = NULL;
  1653. {
  1654. Mat dst = dst_.getMat();
  1655. for (size_t i = 0; i < dst.total(); i++)
  1656. {
  1657. kpt = dst.ptr<CustomType>(0) + i;
  1658. kpt->octave = (int)i;
  1659. }
  1660. }
  1661. const int N = (int)src.total();
  1662. dst_.create(1, N * 2, rawType<CustomType>());
  1663. Mat dst = dst_.getMat();
  1664. for (size_t i = N; i < dst.total(); i++)
  1665. {
  1666. kpt = dst.ptr<CustomType>(0) + i;
  1667. kpt->octave = -(int)i;
  1668. }
  1669. #if 0 // Compilation error
  1670. CustomType& kpt = dst.at<CustomType>(0, 5);
  1671. #endif
  1672. }
  1673. TEST(Core_InputArray, support_CustomType)
  1674. {
  1675. std::vector<CustomType> kp1(5);
  1676. std::vector<CustomType> kp2(3);
  1677. test_CustomType(rawIn(kp1), rawOut(kp2));
  1678. ASSERT_EQ((size_t)10, kp2.size());
  1679. for (int i = 0; i < 3; i++)
  1680. {
  1681. EXPECT_EQ(i, kp2[i].octave);
  1682. }
  1683. for (int i = 3; i < 5; i++)
  1684. {
  1685. EXPECT_EQ(0, kp2[i].octave);
  1686. }
  1687. for (int i = 5; i < 10; i++)
  1688. {
  1689. EXPECT_EQ(-i, kp2[i].octave);
  1690. }
  1691. }
  1692. TEST(Core_InputArray, fetch_MatExpr)
  1693. {
  1694. Mat a(Size(10, 5), CV_32FC1, 5);
  1695. Mat b(Size(10, 5), CV_32FC1, 2);
  1696. MatExpr expr = a * b.t(); // gemm expression
  1697. Mat dst;
  1698. cv::add(expr, Scalar(1), dst); // invoke gemm() here
  1699. void* expr_data = expr.a.data;
  1700. Mat result = expr; // should not call gemm() here again
  1701. EXPECT_EQ(expr_data, result.data); // expr data is reused
  1702. EXPECT_EQ(dst.size(), result.size());
  1703. }
  1704. #ifdef CV_CXX11
  1705. class TestInputArrayRangeChecking {
  1706. static const char *kind2str(cv::_InputArray ia)
  1707. {
  1708. switch (ia.kind())
  1709. {
  1710. #define C(x) case cv::_InputArray::x: return #x
  1711. C(MAT);
  1712. C(UMAT);
  1713. C(EXPR);
  1714. C(MATX);
  1715. C(STD_VECTOR);
  1716. C(NONE);
  1717. C(STD_VECTOR_VECTOR);
  1718. C(STD_BOOL_VECTOR);
  1719. C(STD_VECTOR_MAT);
  1720. C(STD_ARRAY_MAT);
  1721. C(STD_VECTOR_UMAT);
  1722. C(CUDA_GPU_MAT);
  1723. C(STD_VECTOR_CUDA_GPU_MAT);
  1724. #undef C
  1725. default:
  1726. return "<unsupported>";
  1727. }
  1728. }
  1729. static void banner(cv::_InputArray ia, const char *label, const char *name)
  1730. {
  1731. std::cout << std::endl
  1732. << label << " = " << name << ", Kind: " << kind2str(ia)
  1733. << std::endl;
  1734. }
  1735. template<typename I, typename F>
  1736. static void testA(I ia, F f, const char *mfname)
  1737. {
  1738. banner(ia, "f", mfname);
  1739. EXPECT_THROW(f(ia, -1), cv::Exception)
  1740. << "f(ia, " << -1 << ") should throw cv::Exception";
  1741. for (int i = 0; i < int(ia.size()); i++)
  1742. {
  1743. EXPECT_NO_THROW(f(ia, i))
  1744. << "f(ia, " << i << ") should not throw an exception";
  1745. }
  1746. EXPECT_THROW(f(ia, int(ia.size())), cv::Exception)
  1747. << "f(ia, " << ia.size() << ") should throw cv::Exception";
  1748. }
  1749. template<typename I, typename F>
  1750. static void testB(I ia, F f, const char *mfname)
  1751. {
  1752. banner(ia, "f", mfname);
  1753. EXPECT_THROW(f(ia, -1), cv::Exception)
  1754. << "f(ia, " << -1 << ") should throw cv::Exception";
  1755. for (int i = 0; i < int(ia.size()); i++)
  1756. {
  1757. EXPECT_NO_THROW(f(ia, i))
  1758. << "f(ia, " << i << ") should not throw an exception";
  1759. }
  1760. EXPECT_THROW(f(ia, int(ia.size())), cv::Exception)
  1761. << "f(ia, " << ia.size() << ") should throw cv::Exception";
  1762. }
  1763. static void test_isContinuous()
  1764. {
  1765. auto f = [](cv::_InputArray ia, int i) { (void)ia.isContinuous(i); };
  1766. cv::Mat M;
  1767. cv::UMat uM;
  1768. std::vector<cv::Mat> vec = {M, M};
  1769. std::array<cv::Mat, 2> arr = {M, M};
  1770. std::vector<cv::UMat> uvec = {uM, uM};
  1771. testA(vec, f, "isContinuous");
  1772. testA(arr, f, "isContinuous");
  1773. testA(uvec, f, "isContinuous");
  1774. }
  1775. static void test_isSubmatrix()
  1776. {
  1777. auto f = [](cv::_InputArray ia, int i) { (void)ia.isSubmatrix(i); };
  1778. cv::Mat M;
  1779. cv::UMat uM;
  1780. std::vector<cv::Mat> vec = {M, M};
  1781. std::array<cv::Mat, 2> arr = {M, M};
  1782. std::vector<cv::UMat> uvec = {uM, uM};
  1783. testA(vec, f, "isSubmatrix");
  1784. testA(arr, f, "isSubmatrix");
  1785. testA(uvec, f, "isSubmatrix");
  1786. }
  1787. static void test_offset()
  1788. {
  1789. auto f = [](cv::_InputArray ia, int i) { return ia.offset(i); };
  1790. cv::Mat M;
  1791. cv::UMat uM;
  1792. cv::cuda::GpuMat gM;
  1793. std::vector<cv::Mat> vec = {M, M};
  1794. std::array<cv::Mat, 2> arr = {M, M};
  1795. std::vector<cv::UMat> uvec = {uM, uM};
  1796. std::vector<cv::cuda::GpuMat> gvec = {gM, gM};
  1797. testB(vec, f, "offset");
  1798. testB(arr, f, "offset");
  1799. testB(uvec, f, "offset");
  1800. testB(gvec, f, "offset");
  1801. }
  1802. static void test_step()
  1803. {
  1804. auto f = [](cv::_InputArray ia, int i) { return ia.step(i); };
  1805. cv::Mat M;
  1806. cv::UMat uM;
  1807. cv::cuda::GpuMat gM;
  1808. std::vector<cv::Mat> vec = {M, M};
  1809. std::array<cv::Mat, 2> arr = {M, M};
  1810. std::vector<cv::UMat> uvec = {uM, uM};
  1811. std::vector<cv::cuda::GpuMat> gvec = {gM, gM};
  1812. testB(vec, f, "step");
  1813. testB(arr, f, "step");
  1814. testB(uvec, f, "step");
  1815. testB(gvec, f, "step");
  1816. }
  1817. public:
  1818. static void run()
  1819. {
  1820. test_isContinuous();
  1821. test_isSubmatrix();
  1822. test_offset();
  1823. test_step();
  1824. }
  1825. };
  1826. TEST(Core_InputArray, range_checking)
  1827. {
  1828. TestInputArrayRangeChecking::run();
  1829. }
  1830. #endif
  1831. TEST(Core_Vectors, issue_13078)
  1832. {
  1833. float floats_[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
  1834. std::vector<float> floats(floats_, floats_ + 8);
  1835. std::vector<int> ints(4);
  1836. Mat m(4, 1, CV_32FC1, floats.data(), sizeof(floats[0]) * 2);
  1837. m.convertTo(ints, CV_32S);
  1838. ASSERT_EQ(1, ints[0]);
  1839. ASSERT_EQ(3, ints[1]);
  1840. ASSERT_EQ(5, ints[2]);
  1841. ASSERT_EQ(7, ints[3]);
  1842. }
  1843. TEST(Core_Vectors, issue_13078_workaround)
  1844. {
  1845. float floats_[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
  1846. std::vector<float> floats(floats_, floats_ + 8);
  1847. std::vector<int> ints(4);
  1848. Mat m(4, 1, CV_32FC1, floats.data(), sizeof(floats[0]) * 2);
  1849. m.convertTo(Mat(ints), CV_32S);
  1850. ASSERT_EQ(1, ints[0]);
  1851. ASSERT_EQ(3, ints[1]);
  1852. ASSERT_EQ(5, ints[2]);
  1853. ASSERT_EQ(7, ints[3]);
  1854. }
  1855. TEST(Core_MatExpr, issue_13926)
  1856. {
  1857. Mat M1 = (Mat_<double>(4,4,CV_64FC1) << 1, 2, 3, 4,
  1858. 5, 6, 7, 8,
  1859. 9, 10, 11, 12,
  1860. 13, 14, 15, 16);
  1861. Matx44d M2(1, 2, 3, 4,
  1862. 5, 6, 7, 8,
  1863. 9, 10, 11, 12,
  1864. 13, 14, 15, 16);
  1865. EXPECT_GE(1e-6, cvtest::norm(M1*M2, M1*M1, NORM_INF)) << Mat(M1*M2) << std::endl << Mat(M1*M1);
  1866. EXPECT_GE(1e-6, cvtest::norm(M2*M1, M2*M2, NORM_INF)) << Mat(M2*M1) << std::endl << Mat(M2*M2);
  1867. }
  1868. TEST(Core_MatExpr, issue_16655)
  1869. {
  1870. Mat a(Size(5, 5), CV_32FC3, Scalar::all(1));
  1871. Mat b(Size(5, 5), CV_32FC3, Scalar::all(2));
  1872. MatExpr ab_expr = a != b;
  1873. Mat ab_mat = ab_expr;
  1874. EXPECT_EQ(CV_8UC3, ab_expr.type())
  1875. << "MatExpr: CV_8UC3 != " << typeToString(ab_expr.type());
  1876. EXPECT_EQ(CV_8UC3, ab_mat.type())
  1877. << "Mat: CV_8UC3 != " << typeToString(ab_mat.type());
  1878. }
  1879. TEST(Core_MatExpr, issue_16689)
  1880. {
  1881. Mat a(Size(10, 5), CV_32FC1, 5);
  1882. Mat b(Size(10, 5), CV_32FC1, 2);
  1883. Mat bt(Size(5, 10), CV_32FC1, 3);
  1884. {
  1885. MatExpr r = a * bt; // gemm
  1886. EXPECT_EQ(Mat(r).size(), r.size()) << "[10x5] x [5x10] => [5x5]";
  1887. }
  1888. {
  1889. MatExpr r = a * b.t(); // gemm
  1890. EXPECT_EQ(Mat(r).size(), r.size()) << "[10x5] x [10x5].t() => [5x5]";
  1891. }
  1892. {
  1893. MatExpr r = a.t() * b; // gemm
  1894. EXPECT_EQ(Mat(r).size(), r.size()) << "[10x5].t() x [10x5] => [10x10]";
  1895. }
  1896. {
  1897. MatExpr r = a.t() * bt.t(); // gemm
  1898. EXPECT_EQ(Mat(r).size(), r.size()) << "[10x5].t() x [5x10].t() => [10x10]";
  1899. }
  1900. }
  1901. #ifdef HAVE_EIGEN
  1902. TEST(Core_Eigen, eigen2cv_check_Mat_type)
  1903. {
  1904. Mat A(4, 4, CV_32FC1, Scalar::all(0));
  1905. Eigen::MatrixXf eigen_A;
  1906. cv2eigen(A, eigen_A);
  1907. Mat_<float> f_mat;
  1908. EXPECT_NO_THROW(eigen2cv(eigen_A, f_mat));
  1909. EXPECT_EQ(CV_32FC1, f_mat.type());
  1910. Mat_<double> d_mat;
  1911. EXPECT_ANY_THROW(eigen2cv(eigen_A, d_mat));
  1912. //EXPECT_EQ(CV_64FC1, d_mat.type());
  1913. }
  1914. #endif // HAVE_EIGEN
  1915. #ifdef OPENCV_EIGEN_TENSOR_SUPPORT
  1916. TEST(Core_Eigen, cv2eigen_check_tensor_conversion)
  1917. {
  1918. Mat A(2, 3, CV_32FC3);
  1919. float value = 0;
  1920. for(int row=0; row<A.rows; row++)
  1921. for(int col=0; col<A.cols; col++)
  1922. for(int ch=0; ch<A.channels(); ch++)
  1923. A.at<Vec3f>(row,col)[ch] = value++;
  1924. Eigen::Tensor<float, 3, Eigen::RowMajor> row_tensor;
  1925. cv2eigen(A, row_tensor);
  1926. float* mat_ptr = (float*)A.data;
  1927. float* tensor_ptr = row_tensor.data();
  1928. for (int i=0; i< row_tensor.size(); i++)
  1929. ASSERT_FLOAT_EQ(mat_ptr[i], tensor_ptr[i]);
  1930. Eigen::Tensor<float, 3, Eigen::ColMajor> col_tensor;
  1931. cv2eigen(A, col_tensor);
  1932. value = 0;
  1933. for(int row=0; row<A.rows; row++)
  1934. for(int col=0; col<A.cols; col++)
  1935. for(int ch=0; ch<A.channels(); ch++)
  1936. ASSERT_FLOAT_EQ(value++, col_tensor(row,col,ch));
  1937. }
  1938. #endif // OPENCV_EIGEN_TENSOR_SUPPORT
  1939. #ifdef OPENCV_EIGEN_TENSOR_SUPPORT
  1940. TEST(Core_Eigen, eigen2cv_check_tensor_conversion)
  1941. {
  1942. Eigen::Tensor<float, 3, Eigen::RowMajor> row_tensor(2,3,3);
  1943. Eigen::Tensor<float, 3, Eigen::ColMajor> col_tensor(2,3,3);
  1944. float value = 0;
  1945. for(int row=0; row<row_tensor.dimension(0); row++)
  1946. for(int col=0; col<row_tensor.dimension(1); col++)
  1947. for(int ch=0; ch<row_tensor.dimension(2); ch++)
  1948. {
  1949. row_tensor(row,col,ch) = value;
  1950. col_tensor(row,col,ch) = value;
  1951. value++;
  1952. }
  1953. Mat A;
  1954. eigen2cv(row_tensor, A);
  1955. float* tensor_ptr = row_tensor.data();
  1956. float* mat_ptr = (float*)A.data;
  1957. for (int i=0; i< row_tensor.size(); i++)
  1958. ASSERT_FLOAT_EQ(tensor_ptr[i], mat_ptr[i]);
  1959. Mat B;
  1960. eigen2cv(col_tensor, B);
  1961. value = 0;
  1962. for(int row=0; row<B.rows; row++)
  1963. for(int col=0; col<B.cols; col++)
  1964. for(int ch=0; ch<B.channels(); ch++)
  1965. ASSERT_FLOAT_EQ(value++, B.at<Vec3f>(row,col)[ch]);
  1966. }
  1967. #endif // OPENCV_EIGEN_TENSOR_SUPPORT
  1968. #ifdef OPENCV_EIGEN_TENSOR_SUPPORT
  1969. TEST(Core_Eigen, cv2eigen_tensormap_check_tensormap_access)
  1970. {
  1971. float arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
  1972. Mat a_mat(2, 2, CV_32FC3, arr);
  1973. Eigen::TensorMap<Eigen::Tensor<float, 3, Eigen::RowMajor>> a_tensor = cv2eigen_tensormap<float>(a_mat);
  1974. for(int i=0; i<a_mat.rows; i++) {
  1975. for (int j=0; j<a_mat.cols; j++) {
  1976. for (int ch=0; ch<a_mat.channels(); ch++) {
  1977. ASSERT_FLOAT_EQ(a_mat.at<Vec3f>(i,j)[ch], a_tensor(i,j,ch));
  1978. ASSERT_EQ(&a_mat.at<Vec3f>(i,j)[ch], &a_tensor(i,j,ch));
  1979. }
  1980. }
  1981. }
  1982. }
  1983. #endif // OPENCV_EIGEN_TENSOR_SUPPORT
  1984. TEST(Mat, regression_12943) // memory usage: ~4.5 Gb
  1985. {
  1986. applyTestTag(CV_TEST_TAG_MEMORY_6GB);
  1987. const int width = 0x8000;
  1988. const int height = 0x10001;
  1989. cv::Mat src(height, width, CV_8UC1, Scalar::all(128));
  1990. cv::Mat dst;
  1991. cv::flip(src, dst, 0);
  1992. }
  1993. TEST(Mat, empty_iterator_16855)
  1994. {
  1995. cv::Mat m;
  1996. EXPECT_NO_THROW(m.begin<uchar>());
  1997. EXPECT_NO_THROW(m.end<uchar>());
  1998. EXPECT_TRUE(m.begin<uchar>() == m.end<uchar>());
  1999. }
  2000. TEST(Mat, regression_18473)
  2001. {
  2002. std::vector<int> sizes(3);
  2003. sizes[0] = 20;
  2004. sizes[1] = 50;
  2005. sizes[2] = 100;
  2006. #if 1 // with the fix
  2007. std::vector<size_t> steps(2);
  2008. steps[0] = 50*100*2;
  2009. steps[1] = 100*2;
  2010. #else // without the fix
  2011. std::vector<size_t> steps(3);
  2012. steps[0] = 50*100*2;
  2013. steps[1] = 100*2;
  2014. steps[2] = 2;
  2015. #endif
  2016. std::vector<short> data(20*50*100, 0); // 1Mb
  2017. data[data.size() - 1] = 5;
  2018. // param steps Array of ndims-1 steps
  2019. Mat m(sizes, CV_16SC1, (void*)data.data(), (const size_t*)steps.data());
  2020. ASSERT_FALSE(m.empty());
  2021. EXPECT_EQ((int)5, (int)m.at<short>(19, 49, 99));
  2022. }
  2023. TEST(Mat, ptrVecni_20044)
  2024. {
  2025. Mat_<int> m(3,4); m << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12;
  2026. Vec2i idx(1,1);
  2027. uchar *u = m.ptr(idx);
  2028. EXPECT_EQ(int(6), *(int*)(u));
  2029. const uchar *cu = m.ptr(idx);
  2030. EXPECT_EQ(int(6), *(int*)(cu));
  2031. int *i = m.ptr<int>(idx);
  2032. EXPECT_EQ(int(6), *(i));
  2033. const int *ci = m.ptr<int>(idx);
  2034. EXPECT_EQ(int(6), *(ci));
  2035. }
  2036. TEST(Mat, reverse_iterator_19967)
  2037. {
  2038. // empty iterator (#16855)
  2039. cv::Mat m_empty;
  2040. EXPECT_NO_THROW(m_empty.rbegin<uchar>());
  2041. EXPECT_NO_THROW(m_empty.rend<uchar>());
  2042. EXPECT_TRUE(m_empty.rbegin<uchar>() == m_empty.rend<uchar>());
  2043. // 1D test
  2044. std::vector<uchar> data{0, 1, 2, 3};
  2045. const std::vector<int> sizes_1d{4};
  2046. //Base class
  2047. cv::Mat m_1d(sizes_1d, CV_8U, data.data());
  2048. auto mismatch_it_pair_1d = std::mismatch(data.rbegin(), data.rend(), m_1d.rbegin<uchar>());
  2049. EXPECT_EQ(mismatch_it_pair_1d.first, data.rend()); // expect no mismatch
  2050. EXPECT_EQ(mismatch_it_pair_1d.second, m_1d.rend<uchar>());
  2051. //Templated derived class
  2052. cv::Mat_<uchar> m_1d_t(static_cast<int>(sizes_1d.size()), sizes_1d.data(), data.data());
  2053. auto mismatch_it_pair_1d_t = std::mismatch(data.rbegin(), data.rend(), m_1d_t.rbegin());
  2054. EXPECT_EQ(mismatch_it_pair_1d_t.first, data.rend()); // expect no mismatch
  2055. EXPECT_EQ(mismatch_it_pair_1d_t.second, m_1d_t.rend());
  2056. // 2D test
  2057. const std::vector<int> sizes_2d{2, 2};
  2058. //Base class
  2059. cv::Mat m_2d(sizes_2d, CV_8U, data.data());
  2060. auto mismatch_it_pair_2d = std::mismatch(data.rbegin(), data.rend(), m_2d.rbegin<uchar>());
  2061. EXPECT_EQ(mismatch_it_pair_2d.first, data.rend());
  2062. EXPECT_EQ(mismatch_it_pair_2d.second, m_2d.rend<uchar>());
  2063. //Templated derived class
  2064. cv::Mat_<uchar> m_2d_t(static_cast<int>(sizes_2d.size()),sizes_2d.data(), data.data());
  2065. auto mismatch_it_pair_2d_t = std::mismatch(data.rbegin(), data.rend(), m_2d_t.rbegin());
  2066. EXPECT_EQ(mismatch_it_pair_2d_t.first, data.rend());
  2067. EXPECT_EQ(mismatch_it_pair_2d_t.second, m_2d_t.rend());
  2068. // 3D test
  2069. std::vector<uchar> data_3d{0, 1, 2, 3, 4, 5, 6, 7};
  2070. const std::vector<int> sizes_3d{2, 2, 2};
  2071. //Base class
  2072. cv::Mat m_3d(sizes_3d, CV_8U, data_3d.data());
  2073. auto mismatch_it_pair_3d = std::mismatch(data_3d.rbegin(), data_3d.rend(), m_3d.rbegin<uchar>());
  2074. EXPECT_EQ(mismatch_it_pair_3d.first, data_3d.rend());
  2075. EXPECT_EQ(mismatch_it_pair_3d.second, m_3d.rend<uchar>());
  2076. //Templated derived class
  2077. cv::Mat_<uchar> m_3d_t(static_cast<int>(sizes_3d.size()),sizes_3d.data(), data_3d.data());
  2078. auto mismatch_it_pair_3d_t = std::mismatch(data_3d.rbegin(), data_3d.rend(), m_3d_t.rbegin());
  2079. EXPECT_EQ(mismatch_it_pair_3d_t.first, data_3d.rend());
  2080. EXPECT_EQ(mismatch_it_pair_3d_t.second, m_3d_t.rend());
  2081. // const test base class
  2082. const cv::Mat m_1d_const(sizes_1d, CV_8U, data.data());
  2083. auto mismatch_it_pair_1d_const = std::mismatch(data.rbegin(), data.rend(), m_1d_const.rbegin<uchar>());
  2084. EXPECT_EQ(mismatch_it_pair_1d_const.first, data.rend()); // expect no mismatch
  2085. EXPECT_EQ(mismatch_it_pair_1d_const.second, m_1d_const.rend<uchar>());
  2086. EXPECT_FALSE((std::is_assignable<decltype(m_1d_const.rend<uchar>()), uchar>::value)) << "Constness of const iterator violated.";
  2087. EXPECT_FALSE((std::is_assignable<decltype(m_1d_const.rbegin<uchar>()), uchar>::value)) << "Constness of const iterator violated.";
  2088. // const test templated dervied class
  2089. const cv::Mat_<uchar> m_1d_const_t(static_cast<int>(sizes_1d.size()), sizes_1d.data(), data.data());
  2090. auto mismatch_it_pair_1d_const_t = std::mismatch(data.rbegin(), data.rend(), m_1d_const_t.rbegin());
  2091. EXPECT_EQ(mismatch_it_pair_1d_const_t.first, data.rend()); // expect no mismatch
  2092. EXPECT_EQ(mismatch_it_pair_1d_const_t.second, m_1d_const_t.rend());
  2093. EXPECT_FALSE((std::is_assignable<decltype(m_1d_const_t.rend()), uchar>::value)) << "Constness of const iterator violated.";
  2094. EXPECT_FALSE((std::is_assignable<decltype(m_1d_const_t.rbegin()), uchar>::value)) << "Constness of const iterator violated.";
  2095. }
  2096. }} // namespace