test_mat.cpp 87 KB

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