test_imgwarp.cpp 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804
  1. /*M///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
  4. //
  5. // By downloading, copying, installing or using the software you agree to this license.
  6. // If you do not agree to this license, do not download, install,
  7. // copy or use the software.
  8. //
  9. //
  10. // Intel License Agreement
  11. // For Open Source Computer Vision Library
  12. //
  13. // Copyright (C) 2000, Intel Corporation, all rights reserved.
  14. // Third party copyrights are property of their respective owners.
  15. //
  16. // Redistribution and use in source and binary forms, with or without modification,
  17. // are permitted provided that the following conditions are met:
  18. //
  19. // * Redistribution's of source code must retain the above copyright notice,
  20. // this list of conditions and the following disclaimer.
  21. //
  22. // * Redistribution's in binary form must reproduce the above copyright notice,
  23. // this list of conditions and the following disclaimer in the documentation
  24. // and/or other materials provided with the distribution.
  25. //
  26. // * The name of Intel Corporation may not be used to endorse or promote products
  27. // derived from this software without specific prior written permission.
  28. //
  29. // This software is provided by the copyright holders and contributors "as is" and
  30. // any express or implied warranties, including, but not limited to, the implied
  31. // warranties of merchantability and fitness for a particular purpose are disclaimed.
  32. // In no event shall the Intel Corporation or contributors be liable for any direct,
  33. // indirect, incidental, special, exemplary, or consequential damages
  34. // (including, but not limited to, procurement of substitute goods or services;
  35. // loss of use, data, or profits; or business interruption) however caused
  36. // and on any theory of liability, whether in contract, strict liability,
  37. // or tort (including negligence or otherwise) arising in any way out of
  38. // the use of this software, even if advised of the possibility of such damage.
  39. //
  40. //M*/
  41. #include "opencv2/ts/ocl_test.hpp"
  42. #include "opencv2/ts/ts_gtest.h"
  43. #include "test_precomp.hpp"
  44. namespace opencv_test { namespace {
  45. class CV_ImgWarpBaseTest : public cvtest::ArrayTest
  46. {
  47. public:
  48. CV_ImgWarpBaseTest( bool warp_matrix );
  49. protected:
  50. int read_params( const cv::FileStorage& fs );
  51. int prepare_test_case( int test_case_idx );
  52. void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  53. void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
  54. void fill_array( int test_case_idx, int i, int j, Mat& arr );
  55. int interpolation;
  56. int max_interpolation;
  57. double spatial_scale_zoom, spatial_scale_decimate;
  58. };
  59. CV_ImgWarpBaseTest::CV_ImgWarpBaseTest( bool warp_matrix )
  60. {
  61. test_array[INPUT].push_back(NULL);
  62. if( warp_matrix )
  63. test_array[INPUT].push_back(NULL);
  64. test_array[INPUT_OUTPUT].push_back(NULL);
  65. test_array[REF_INPUT_OUTPUT].push_back(NULL);
  66. max_interpolation = 5;
  67. interpolation = 0;
  68. element_wise_relative_error = false;
  69. spatial_scale_zoom = 0.01;
  70. spatial_scale_decimate = 0.005;
  71. }
  72. int CV_ImgWarpBaseTest::read_params( const cv::FileStorage& fs )
  73. {
  74. int code = cvtest::ArrayTest::read_params( fs );
  75. return code;
  76. }
  77. void CV_ImgWarpBaseTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high )
  78. {
  79. cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high );
  80. if( CV_MAT_DEPTH(type) == CV_32F )
  81. {
  82. low = Scalar::all(-10.);
  83. high = Scalar::all(10);
  84. }
  85. }
  86. void CV_ImgWarpBaseTest::get_test_array_types_and_sizes( int test_case_idx,
  87. vector<vector<Size> >& sizes, vector<vector<int> >& types )
  88. {
  89. RNG& rng = ts->get_rng();
  90. int depth = cvtest::randInt(rng) % 3;
  91. int cn = cvtest::randInt(rng) % 3 + 1;
  92. cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
  93. depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : CV_32F;
  94. types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(depth, cn);
  95. if( test_array[INPUT].size() > 1 )
  96. types[INPUT][1] = cvtest::randInt(rng) & 1 ? CV_32FC1 : CV_64FC1;
  97. interpolation = cvtest::randInt(rng) % max_interpolation;
  98. }
  99. void CV_ImgWarpBaseTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
  100. {
  101. if( i != INPUT || j != 0 )
  102. cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
  103. }
  104. int CV_ImgWarpBaseTest::prepare_test_case( int test_case_idx )
  105. {
  106. int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
  107. Mat& img = test_mat[INPUT][0];
  108. int i, j, cols = img.cols;
  109. int type = img.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
  110. double scale = depth == CV_16U ? 1000. : 255.*0.5;
  111. double space_scale = spatial_scale_decimate;
  112. vector<float> buffer(img.cols*cn);
  113. if( code <= 0 )
  114. return code;
  115. if( test_mat[INPUT_OUTPUT][0].cols >= img.cols &&
  116. test_mat[INPUT_OUTPUT][0].rows >= img.rows )
  117. space_scale = spatial_scale_zoom;
  118. for( i = 0; i < img.rows; i++ )
  119. {
  120. uchar* ptr = img.ptr(i);
  121. switch( cn )
  122. {
  123. case 1:
  124. for( j = 0; j < cols; j++ )
  125. buffer[j] = (float)((sin((i+1)*space_scale)*sin((j+1)*space_scale)+1.)*scale);
  126. break;
  127. case 2:
  128. for( j = 0; j < cols; j++ )
  129. {
  130. buffer[j*2] = (float)((sin((i+1)*space_scale)+1.)*scale);
  131. buffer[j*2+1] = (float)((sin((i+j)*space_scale)+1.)*scale);
  132. }
  133. break;
  134. case 3:
  135. for( j = 0; j < cols; j++ )
  136. {
  137. buffer[j*3] = (float)((sin((i+1)*space_scale)+1.)*scale);
  138. buffer[j*3+1] = (float)((sin(j*space_scale)+1.)*scale);
  139. buffer[j*3+2] = (float)((sin((i+j)*space_scale)+1.)*scale);
  140. }
  141. break;
  142. case 4:
  143. for( j = 0; j < cols; j++ )
  144. {
  145. buffer[j*4] = (float)((sin((i+1)*space_scale)+1.)*scale);
  146. buffer[j*4+1] = (float)((sin(j*space_scale)+1.)*scale);
  147. buffer[j*4+2] = (float)((sin((i+j)*space_scale)+1.)*scale);
  148. buffer[j*4+3] = (float)((sin((i-j)*space_scale)+1.)*scale);
  149. }
  150. break;
  151. default:
  152. CV_Assert(0);
  153. }
  154. /*switch( depth )
  155. {
  156. case CV_8U:
  157. for( j = 0; j < cols*cn; j++ )
  158. ptr[j] = (uchar)cvRound(buffer[j]);
  159. break;
  160. case CV_16U:
  161. for( j = 0; j < cols*cn; j++ )
  162. ((ushort*)ptr)[j] = (ushort)cvRound(buffer[j]);
  163. break;
  164. case CV_32F:
  165. for( j = 0; j < cols*cn; j++ )
  166. ((float*)ptr)[j] = (float)buffer[j];
  167. break;
  168. default:
  169. CV_Assert(0);
  170. }*/
  171. cv::Mat src(1, cols*cn, CV_32F, &buffer[0]);
  172. cv::Mat dst(1, cols*cn, depth, ptr);
  173. src.convertTo(dst, dst.type());
  174. }
  175. return code;
  176. }
  177. /////////////////////////
  178. class CV_ResizeTest : public CV_ImgWarpBaseTest
  179. {
  180. public:
  181. CV_ResizeTest();
  182. protected:
  183. void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  184. void run_func();
  185. void prepare_to_validation( int /*test_case_idx*/ );
  186. double get_success_error_level( int test_case_idx, int i, int j );
  187. };
  188. CV_ResizeTest::CV_ResizeTest() : CV_ImgWarpBaseTest( false )
  189. {
  190. }
  191. void CV_ResizeTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
  192. {
  193. RNG& rng = ts->get_rng();
  194. CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
  195. Size sz;
  196. sz.width = (cvtest::randInt(rng) % sizes[INPUT][0].width) + 1;
  197. sz.height = (cvtest::randInt(rng) % sizes[INPUT][0].height) + 1;
  198. if( cvtest::randInt(rng) & 1 )
  199. {
  200. int xfactor = cvtest::randInt(rng) % 10 + 1;
  201. int yfactor = cvtest::randInt(rng) % 10 + 1;
  202. if( cvtest::randInt(rng) & 1 )
  203. yfactor = xfactor;
  204. sz.width = sizes[INPUT][0].width / xfactor;
  205. sz.width = MAX(sz.width,1);
  206. sz.height = sizes[INPUT][0].height / yfactor;
  207. sz.height = MAX(sz.height,1);
  208. sizes[INPUT][0].width = sz.width * xfactor;
  209. sizes[INPUT][0].height = sz.height * yfactor;
  210. }
  211. if( cvtest::randInt(rng) & 1 )
  212. sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = sz;
  213. else
  214. {
  215. sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = sizes[INPUT][0];
  216. sizes[INPUT][0] = sz;
  217. }
  218. if( interpolation == 4 &&
  219. (MIN(sizes[INPUT][0].width,sizes[INPUT_OUTPUT][0].width) < 4 ||
  220. MIN(sizes[INPUT][0].height,sizes[INPUT_OUTPUT][0].height) < 4))
  221. interpolation = 2;
  222. }
  223. void CV_ResizeTest::run_func()
  224. {
  225. cvResize( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], interpolation );
  226. }
  227. double CV_ResizeTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
  228. {
  229. int depth = test_mat[INPUT][0].depth();
  230. return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 1e-1;
  231. }
  232. void CV_ResizeTest::prepare_to_validation( int /*test_case_idx*/ )
  233. {
  234. CvMat _src = cvMat(test_mat[INPUT][0]), _dst = cvMat(test_mat[REF_INPUT_OUTPUT][0]);
  235. CvMat *src = &_src, *dst = &_dst;
  236. int i, j, k;
  237. CvMat* x_idx = cvCreateMat( 1, dst->cols, CV_32SC1 );
  238. CvMat* y_idx = cvCreateMat( 1, dst->rows, CV_32SC1 );
  239. int* x_tab = x_idx->data.i;
  240. int elem_size = CV_ELEM_SIZE(src->type);
  241. int drows = dst->rows, dcols = dst->cols;
  242. if( interpolation == cv::INTER_NEAREST )
  243. {
  244. for( j = 0; j < dcols; j++ )
  245. {
  246. int t = (j*src->cols*2 + MIN(src->cols,dcols) - 1)/(dcols*2);
  247. t -= t >= src->cols;
  248. x_idx->data.i[j] = t*elem_size;
  249. }
  250. for( j = 0; j < drows; j++ )
  251. {
  252. int t = (j*src->rows*2 + MIN(src->rows,drows) - 1)/(drows*2);
  253. t -= t >= src->rows;
  254. y_idx->data.i[j] = t;
  255. }
  256. }
  257. else
  258. {
  259. double scale_x = (double)src->cols/dcols;
  260. double scale_y = (double)src->rows/drows;
  261. for( j = 0; j < dcols; j++ )
  262. {
  263. double f = ((j+0.5)*scale_x - 0.5);
  264. i = cvRound(f);
  265. x_idx->data.i[j] = (i < 0 ? 0 : i >= src->cols ? src->cols - 1 : i)*elem_size;
  266. }
  267. for( j = 0; j < drows; j++ )
  268. {
  269. double f = ((j+0.5)*scale_y - 0.5);
  270. i = cvRound(f);
  271. y_idx->data.i[j] = i < 0 ? 0 : i >= src->rows ? src->rows - 1 : i;
  272. }
  273. }
  274. for( i = 0; i < drows; i++ )
  275. {
  276. uchar* dptr = dst->data.ptr + dst->step*i;
  277. const uchar* sptr0 = src->data.ptr + src->step*y_idx->data.i[i];
  278. for( j = 0; j < dcols; j++, dptr += elem_size )
  279. {
  280. const uchar* sptr = sptr0 + x_tab[j];
  281. for( k = 0; k < elem_size; k++ )
  282. dptr[k] = sptr[k];
  283. }
  284. }
  285. cvReleaseMat( &x_idx );
  286. cvReleaseMat( &y_idx );
  287. }
  288. class CV_ResizeExactTest : public CV_ResizeTest
  289. {
  290. public:
  291. CV_ResizeExactTest();
  292. protected:
  293. void get_test_array_types_and_sizes(int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types);
  294. };
  295. CV_ResizeExactTest::CV_ResizeExactTest() : CV_ResizeTest()
  296. {
  297. max_interpolation = 2;
  298. }
  299. void CV_ResizeExactTest::get_test_array_types_and_sizes(int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types)
  300. {
  301. CV_ResizeTest::get_test_array_types_and_sizes(test_case_idx, sizes, types);
  302. switch (interpolation)
  303. {
  304. case 0:
  305. interpolation = INTER_LINEAR_EXACT;
  306. break;
  307. case 1:
  308. interpolation = INTER_NEAREST_EXACT;
  309. break;
  310. default:
  311. CV_Assert(interpolation < max_interpolation);
  312. }
  313. if (CV_MAT_DEPTH(types[INPUT][0]) == CV_32F ||
  314. CV_MAT_DEPTH(types[INPUT][0]) == CV_64F)
  315. types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(CV_8U, CV_MAT_CN(types[INPUT][0]));
  316. }
  317. /////////////////////////
  318. static void test_remap( const Mat& src, Mat& dst, const Mat& mapx, const Mat& mapy,
  319. Mat* mask=0, int interpolation=cv::INTER_LINEAR )
  320. {
  321. int x, y, k;
  322. int drows = dst.rows, dcols = dst.cols;
  323. int srows = src.rows, scols = src.cols;
  324. const uchar* sptr0 = src.ptr();
  325. int depth = src.depth(), cn = src.channels();
  326. int elem_size = (int)src.elemSize();
  327. int step = (int)(src.step / CV_ELEM_SIZE(depth));
  328. int delta;
  329. if( interpolation != cv::INTER_CUBIC )
  330. {
  331. delta = 0;
  332. scols -= 1; srows -= 1;
  333. }
  334. else
  335. {
  336. delta = 1;
  337. scols = MAX(scols - 3, 0);
  338. srows = MAX(srows - 3, 0);
  339. }
  340. int scols1 = MAX(scols - 2, 0);
  341. int srows1 = MAX(srows - 2, 0);
  342. if( mask )
  343. *mask = Scalar::all(0);
  344. for( y = 0; y < drows; y++ )
  345. {
  346. uchar* dptr = dst.ptr(y);
  347. const float* mx = mapx.ptr<float>(y);
  348. const float* my = mapy.ptr<float>(y);
  349. uchar* m = mask ? mask->ptr(y) : 0;
  350. for( x = 0; x < dcols; x++, dptr += elem_size )
  351. {
  352. float xs = mx[x];
  353. float ys = my[x];
  354. int ixs = cvFloor(xs);
  355. int iys = cvFloor(ys);
  356. if( (unsigned)(ixs - delta - 1) >= (unsigned)scols1 ||
  357. (unsigned)(iys - delta - 1) >= (unsigned)srows1 )
  358. {
  359. if( m )
  360. m[x] = 1;
  361. if( (unsigned)(ixs - delta) >= (unsigned)scols ||
  362. (unsigned)(iys - delta) >= (unsigned)srows )
  363. continue;
  364. }
  365. xs -= ixs;
  366. ys -= iys;
  367. switch( depth )
  368. {
  369. case CV_8U:
  370. {
  371. const uchar* sptr = sptr0 + iys*step + ixs*cn;
  372. for( k = 0; k < cn; k++ )
  373. {
  374. float v00 = sptr[k];
  375. float v01 = sptr[cn + k];
  376. float v10 = sptr[step + k];
  377. float v11 = sptr[step + cn + k];
  378. v00 = v00 + xs*(v01 - v00);
  379. v10 = v10 + xs*(v11 - v10);
  380. v00 = v00 + ys*(v10 - v00);
  381. dptr[k] = (uchar)cvRound(v00);
  382. }
  383. }
  384. break;
  385. case CV_16U:
  386. {
  387. const ushort* sptr = (const ushort*)sptr0 + iys*step + ixs*cn;
  388. for( k = 0; k < cn; k++ )
  389. {
  390. float v00 = sptr[k];
  391. float v01 = sptr[cn + k];
  392. float v10 = sptr[step + k];
  393. float v11 = sptr[step + cn + k];
  394. v00 = v00 + xs*(v01 - v00);
  395. v10 = v10 + xs*(v11 - v10);
  396. v00 = v00 + ys*(v10 - v00);
  397. ((ushort*)dptr)[k] = (ushort)cvRound(v00);
  398. }
  399. }
  400. break;
  401. case CV_32F:
  402. {
  403. const float* sptr = (const float*)sptr0 + iys*step + ixs*cn;
  404. for( k = 0; k < cn; k++ )
  405. {
  406. float v00 = sptr[k];
  407. float v01 = sptr[cn + k];
  408. float v10 = sptr[step + k];
  409. float v11 = sptr[step + cn + k];
  410. v00 = v00 + xs*(v01 - v00);
  411. v10 = v10 + xs*(v11 - v10);
  412. v00 = v00 + ys*(v10 - v00);
  413. ((float*)dptr)[k] = (float)v00;
  414. }
  415. }
  416. break;
  417. default:
  418. CV_Assert(0);
  419. }
  420. }
  421. }
  422. }
  423. /////////////////////////
  424. class CV_WarpAffineTest : public CV_ImgWarpBaseTest
  425. {
  426. public:
  427. CV_WarpAffineTest();
  428. protected:
  429. void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  430. void run_func();
  431. int prepare_test_case( int test_case_idx );
  432. void prepare_to_validation( int /*test_case_idx*/ );
  433. double get_success_error_level( int test_case_idx, int i, int j );
  434. };
  435. CV_WarpAffineTest::CV_WarpAffineTest() : CV_ImgWarpBaseTest( true )
  436. {
  437. //spatial_scale_zoom = spatial_scale_decimate;
  438. spatial_scale_decimate = spatial_scale_zoom;
  439. }
  440. void CV_WarpAffineTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
  441. {
  442. CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
  443. Size sz = sizes[INPUT][0];
  444. // run for the second time to get output of a different size
  445. CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
  446. sizes[INPUT][0] = sz;
  447. sizes[INPUT][1] = Size( 3, 2 );
  448. }
  449. void CV_WarpAffineTest::run_func()
  450. {
  451. CvMat mtx = cvMat(test_mat[INPUT][1]);
  452. cvWarpAffine( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &mtx, interpolation );
  453. }
  454. double CV_WarpAffineTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
  455. {
  456. int depth = test_mat[INPUT][0].depth();
  457. return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2;
  458. }
  459. int CV_WarpAffineTest::prepare_test_case( int test_case_idx )
  460. {
  461. RNG& rng = ts->get_rng();
  462. int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
  463. const Mat& src = test_mat[INPUT][0];
  464. const Mat& dst = test_mat[INPUT_OUTPUT][0];
  465. Mat& mat = test_mat[INPUT][1];
  466. Point2f center;
  467. double scale, angle;
  468. if( code <= 0 )
  469. return code;
  470. double buffer[6];
  471. Mat tmp( 2, 3, mat.type(), buffer );
  472. center.x = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.cols);
  473. center.y = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.rows);
  474. angle = cvtest::randReal(rng)*360;
  475. scale = ((double)dst.rows/src.rows + (double)dst.cols/src.cols)*0.5;
  476. getRotationMatrix2D(center, angle, scale).convertTo(mat, mat.depth());
  477. rng.fill( tmp, RNG::NORMAL, Scalar::all(1.), Scalar::all(0.01) );
  478. cv::max(tmp, 0.9, tmp);
  479. cv::min(tmp, 1.1, tmp);
  480. cv::multiply(tmp, mat, mat, 1.);
  481. return code;
  482. }
  483. void CV_WarpAffineTest::prepare_to_validation( int /*test_case_idx*/ )
  484. {
  485. const Mat& src = test_mat[INPUT][0];
  486. Mat& dst = test_mat[REF_INPUT_OUTPUT][0];
  487. Mat& dst0 = test_mat[INPUT_OUTPUT][0];
  488. Mat mapx(dst.size(), CV_32F), mapy(dst.size(), CV_32F);
  489. double m[6];
  490. Mat srcAb, dstAb( 2, 3, CV_64FC1, m );
  491. //cvInvert( &tM, &M, CV_LU );
  492. // [R|t] -> [R^-1 | -(R^-1)*t]
  493. test_mat[INPUT][1].convertTo( srcAb, CV_64F );
  494. Mat A = srcAb.colRange(0, 2);
  495. Mat b = srcAb.col(2);
  496. Mat invA = dstAb.colRange(0, 2);
  497. Mat invAb = dstAb.col(2);
  498. cv::invert(A, invA, CV_SVD);
  499. cv::gemm(invA, b, -1, Mat(), 0, invAb);
  500. for( int y = 0; y < dst.rows; y++ )
  501. for( int x = 0; x < dst.cols; x++ )
  502. {
  503. mapx.at<float>(y, x) = (float)(x*m[0] + y*m[1] + m[2]);
  504. mapy.at<float>(y, x) = (float)(x*m[3] + y*m[4] + m[5]);
  505. }
  506. Mat mask( dst.size(), CV_8U );
  507. test_remap( src, dst, mapx, mapy, &mask );
  508. dst.setTo(Scalar::all(0), mask);
  509. dst0.setTo(Scalar::all(0), mask);
  510. }
  511. /////////////////////////
  512. class CV_WarpPerspectiveTest : public CV_ImgWarpBaseTest
  513. {
  514. public:
  515. CV_WarpPerspectiveTest();
  516. protected:
  517. void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  518. void run_func();
  519. int prepare_test_case( int test_case_idx );
  520. void prepare_to_validation( int /*test_case_idx*/ );
  521. double get_success_error_level( int test_case_idx, int i, int j );
  522. int borderType;
  523. };
  524. CV_WarpPerspectiveTest::CV_WarpPerspectiveTest() : CV_ImgWarpBaseTest( true )
  525. {
  526. //spatial_scale_zoom = spatial_scale_decimate;
  527. spatial_scale_decimate = spatial_scale_zoom;
  528. }
  529. void CV_WarpPerspectiveTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
  530. {
  531. CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
  532. Size sz = sizes[INPUT][0];
  533. // run for the second time to get output of a different size
  534. CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
  535. sizes[INPUT][0] = sz;
  536. sizes[INPUT][1] = Size( 3, 3 );
  537. }
  538. void CV_WarpPerspectiveTest::run_func()
  539. {
  540. Mat& dst = test_mat[INPUT_OUTPUT][0];
  541. cv::warpPerspective(test_mat[INPUT][0], dst, test_mat[INPUT][1], dst.size(), interpolation, borderType, Scalar::all(0));
  542. }
  543. double CV_WarpPerspectiveTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
  544. {
  545. int depth = test_mat[INPUT][0].depth();
  546. return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 0.13;
  547. }
  548. int CV_WarpPerspectiveTest::prepare_test_case( int test_case_idx )
  549. {
  550. RNG& rng = ts->get_rng();
  551. // only these two borders are declared as supported
  552. borderType = rng() % 2 ? BORDER_REPLICATE : BORDER_CONSTANT;
  553. int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
  554. const CvMat src = cvMat(test_mat[INPUT][0]);
  555. const CvMat dst = cvMat(test_mat[INPUT_OUTPUT][0]);
  556. Mat& mat = test_mat[INPUT][1];
  557. Point2f s[4], d[4];
  558. int i;
  559. if( code <= 0 )
  560. return code;
  561. s[0] = Point2f(0,0);
  562. d[0] = Point2f(0,0);
  563. s[1] = Point2f(src.cols-1.f,0);
  564. d[1] = Point2f(dst.cols-1.f,0);
  565. s[2] = Point2f(src.cols-1.f,src.rows-1.f);
  566. d[2] = Point2f(dst.cols-1.f,dst.rows-1.f);
  567. s[3] = Point2f(0,src.rows-1.f);
  568. d[3] = Point2f(0,dst.rows-1.f);
  569. float bufer[16];
  570. Mat tmp( 1, 16, CV_32FC1, bufer );
  571. rng.fill( tmp, RNG::NORMAL, Scalar::all(0.), Scalar::all(0.1) );
  572. for( i = 0; i < 4; i++ )
  573. {
  574. s[i].x += bufer[i*4]*src.cols/2;
  575. s[i].y += bufer[i*4+1]*src.rows/2;
  576. d[i].x += bufer[i*4+2]*dst.cols/2;
  577. d[i].y += bufer[i*4+3]*dst.rows/2;
  578. }
  579. cv::getPerspectiveTransform( s, d ).convertTo( mat, mat.depth() );
  580. return code;
  581. }
  582. void CV_WarpPerspectiveTest::prepare_to_validation( int /*test_case_idx*/ )
  583. {
  584. Mat& src = test_mat[INPUT][0];
  585. Mat& dst = test_mat[REF_INPUT_OUTPUT][0];
  586. Mat& dst0 = test_mat[INPUT_OUTPUT][0];
  587. Mat mapx(dst.size(), CV_32F), mapy(dst.size(), CV_32F);
  588. double m[9];
  589. Mat srcM, dstM(3, 3, CV_64F, m);
  590. //cvInvert( &tM, &M, CV_LU );
  591. // [R|t] -> [R^-1 | -(R^-1)*t]
  592. test_mat[INPUT][1].convertTo( srcM, CV_64F );
  593. cv::invert(srcM, dstM, CV_SVD);
  594. for( int y = 0; y < dst.rows; y++ )
  595. {
  596. for( int x = 0; x < dst.cols; x++ )
  597. {
  598. double xs = x*m[0] + y*m[1] + m[2];
  599. double ys = x*m[3] + y*m[4] + m[5];
  600. double ds = x*m[6] + y*m[7] + m[8];
  601. ds = ds ? 1./ds : 0;
  602. xs *= ds;
  603. ys *= ds;
  604. mapx.at<float>(y, x) = (float)xs;
  605. mapy.at<float>(y, x) = (float)ys;
  606. }
  607. }
  608. Mat mask( dst.size(), CV_8U );
  609. test_remap( src, dst, mapx, mapy, &mask, interpolation);
  610. dst.setTo(Scalar::all(0), mask);
  611. dst0.setTo(Scalar::all(0), mask);
  612. }
  613. /////////////////////////
  614. class CV_RemapTest : public CV_ImgWarpBaseTest
  615. {
  616. public:
  617. CV_RemapTest();
  618. protected:
  619. void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  620. void run_func();
  621. int prepare_test_case( int test_case_idx );
  622. void prepare_to_validation( int /*test_case_idx*/ );
  623. double get_success_error_level( int test_case_idx, int i, int j );
  624. void fill_array( int test_case_idx, int i, int j, Mat& arr );
  625. };
  626. CV_RemapTest::CV_RemapTest() : CV_ImgWarpBaseTest( false )
  627. {
  628. //spatial_scale_zoom = spatial_scale_decimate;
  629. test_array[INPUT].push_back(NULL);
  630. test_array[INPUT].push_back(NULL);
  631. spatial_scale_decimate = spatial_scale_zoom;
  632. }
  633. void CV_RemapTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
  634. {
  635. CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
  636. types[INPUT][1] = types[INPUT][2] = CV_32FC1;
  637. interpolation = cv::INTER_LINEAR;
  638. }
  639. void CV_RemapTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
  640. {
  641. if( i != INPUT )
  642. CV_ImgWarpBaseTest::fill_array( test_case_idx, i, j, arr );
  643. }
  644. void CV_RemapTest::run_func()
  645. {
  646. cv::remap(test_mat[INPUT][0], test_mat[INPUT_OUTPUT][0],
  647. test_mat[INPUT][1], test_mat[INPUT][2], interpolation );
  648. }
  649. double CV_RemapTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
  650. {
  651. int depth = test_mat[INPUT][0].depth();
  652. return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2;
  653. }
  654. int CV_RemapTest::prepare_test_case( int test_case_idx )
  655. {
  656. RNG& rng = ts->get_rng();
  657. int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
  658. const Mat& src = test_mat[INPUT][0];
  659. double a[9] = {0,0,0,0,0,0,0,0,1}, k[4];
  660. Mat _a( 3, 3, CV_64F, a );
  661. Mat _k( 4, 1, CV_64F, k );
  662. double sz = MAX(src.rows, src.cols);
  663. if( code <= 0 )
  664. return code;
  665. double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;
  666. a[2] = (src.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
  667. a[5] = (src.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
  668. a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);
  669. a[4] = aspect_ratio*a[0];
  670. k[0] = cvtest::randReal(rng)*0.06 - 0.03;
  671. k[1] = cvtest::randReal(rng)*0.06 - 0.03;
  672. if( k[0]*k[1] > 0 )
  673. k[1] = -k[1];
  674. k[2] = cvtest::randReal(rng)*0.004 - 0.002;
  675. k[3] = cvtest::randReal(rng)*0.004 - 0.002;
  676. cvtest::initUndistortMap( _a, _k, Mat(), Mat(), test_mat[INPUT][1].size(), test_mat[INPUT][1], test_mat[INPUT][2], CV_32F );
  677. return code;
  678. }
  679. void CV_RemapTest::prepare_to_validation( int /*test_case_idx*/ )
  680. {
  681. Mat& dst = test_mat[REF_INPUT_OUTPUT][0];
  682. Mat& dst0 = test_mat[INPUT_OUTPUT][0];
  683. Mat mask( dst.size(), CV_8U );
  684. test_remap(test_mat[INPUT][0], dst, test_mat[INPUT][1],
  685. test_mat[INPUT][2], &mask, interpolation );
  686. dst.setTo(Scalar::all(0), mask);
  687. dst0.setTo(Scalar::all(0), mask);
  688. }
  689. ////////////////////////////// GetRectSubPix /////////////////////////////////
  690. static void
  691. test_getQuadrangeSubPix( const Mat& src, Mat& dst, double* a )
  692. {
  693. int sstep = (int)(src.step / sizeof(float));
  694. int scols = src.cols, srows = src.rows;
  695. CV_Assert( src.depth() == CV_32F && src.type() == dst.type() );
  696. int cn = dst.channels();
  697. for( int y = 0; y < dst.rows; y++ )
  698. for( int x = 0; x < dst.cols; x++ )
  699. {
  700. float* d = dst.ptr<float>(y) + x*cn;
  701. float sx = (float)(a[0]*x + a[1]*y + a[2]);
  702. float sy = (float)(a[3]*x + a[4]*y + a[5]);
  703. int ix = cvFloor(sx), iy = cvFloor(sy);
  704. int dx = cn, dy = sstep;
  705. const float* s;
  706. sx -= ix; sy -= iy;
  707. if( (unsigned)ix >= (unsigned)(scols-1) )
  708. ix = ix < 0 ? 0 : scols - 1, sx = 0, dx = 0;
  709. if( (unsigned)iy >= (unsigned)(srows-1) )
  710. iy = iy < 0 ? 0 : srows - 1, sy = 0, dy = 0;
  711. s = src.ptr<float>(iy) + ix*cn;
  712. for( int k = 0; k < cn; k++, s++ )
  713. {
  714. float t0 = s[0] + sx*(s[dx] - s[0]);
  715. float t1 = s[dy] + sx*(s[dy + dx] - s[dy]);
  716. d[k] = t0 + sy*(t1 - t0);
  717. }
  718. }
  719. }
  720. class CV_GetRectSubPixTest : public CV_ImgWarpBaseTest
  721. {
  722. public:
  723. CV_GetRectSubPixTest();
  724. protected:
  725. void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  726. void run_func();
  727. int prepare_test_case( int test_case_idx );
  728. void prepare_to_validation( int /*test_case_idx*/ );
  729. double get_success_error_level( int test_case_idx, int i, int j );
  730. void fill_array( int test_case_idx, int i, int j, Mat& arr );
  731. Point2f center;
  732. bool test_cpp;
  733. };
  734. CV_GetRectSubPixTest::CV_GetRectSubPixTest() : CV_ImgWarpBaseTest( false )
  735. {
  736. //spatial_scale_zoom = spatial_scale_decimate;
  737. spatial_scale_decimate = spatial_scale_zoom;
  738. test_cpp = false;
  739. }
  740. void CV_GetRectSubPixTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
  741. {
  742. RNG& rng = ts->get_rng();
  743. CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
  744. int src_depth = cvtest::randInt(rng) % 2, dst_depth;
  745. int cn = cvtest::randInt(rng) % 2 ? 3 : 1;
  746. Size src_size, dst_size;
  747. dst_depth = src_depth = src_depth == 0 ? CV_8U : CV_32F;
  748. if( src_depth < CV_32F && cvtest::randInt(rng) % 2 )
  749. dst_depth = CV_32F;
  750. types[INPUT][0] = CV_MAKETYPE(src_depth,cn);
  751. types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(dst_depth,cn);
  752. src_size = sizes[INPUT][0];
  753. dst_size.width = cvRound(sqrt(cvtest::randReal(rng)*src_size.width) + 1);
  754. dst_size.height = cvRound(sqrt(cvtest::randReal(rng)*src_size.height) + 1);
  755. dst_size.width = MIN(dst_size.width,src_size.width);
  756. dst_size.height = MIN(dst_size.width,src_size.height);
  757. sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = dst_size;
  758. center.x = (float)(cvtest::randReal(rng)*src_size.width);
  759. center.y = (float)(cvtest::randReal(rng)*src_size.height);
  760. interpolation = cv::INTER_LINEAR;
  761. test_cpp = (cvtest::randInt(rng) & 256) == 0;
  762. }
  763. void CV_GetRectSubPixTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
  764. {
  765. if( i != INPUT )
  766. CV_ImgWarpBaseTest::fill_array( test_case_idx, i, j, arr );
  767. }
  768. void CV_GetRectSubPixTest::run_func()
  769. {
  770. cv::Mat _out = test_mat[INPUT_OUTPUT][0];
  771. cv::getRectSubPix(test_mat[INPUT][0], _out.size(), center, _out, _out.type());
  772. }
  773. double CV_GetRectSubPixTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
  774. {
  775. int in_depth = test_mat[INPUT][0].depth();
  776. int out_depth = test_mat[INPUT_OUTPUT][0].depth();
  777. return in_depth >= CV_32F ? 1e-3 : out_depth >= CV_32F ? 1e-2 : 1;
  778. }
  779. int CV_GetRectSubPixTest::prepare_test_case( int test_case_idx )
  780. {
  781. return CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
  782. }
  783. void CV_GetRectSubPixTest::prepare_to_validation( int /*test_case_idx*/ )
  784. {
  785. Mat& src0 = test_mat[INPUT][0];
  786. Mat& dst0 = test_mat[REF_INPUT_OUTPUT][0];
  787. Mat src = src0, dst = dst0;
  788. int ftype = CV_MAKETYPE(CV_32F,src0.channels());
  789. double a[] = { 1, 0, center.x - dst.cols*0.5 + 0.5,
  790. 0, 1, center.y - dst.rows*0.5 + 0.5 };
  791. if( src.depth() != CV_32F )
  792. src0.convertTo(src, CV_32F);
  793. if( dst.depth() != CV_32F )
  794. dst.create(dst0.size(), ftype);
  795. test_getQuadrangeSubPix( src, dst, a );
  796. if( dst.data != dst0.data )
  797. dst.convertTo(dst0, dst0.depth());
  798. }
  799. class CV_GetQuadSubPixTest : public CV_ImgWarpBaseTest
  800. {
  801. public:
  802. CV_GetQuadSubPixTest();
  803. protected:
  804. void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  805. void run_func();
  806. int prepare_test_case( int test_case_idx );
  807. void prepare_to_validation( int /*test_case_idx*/ );
  808. double get_success_error_level( int test_case_idx, int i, int j );
  809. };
  810. CV_GetQuadSubPixTest::CV_GetQuadSubPixTest() : CV_ImgWarpBaseTest( true )
  811. {
  812. //spatial_scale_zoom = spatial_scale_decimate;
  813. spatial_scale_decimate = spatial_scale_zoom;
  814. }
  815. void CV_GetQuadSubPixTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
  816. {
  817. int min_size = 4;
  818. CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
  819. Size sz = sizes[INPUT][0], dsz;
  820. RNG& rng = ts->get_rng();
  821. int msz, src_depth = cvtest::randInt(rng) % 2, dst_depth;
  822. int cn = cvtest::randInt(rng) % 2 ? 3 : 1;
  823. dst_depth = src_depth = src_depth == 0 ? CV_8U : CV_32F;
  824. if( src_depth < CV_32F && cvtest::randInt(rng) % 2 )
  825. dst_depth = CV_32F;
  826. types[INPUT][0] = CV_MAKETYPE(src_depth,cn);
  827. types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(dst_depth,cn);
  828. sz.width = MAX(sz.width,min_size);
  829. sz.height = MAX(sz.height,min_size);
  830. sizes[INPUT][0] = sz;
  831. msz = MIN( sz.width, sz.height );
  832. dsz.width = cvRound(sqrt(cvtest::randReal(rng)*msz) + 1);
  833. dsz.height = cvRound(sqrt(cvtest::randReal(rng)*msz) + 1);
  834. dsz.width = MIN(dsz.width,msz);
  835. dsz.height = MIN(dsz.width,msz);
  836. dsz.width = MAX(dsz.width,min_size);
  837. dsz.height = MAX(dsz.height,min_size);
  838. sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = dsz;
  839. sizes[INPUT][1] = cvSize( 3, 2 );
  840. }
  841. void CV_GetQuadSubPixTest::run_func()
  842. {
  843. CvMat mtx = cvMat(test_mat[INPUT][1]);
  844. cvGetQuadrangleSubPix( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &mtx );
  845. }
  846. double CV_GetQuadSubPixTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
  847. {
  848. int in_depth = test_mat[INPUT][0].depth();
  849. //int out_depth = test_mat[INPUT_OUTPUT][0].depth();
  850. return in_depth >= CV_32F ? 1e-2 : 4;
  851. }
  852. int CV_GetQuadSubPixTest::prepare_test_case( int test_case_idx )
  853. {
  854. RNG& rng = ts->get_rng();
  855. int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
  856. const Mat& src = test_mat[INPUT][0];
  857. Mat& mat = test_mat[INPUT][1];
  858. Point2f center;
  859. double scale, angle;
  860. if( code <= 0 )
  861. return code;
  862. double a[6];
  863. Mat A( 2, 3, CV_64FC1, a );
  864. center.x = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.cols);
  865. center.y = (float)((cvtest::randReal(rng)*1.2 - 0.1)*src.rows);
  866. angle = cvtest::randReal(rng)*360;
  867. scale = cvtest::randReal(rng)*0.2 + 0.9;
  868. // y = Ax + b -> x = A^-1(y - b) = A^-1*y - A^-1*b
  869. scale = 1./scale;
  870. angle = angle*(CV_PI/180.);
  871. a[0] = a[4] = cos(angle)*scale;
  872. a[1] = sin(angle)*scale;
  873. a[3] = -a[1];
  874. a[2] = center.x - a[0]*center.x - a[1]*center.y;
  875. a[5] = center.y - a[3]*center.x - a[4]*center.y;
  876. A.convertTo( mat, mat.depth() );
  877. return code;
  878. }
  879. void CV_GetQuadSubPixTest::prepare_to_validation( int /*test_case_idx*/ )
  880. {
  881. Mat& src0 = test_mat[INPUT][0];
  882. Mat& dst0 = test_mat[REF_INPUT_OUTPUT][0];
  883. Mat src = src0, dst = dst0;
  884. int ftype = CV_MAKETYPE(CV_32F,src0.channels());
  885. double a[6], dx = (dst0.cols - 1)*0.5, dy = (dst0.rows - 1)*0.5;
  886. Mat A( 2, 3, CV_64F, a );
  887. if( src.depth() != CV_32F )
  888. src0.convertTo(src, CV_32F);
  889. if( dst.depth() != CV_32F )
  890. dst.create(dst0.size(), ftype);
  891. test_mat[INPUT][1].convertTo( A, CV_64F );
  892. a[2] -= a[0]*dx + a[1]*dy;
  893. a[5] -= a[3]*dx + a[4]*dy;
  894. test_getQuadrangeSubPix( src, dst, a );
  895. if( dst.data != dst0.data )
  896. dst.convertTo(dst0, dst0.depth());
  897. }
  898. ////////////////////////////// resizeArea /////////////////////////////////
  899. template <typename T>
  900. static void check_resize_area(const Mat& expected, const Mat& actual, double tolerance = 1.0)
  901. {
  902. ASSERT_EQ(actual.type(), expected.type());
  903. ASSERT_EQ(actual.size(), expected.size());
  904. Mat diff;
  905. absdiff(actual, expected, diff);
  906. Mat one_channel_diff = diff; //.reshape(1);
  907. Size dsize = actual.size();
  908. bool next = true;
  909. for (int dy = 0; dy < dsize.height && next; ++dy)
  910. {
  911. const T* eD = expected.ptr<T>(dy);
  912. const T* aD = actual.ptr<T>(dy);
  913. for (int dx = 0; dx < dsize.width && next; ++dx)
  914. if (fabs(static_cast<double>(aD[dx] - eD[dx])) > tolerance)
  915. {
  916. cvtest::TS::ptr()->printf(cvtest::TS::SUMMARY, "Inf norm: %f\n", static_cast<float>(cvtest::norm(actual, expected, NORM_INF)));
  917. cvtest::TS::ptr()->printf(cvtest::TS::SUMMARY, "Error in : (%d, %d)\n", dx, dy);
  918. const int radius = 3;
  919. int rmin = MAX(dy - radius, 0), rmax = MIN(dy + radius, dsize.height);
  920. int cmin = MAX(dx - radius, 0), cmax = MIN(dx + radius, dsize.width);
  921. std::cout << "Abs diff:" << std::endl << diff << std::endl;
  922. std::cout << "actual result:\n" << actual(Range(rmin, rmax), Range(cmin, cmax)) << std::endl;
  923. std::cout << "expected result:\n" << expected(Range(rmin, rmax), Range(cmin, cmax)) << std::endl;
  924. next = false;
  925. }
  926. }
  927. ASSERT_EQ(0, cvtest::norm(one_channel_diff, cv::NORM_INF));
  928. }
  929. ///////////////////////////////////////////////////////////////////////////
  930. TEST(Imgproc_cvWarpAffine, regression)
  931. {
  932. IplImage* src = cvCreateImage(cvSize(100, 100), IPL_DEPTH_8U, 1);
  933. IplImage* dst = cvCreateImage(cvSize(100, 100), IPL_DEPTH_8U, 1);
  934. cvZero(src);
  935. float m[6];
  936. CvMat M = cvMat( 2, 3, CV_32F, m );
  937. int w = src->width;
  938. int h = src->height;
  939. cv2DRotationMatrix(cvPoint2D32f(w*0.5f, h*0.5f), 45.0, 1.0, &M);
  940. cvWarpAffine(src, dst, &M);
  941. cvReleaseImage(&src);
  942. cvReleaseImage(&dst);
  943. }
  944. TEST(Imgproc_fitLine_vector_3d, regression)
  945. {
  946. std::vector<Point3f> points_vector;
  947. Point3f p21(4,4,4);
  948. Point3f p22(8,8,8);
  949. points_vector.push_back(p21);
  950. points_vector.push_back(p22);
  951. std::vector<float> line;
  952. cv::fitLine(points_vector, line, CV_DIST_L2, 0 ,0 ,0);
  953. ASSERT_EQ(line.size(), (size_t)6);
  954. }
  955. TEST(Imgproc_fitLine_vector_2d, regression)
  956. {
  957. std::vector<Point2f> points_vector;
  958. Point2f p21(4,4);
  959. Point2f p22(8,8);
  960. Point2f p23(16,16);
  961. points_vector.push_back(p21);
  962. points_vector.push_back(p22);
  963. points_vector.push_back(p23);
  964. std::vector<float> line;
  965. cv::fitLine(points_vector, line, CV_DIST_L2, 0 ,0 ,0);
  966. ASSERT_EQ(line.size(), (size_t)4);
  967. }
  968. TEST(Imgproc_fitLine_Mat_2dC2, regression)
  969. {
  970. cv::Mat mat1 = Mat::zeros(3, 1, CV_32SC2);
  971. std::vector<float> line1;
  972. cv::fitLine(mat1, line1, CV_DIST_L2, 0 ,0 ,0);
  973. ASSERT_EQ(line1.size(), (size_t)4);
  974. }
  975. TEST(Imgproc_fitLine_Mat_2dC1, regression)
  976. {
  977. cv::Matx<int, 3, 2> mat2;
  978. std::vector<float> line2;
  979. cv::fitLine(mat2, line2, CV_DIST_L2, 0 ,0 ,0);
  980. ASSERT_EQ(line2.size(), (size_t)4);
  981. }
  982. TEST(Imgproc_fitLine_Mat_3dC3, regression)
  983. {
  984. cv::Mat mat1 = Mat::zeros(2, 1, CV_32SC3);
  985. std::vector<float> line1;
  986. cv::fitLine(mat1, line1, CV_DIST_L2, 0 ,0 ,0);
  987. ASSERT_EQ(line1.size(), (size_t)6);
  988. }
  989. TEST(Imgproc_fitLine_Mat_3dC1, regression)
  990. {
  991. cv::Mat mat2 = Mat::zeros(2, 3, CV_32SC1);
  992. std::vector<float> line2;
  993. cv::fitLine(mat2, line2, CV_DIST_L2, 0 ,0 ,0);
  994. ASSERT_EQ(line2.size(), (size_t)6);
  995. }
  996. TEST(Imgproc_resize_area, regression)
  997. {
  998. static ushort input_data[16 * 16] = {
  999. 90, 94, 80, 3, 231, 2, 186, 245, 188, 165, 10, 19, 201, 169, 8, 228,
  1000. 86, 5, 203, 120, 136, 185, 24, 94, 81, 150, 163, 137, 88, 105, 132, 132,
  1001. 236, 48, 250, 218, 19, 52, 54, 221, 159, 112, 45, 11, 152, 153, 112, 134,
  1002. 78, 133, 136, 83, 65, 76, 82, 250, 9, 235, 148, 26, 236, 179, 200, 50,
  1003. 99, 51, 103, 142, 201, 65, 176, 33, 49, 226, 177, 109, 46, 21, 67, 130,
  1004. 54, 125, 107, 154, 145, 51, 199, 189, 161, 142, 231, 240, 139, 162, 240, 22,
  1005. 231, 86, 79, 106, 92, 47, 146, 156, 36, 207, 71, 33, 2, 244, 221, 71,
  1006. 44, 127, 71, 177, 75, 126, 68, 119, 200, 129, 191, 251, 6, 236, 247, 6,
  1007. 133, 175, 56, 239, 147, 221, 243, 154, 242, 82, 106, 99, 77, 158, 60, 229,
  1008. 2, 42, 24, 174, 27, 198, 14, 204, 246, 251, 141, 31, 114, 163, 29, 147,
  1009. 121, 53, 74, 31, 147, 189, 42, 98, 202, 17, 228, 123, 209, 40, 77, 49,
  1010. 112, 203, 30, 12, 205, 25, 19, 106, 145, 185, 163, 201, 237, 223, 247, 38,
  1011. 33, 105, 243, 117, 92, 179, 204, 248, 160, 90, 73, 126, 2, 41, 213, 204,
  1012. 6, 124, 195, 201, 230, 187, 210, 167, 48, 79, 123, 159, 145, 218, 105, 209,
  1013. 240, 152, 136, 235, 235, 164, 157, 9, 152, 38, 27, 209, 120, 77, 238, 196,
  1014. 240, 233, 10, 241, 90, 67, 12, 79, 0, 43, 58, 27, 83, 199, 190, 182};
  1015. static ushort expected_data[5 * 5] = {
  1016. 120, 100, 151, 101, 130,
  1017. 106, 115, 141, 130, 127,
  1018. 91, 136, 170, 114, 140,
  1019. 104, 122, 131, 147, 133,
  1020. 161, 163, 70, 107, 182
  1021. };
  1022. cv::Mat src(16, 16, CV_16UC1, input_data);
  1023. cv::Mat expected(5, 5, CV_16UC1, expected_data);
  1024. cv::Mat actual(expected.size(), expected.type());
  1025. cv::resize(src, actual, cv::Size(), 0.3, 0.3, INTER_AREA);
  1026. check_resize_area<ushort>(expected, actual, 1.0);
  1027. }
  1028. TEST(Imgproc_resize_area, regression_half_round)
  1029. {
  1030. static uchar input_data[32 * 32];
  1031. for(int i = 0; i < 32 * 32; ++i)
  1032. input_data[i] = (uchar)(i % 2 + 253 + i / (16 * 32));
  1033. static uchar expected_data[16 * 16];
  1034. for(int i = 0; i < 16 * 16; ++i)
  1035. expected_data[i] = (uchar)(254 + i / (16 * 8));
  1036. cv::Mat src(32, 32, CV_8UC1, input_data);
  1037. cv::Mat expected(16, 16, CV_8UC1, expected_data);
  1038. cv::Mat actual(expected.size(), expected.type());
  1039. cv::resize(src, actual, cv::Size(), 0.5, 0.5, INTER_AREA);
  1040. check_resize_area<uchar>(expected, actual, 0.5);
  1041. }
  1042. TEST(Imgproc_resize_area, regression_quarter_round)
  1043. {
  1044. static uchar input_data[32 * 32];
  1045. for(int i = 0; i < 32 * 32; ++i)
  1046. input_data[i] = (uchar)(i % 2 + 253 + i / (16 * 32));
  1047. static uchar expected_data[8 * 8];
  1048. for(int i = 0; i < 8 * 8; ++i)
  1049. expected_data[i] = 254;
  1050. cv::Mat src(32, 32, CV_8UC1, input_data);
  1051. cv::Mat expected(8, 8, CV_8UC1, expected_data);
  1052. cv::Mat actual(expected.size(), expected.type());
  1053. cv::resize(src, actual, cv::Size(), 0.25, 0.25, INTER_AREA);
  1054. check_resize_area<uchar>(expected, actual, 0.5);
  1055. }
  1056. typedef tuple<int, int, int, int, bool> RemapRelativeParam;
  1057. typedef testing::TestWithParam<RemapRelativeParam> Imgproc_RemapRelative;
  1058. TEST_P(Imgproc_RemapRelative, validity)
  1059. {
  1060. int srcType = CV_MAKE_TYPE(get<0>(GetParam()), get<1>(GetParam()));
  1061. int interpolation = get<2>(GetParam());
  1062. int borderType = get<3>(GetParam());
  1063. bool useFixedPoint = get<4>(GetParam());
  1064. const int nChannels = CV_MAT_CN(srcType);
  1065. const cv::Size size(127, 61);
  1066. cv::Mat data64FC1(1, size.area()*nChannels, CV_64FC1);
  1067. data64FC1.forEach<double>([&](double& pixel, const int* position) {pixel = static_cast<double>(position[1]);});
  1068. cv::Mat src;
  1069. data64FC1.reshape(nChannels, size.height).convertTo(src, srcType);
  1070. cv::Mat mapRelativeX32F(size, CV_32FC1);
  1071. mapRelativeX32F.setTo(cv::Scalar::all(-0.25));
  1072. cv::Mat mapRelativeY32F(size, CV_32FC1);
  1073. mapRelativeY32F.setTo(cv::Scalar::all(-0.25));
  1074. cv::Mat mapAbsoluteX32F = mapRelativeX32F.clone();
  1075. mapAbsoluteX32F.forEach<float>([&](float& pixel, const int* position) {
  1076. pixel += static_cast<float>(position[1]);
  1077. });
  1078. cv::Mat mapAbsoluteY32F = mapRelativeY32F.clone();
  1079. mapAbsoluteY32F.forEach<float>([&](float& pixel, const int* position) {
  1080. pixel += static_cast<float>(position[0]);
  1081. });
  1082. cv::Mat mapAbsoluteX16S;
  1083. cv::Mat mapAbsoluteY16S;
  1084. cv::Mat mapRelativeX16S;
  1085. cv::Mat mapRelativeY16S;
  1086. if (useFixedPoint)
  1087. {
  1088. const bool nninterpolation = (interpolation == cv::INTER_NEAREST) || (interpolation == cv::INTER_NEAREST_EXACT);
  1089. cv::convertMaps(mapAbsoluteX32F, mapAbsoluteY32F, mapAbsoluteX16S, mapAbsoluteY16S, CV_16SC2, nninterpolation);
  1090. cv::convertMaps(mapRelativeX32F, mapRelativeY32F, mapRelativeX16S, mapRelativeY16S, CV_16SC2, nninterpolation);
  1091. }
  1092. cv::Mat dstAbsolute;
  1093. cv::Mat dstRelative;
  1094. if (useFixedPoint)
  1095. {
  1096. cv::remap(src, dstAbsolute, mapAbsoluteX16S, mapAbsoluteY16S, interpolation, borderType);
  1097. cv::remap(src, dstRelative, mapRelativeX16S, mapRelativeY16S, interpolation | WARP_RELATIVE_MAP, borderType);
  1098. }
  1099. else
  1100. {
  1101. cv::remap(src, dstAbsolute, mapAbsoluteX32F, mapAbsoluteY32F, interpolation, borderType);
  1102. cv::remap(src, dstRelative, mapRelativeX32F, mapRelativeY32F, interpolation | WARP_RELATIVE_MAP, borderType);
  1103. }
  1104. EXPECT_LE(cvtest::norm(dstAbsolute, dstRelative, NORM_INF), 1);
  1105. };
  1106. INSTANTIATE_TEST_CASE_P(ImgProc, Imgproc_RemapRelative, testing::Combine(
  1107. testing::Values(CV_8U, CV_16U, CV_32F, CV_64F),
  1108. testing::Values(1, 3, 4),
  1109. testing::Values((int)INTER_NEAREST, (int)INTER_LINEAR, (int)INTER_CUBIC, (int)INTER_LANCZOS4),
  1110. testing::Values((int)BORDER_CONSTANT, (int)BORDER_REPLICATE, (int)BORDER_WRAP, (int)BORDER_REFLECT, (int)BORDER_REFLECT_101),
  1111. testing::Values(false, true)));
  1112. //////////////////////////////////////////////////////////////////////////
  1113. TEST(Imgproc_Resize, accuracy) { CV_ResizeTest test; test.safe_run(); }
  1114. TEST(Imgproc_ResizeExact, accuracy) { CV_ResizeExactTest test; test.safe_run(); }
  1115. TEST(Imgproc_WarpAffine, accuracy) { CV_WarpAffineTest test; test.safe_run(); }
  1116. TEST(Imgproc_WarpPerspective, accuracy) { CV_WarpPerspectiveTest test; test.safe_run(); }
  1117. TEST(Imgproc_Remap, accuracy) { CV_RemapTest test; test.safe_run(); }
  1118. TEST(Imgproc_GetRectSubPix, accuracy) { CV_GetRectSubPixTest test; test.safe_run(); }
  1119. TEST(Imgproc_GetQuadSubPix, accuracy) { CV_GetQuadSubPixTest test; test.safe_run(); }
  1120. //////////////////////////////////////////////////////////////////////////
  1121. template <typename T, typename WT>
  1122. struct IntCast
  1123. {
  1124. T operator() (WT val) const
  1125. {
  1126. return cv::saturate_cast<T>(val >> 2);
  1127. }
  1128. };
  1129. template <typename T, typename WT>
  1130. struct FltCast
  1131. {
  1132. T operator() (WT val) const
  1133. {
  1134. return cv::saturate_cast<T>(val * 0.25);
  1135. }
  1136. };
  1137. template <typename T, typename WT, int one, typename CastOp>
  1138. void resizeArea(const cv::Mat & src, cv::Mat & dst)
  1139. {
  1140. int cn = src.channels();
  1141. CastOp castOp;
  1142. for (int y = 0; y < dst.rows; ++y)
  1143. {
  1144. const T * sptr0 = src.ptr<T>(y << 1);
  1145. const T * sptr1 = src.ptr<T>((y << 1) + 1);
  1146. T * dptr = dst.ptr<T>(y);
  1147. for (int x = 0; x < dst.cols * cn; x += cn)
  1148. {
  1149. int x1 = x << 1;
  1150. for (int c = 0; c < cn; ++c)
  1151. {
  1152. WT sum = WT(sptr0[x1 + c]) + WT(sptr0[x1 + c + cn]);
  1153. sum += WT(sptr1[x1 + c]) + WT(sptr1[x1 + c + cn]) + (WT)(one);
  1154. dptr[x + c] = castOp(sum);
  1155. }
  1156. }
  1157. }
  1158. }
  1159. TEST(Resize, Area_half)
  1160. {
  1161. const int size = 1000;
  1162. int types[] = { CV_8UC1, CV_8UC4,
  1163. CV_16UC1, CV_16UC4,
  1164. CV_16SC1, CV_16SC3, CV_16SC4,
  1165. CV_32FC1, CV_32FC4 };
  1166. cv::RNG rng(17);
  1167. for (int i = 0, _size = sizeof(types) / sizeof(types[0]); i < _size; ++i)
  1168. {
  1169. int type = types[i], depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
  1170. const float eps = depth <= CV_32S ? 0 : 7e-5f;
  1171. SCOPED_TRACE(depth);
  1172. SCOPED_TRACE(cn);
  1173. cv::Mat src(size, size, type), dst_actual(size >> 1, size >> 1, type),
  1174. dst_reference(size >> 1, size >> 1, type);
  1175. rng.fill(src, cv::RNG::UNIFORM, -1000, 1000, true);
  1176. if (depth == CV_8U)
  1177. resizeArea<uchar, ushort, 2, IntCast<uchar, ushort> >(src, dst_reference);
  1178. else if (depth == CV_16U)
  1179. resizeArea<ushort, uint, 2, IntCast<ushort, uint> >(src, dst_reference);
  1180. else if (depth == CV_16S)
  1181. resizeArea<short, int, 2, IntCast<short, int> >(src, dst_reference);
  1182. else if (depth == CV_32F)
  1183. resizeArea<float, float, 0, FltCast<float, float> >(src, dst_reference);
  1184. else
  1185. CV_Assert(0);
  1186. cv::resize(src, dst_actual, dst_actual.size(), 0, 0, cv::INTER_AREA);
  1187. ASSERT_GE(eps, cvtest::norm(dst_reference, dst_actual, cv::NORM_INF));
  1188. }
  1189. }
  1190. TEST(Resize, lanczos4_regression_16192)
  1191. {
  1192. Size src_size(11, 17);
  1193. Size dst_size(11, 153);
  1194. Mat src(src_size, CV_8UC3, Scalar::all(128));
  1195. Mat dst(dst_size, CV_8UC3, Scalar::all(255));
  1196. cv::resize(src, dst, dst_size, 0, 0, INTER_LANCZOS4);
  1197. Mat expected(dst_size, CV_8UC3, Scalar::all(128));
  1198. EXPECT_EQ(cvtest::norm(dst, expected, NORM_INF), 0) << dst(Rect(0,0,8,8));
  1199. }
  1200. TEST(Resize, nearest_regression_15075)
  1201. {
  1202. const int C = 5;
  1203. const int i1 = 5, j1 = 5;
  1204. Size src_size(12, 12);
  1205. Size dst_size(11, 11);
  1206. cv::Mat src = cv::Mat::zeros(src_size, CV_8UC(C)), dst;
  1207. for (int j = 0; j < C; j++)
  1208. src.col(i1).row(j1).data[j] = 1;
  1209. cv::resize(src, dst, dst_size, 0, 0, INTER_NEAREST);
  1210. EXPECT_EQ(C, cvtest::norm(dst, NORM_L1)) << src.size;
  1211. }
  1212. TEST(Imgproc_Warp, multichannel)
  1213. {
  1214. static const int inter_types[] = {INTER_NEAREST, INTER_AREA, INTER_CUBIC,
  1215. INTER_LANCZOS4, INTER_LINEAR};
  1216. static const int inter_n = sizeof(inter_types) / sizeof(int);
  1217. static const int border_types[] = {BORDER_CONSTANT, BORDER_DEFAULT,
  1218. BORDER_REFLECT, BORDER_REPLICATE,
  1219. BORDER_WRAP, BORDER_WRAP};
  1220. static const int border_n = sizeof(border_types) / sizeof(int);
  1221. RNG& rng = theRNG();
  1222. for( int iter = 0; iter < 100; iter++ )
  1223. {
  1224. int inter = inter_types[rng.uniform(0, inter_n)];
  1225. int border = border_types[rng.uniform(0, border_n)];
  1226. int width = rng.uniform(3, 333);
  1227. int height = rng.uniform(3, 333);
  1228. int cn = rng.uniform(1, 15);
  1229. if(inter == INTER_CUBIC || inter == INTER_LANCZOS4)
  1230. cn = rng.uniform(1, 5);
  1231. Mat src(height, width, CV_8UC(cn)), dst;
  1232. //randu(src, 0, 256);
  1233. src.setTo(0.);
  1234. Mat rot = getRotationMatrix2D(Point2f(0.f, 0.f), 1.0, 1.0);
  1235. warpAffine(src, dst, rot, src.size(), inter, border);
  1236. ASSERT_EQ(0.0, cvtest::norm(dst, NORM_INF));
  1237. Mat rot2 = Mat::eye(3, 3, rot.type());
  1238. rot.copyTo(rot2.rowRange(0, 2));
  1239. warpPerspective(src, dst, rot2, src.size(), inter, border);
  1240. ASSERT_EQ(0.0, cvtest::norm(dst, NORM_INF));
  1241. }
  1242. }
  1243. TEST(Imgproc_Warp, regression_19566) // valgrind should detect problem if any
  1244. {
  1245. const Size imgSize(8192, 8);
  1246. Mat inMat = Mat::zeros(imgSize, CV_8UC4);
  1247. Mat outMat = Mat::zeros(imgSize, CV_8UC4);
  1248. warpAffine(
  1249. inMat,
  1250. outMat,
  1251. getRotationMatrix2D(Point2f(imgSize.width / 2.0f, imgSize.height / 2.0f), 45.0, 1.0),
  1252. imgSize,
  1253. INTER_LINEAR,
  1254. cv::BORDER_CONSTANT,
  1255. cv::Scalar(0.0, 0.0, 0.0, 255.0)
  1256. );
  1257. }
  1258. TEST(Imgproc_GetAffineTransform, singularity)
  1259. {
  1260. Point2f A_sample[3];
  1261. A_sample[0] = Point2f(8.f, 9.f);
  1262. A_sample[1] = Point2f(40.f, 41.f);
  1263. A_sample[2] = Point2f(47.f, 48.f);
  1264. Point2f B_sample[3];
  1265. B_sample[0] = Point2f(7.37465f, 11.8295f);
  1266. B_sample[1] = Point2f(15.0113f, 12.8994f);
  1267. B_sample[2] = Point2f(38.9943f, 9.56297f);
  1268. Mat trans = getAffineTransform(A_sample, B_sample);
  1269. ASSERT_EQ(0.0, cvtest::norm(trans, NORM_INF));
  1270. }
  1271. TEST(Imgproc_Remap, DISABLED_memleak)
  1272. {
  1273. Mat src;
  1274. const int N = 400;
  1275. src.create(N, N, CV_8U);
  1276. randu(src, 0, 256);
  1277. Mat map_x, map_y, dst;
  1278. dst.create( src.size(), src.type() );
  1279. map_x.create( src.size(), CV_32FC1 );
  1280. map_y.create( src.size(), CV_32FC1 );
  1281. randu(map_x, 0., N+0.);
  1282. randu(map_y, 0., N+0.);
  1283. for( int iter = 0; iter < 10000; iter++ )
  1284. {
  1285. if(iter % 100 == 0)
  1286. {
  1287. putchar('.');
  1288. fflush(stdout);
  1289. }
  1290. remap(src, dst, map_x, map_y, cv::INTER_LINEAR);
  1291. }
  1292. }
  1293. //** @deprecated */
  1294. TEST(Imgproc_linearPolar, identity)
  1295. {
  1296. const int N = 33;
  1297. Mat in(N, N, CV_8UC3, Scalar(255, 0, 0));
  1298. in(cv::Rect(N/3, N/3, N/3, N/3)).setTo(Scalar::all(255));
  1299. cv::blur(in, in, Size(5, 5));
  1300. cv::blur(in, in, Size(5, 5));
  1301. Mat src = in.clone();
  1302. Mat dst;
  1303. Rect roi = Rect(0, 0, in.cols - ((N+19)/20), in.rows);
  1304. for (int i = 1; i <= 5; i++)
  1305. {
  1306. linearPolar(src, dst,
  1307. Point2f((N-1) * 0.5f, (N-1) * 0.5f), N * 0.5f,
  1308. cv::WARP_FILL_OUTLIERS | cv::INTER_LINEAR | cv::WARP_INVERSE_MAP);
  1309. linearPolar(dst, src,
  1310. Point2f((N-1) * 0.5f, (N-1) * 0.5f), N * 0.5f,
  1311. cv::WARP_FILL_OUTLIERS | cv::INTER_LINEAR);
  1312. double psnr = cvtest::PSNR(in(roi), src(roi));
  1313. EXPECT_LE(25, psnr) << "iteration=" << i;
  1314. }
  1315. #if 0
  1316. Mat all(N*2+2,N*2+2, src.type(), Scalar(0,0,255));
  1317. in.copyTo(all(Rect(0,0,N,N)));
  1318. src.copyTo(all(Rect(0,N+1,N,N)));
  1319. src.copyTo(all(Rect(N+1,0,N,N)));
  1320. dst.copyTo(all(Rect(N+1,N+1,N,N)));
  1321. imwrite("linearPolar.png", all);
  1322. imshow("input", in); imshow("result", dst); imshow("restore", src); imshow("all", all);
  1323. cv::waitKey();
  1324. #endif
  1325. }
  1326. //** @deprecated */
  1327. TEST(Imgproc_logPolar, identity)
  1328. {
  1329. const int N = 33;
  1330. Mat in(N, N, CV_8UC3, Scalar(255, 0, 0));
  1331. in(cv::Rect(N/3, N/3, N/3, N/3)).setTo(Scalar::all(255));
  1332. cv::blur(in, in, Size(5, 5));
  1333. cv::blur(in, in, Size(5, 5));
  1334. Mat src = in.clone();
  1335. Mat dst;
  1336. Rect roi = Rect(0, 0, in.cols - ((N+19)/20), in.rows);
  1337. double M = N/log(N * 0.5f);
  1338. for (int i = 1; i <= 5; i++)
  1339. {
  1340. logPolar(src, dst,
  1341. Point2f((N-1) * 0.5f, (N-1) * 0.5f), M,
  1342. cv::WARP_FILL_OUTLIERS | cv::INTER_LINEAR | cv::WARP_INVERSE_MAP);
  1343. logPolar(dst, src,
  1344. Point2f((N-1) * 0.5f, (N-1) * 0.5f), M,
  1345. cv::WARP_FILL_OUTLIERS | cv::INTER_LINEAR);
  1346. double psnr = cvtest::PSNR(in(roi), src(roi));
  1347. EXPECT_LE(25, psnr) << "iteration=" << i;
  1348. }
  1349. #if 0
  1350. Mat all(N*2+2,N*2+2, src.type(), Scalar(0,0,255));
  1351. in.copyTo(all(Rect(0,0,N,N)));
  1352. src.copyTo(all(Rect(0,N+1,N,N)));
  1353. src.copyTo(all(Rect(N+1,0,N,N)));
  1354. dst.copyTo(all(Rect(N+1,N+1,N,N)));
  1355. imwrite("logPolar.png", all);
  1356. imshow("input", in); imshow("result", dst); imshow("restore", src); imshow("all", all);
  1357. cv::waitKey();
  1358. #endif
  1359. }
  1360. TEST(Imgproc_warpPolar, identity)
  1361. {
  1362. const int N = 33;
  1363. Mat in(N, N, CV_8UC3, Scalar(255, 0, 0));
  1364. in(cv::Rect(N / 3, N / 3, N / 3, N / 3)).setTo(Scalar::all(255));
  1365. cv::blur(in, in, Size(5, 5));
  1366. cv::blur(in, in, Size(5, 5));
  1367. Mat src = in.clone();
  1368. Mat dst;
  1369. Rect roi = Rect(0, 0, in.cols - ((N + 19) / 20), in.rows);
  1370. Point2f center = Point2f((N - 1) * 0.5f, (N - 1) * 0.5f);
  1371. double radius = N * 0.5;
  1372. int flags = cv::WARP_FILL_OUTLIERS | cv::INTER_LINEAR;
  1373. // test linearPolar
  1374. for (int ki = 1; ki <= 5; ki++)
  1375. {
  1376. warpPolar(src, dst, src.size(), center, radius, flags + WARP_POLAR_LINEAR + cv::WARP_INVERSE_MAP);
  1377. warpPolar(dst, src, src.size(), center, radius, flags + WARP_POLAR_LINEAR);
  1378. double psnr = cv::PSNR(in(roi), src(roi));
  1379. EXPECT_LE(25, psnr) << "iteration=" << ki;
  1380. }
  1381. // test logPolar
  1382. src = in.clone();
  1383. for (int ki = 1; ki <= 5; ki++)
  1384. {
  1385. warpPolar(src, dst, src.size(),center, radius, flags + WARP_POLAR_LOG + cv::WARP_INVERSE_MAP );
  1386. warpPolar(dst, src, src.size(),center, radius, flags + WARP_POLAR_LOG);
  1387. double psnr = cv::PSNR(in(roi), src(roi));
  1388. EXPECT_LE(25, psnr) << "iteration=" << ki;
  1389. }
  1390. #if 0
  1391. Mat all(N*2+2,N*2+2, src.type(), Scalar(0,0,255));
  1392. in.copyTo(all(Rect(0,0,N,N)));
  1393. src.copyTo(all(Rect(0,N+1,N,N)));
  1394. src.copyTo(all(Rect(N+1,0,N,N)));
  1395. dst.copyTo(all(Rect(N+1,N+1,N,N)));
  1396. imwrite("linearPolar.png", all);
  1397. imshow("input", in); imshow("result", dst); imshow("restore", src); imshow("all", all);
  1398. cv::waitKey();
  1399. #endif
  1400. }
  1401. TEST(Imgproc_Remap, issue_23562)
  1402. {
  1403. cv::RNG rng(17);
  1404. Mat_<float> mapx({3, 3}, {0, 1, 2, 0, 1, 2, 0, 1, 2});
  1405. Mat_<float> mapy({3, 3}, {0, 0, 0, 1, 1, 1, 2, 2, 2});
  1406. for (int cn = 1; cn <= 4; ++cn) {
  1407. Mat src(3, 3, CV_32FC(cn));
  1408. rng.fill(src, cv::RNG::UNIFORM, -1, 1);
  1409. Mat dst = Mat::zeros(3, 3, CV_32FC(cn));
  1410. Mat ref = src.clone();
  1411. remap(src, dst, mapx, mapy, INTER_LINEAR, BORDER_TRANSPARENT);
  1412. ASSERT_EQ(0.0, cvtest::norm(ref, dst, NORM_INF)) << "channels=" << cn;
  1413. }
  1414. mapx = Mat1f({3, 3}, {0, 1, 2, 0, 1, 2, 0, 1, 2});
  1415. mapy = Mat1f({3, 3}, {0, 0, 0, 1, 1, 1, 2, 2, 1.5});
  1416. for (int cn = 1; cn <= 4; ++cn) {
  1417. Mat src = cv::Mat(3, 3, CV_32FC(cn));
  1418. Mat dst = 10 * Mat::ones(3, 3, CV_32FC(cn));
  1419. for(int y = 0; y < 3; ++y) {
  1420. for(int x = 0; x < 3; ++x) {
  1421. for(int k = 0; k < cn; ++k) {
  1422. src.ptr<float>(y,x)[k] = 10.f * y + x;
  1423. }
  1424. }
  1425. }
  1426. Mat ref = src.clone();
  1427. for(int k = 0; k < cn; ++k) {
  1428. ref.ptr<float>(2,2)[k] = (src.ptr<float>(1, 2)[k] + src.ptr<float>(2, 2)[k]) / 2.f;
  1429. }
  1430. remap(src, dst, mapx, mapy, INTER_LINEAR, BORDER_TRANSPARENT);
  1431. ASSERT_EQ(0.0, cvtest::norm(ref, dst, NORM_INF)) << "channels=" << cn;
  1432. }
  1433. }
  1434. TEST(Imgproc_getPerspectiveTransform, issue_26916)
  1435. {
  1436. double src_data[] = {320, 512, 960, 512, 0, 1024, 1280, 1024};
  1437. const Mat src_points(4, 2, CV_64FC1, src_data);
  1438. double dst_data[] = {0, 0, 1280, 0, 0, 1024, 1280, 1024};
  1439. const Mat dst_points(4, 2, CV_64FC1, dst_data);
  1440. Mat src_points_f;
  1441. src_points.convertTo(src_points_f, CV_32FC1);
  1442. Mat dst_points_f;
  1443. dst_points.convertTo(dst_points_f, CV_32FC1);
  1444. Mat perspective_transform = getPerspectiveTransform(src_points_f, dst_points_f);
  1445. EXPECT_NEAR(perspective_transform.at<double>(2, 2), 0, 1e-16);
  1446. EXPECT_NEAR(cv::norm(perspective_transform), 1, 1e-14);
  1447. const Mat ones = Mat::ones(4, 1, CV_64FC1);
  1448. Mat homogeneous_src_points;
  1449. hconcat(src_points, ones, homogeneous_src_points);
  1450. Mat obtained_homogeneous_dst_points = (perspective_transform * homogeneous_src_points.t()).t();
  1451. for (int row = 0; row < 4; ++row)
  1452. {
  1453. obtained_homogeneous_dst_points.row(row) /= obtained_homogeneous_dst_points.at<double>(row, 2);
  1454. }
  1455. Mat expected_homogeneous_dst_points;
  1456. hconcat(dst_points, ones, expected_homogeneous_dst_points);
  1457. EXPECT_MAT_NEAR(obtained_homogeneous_dst_points, expected_homogeneous_dst_points, 1e-10);
  1458. }
  1459. }} // namespace
  1460. /* End of file. */