test_fundam.cpp 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677
  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 "test_precomp.hpp"
  42. #include "opencv2/core/core_c.h"
  43. #include "opencv2/calib3d/calib3d_c.h"
  44. namespace cvtest {
  45. static int cvTsRodrigues( const CvMat* src, CvMat* dst, CvMat* jacobian )
  46. {
  47. int depth;
  48. int i;
  49. float Jf[27];
  50. double J[27];
  51. CvMat _Jf, matJ = cvMat( 3, 9, CV_64F, J );
  52. depth = CV_MAT_DEPTH(src->type);
  53. if( jacobian )
  54. {
  55. CV_Assert( (jacobian->rows == 9 && jacobian->cols == 3) ||
  56. (jacobian->rows == 3 && jacobian->cols == 9) );
  57. }
  58. if( src->cols == 1 || src->rows == 1 )
  59. {
  60. double r[3], theta;
  61. CvMat _r = cvMat( src->rows, src->cols, CV_MAKETYPE(CV_64F,CV_MAT_CN(src->type)), r);
  62. CV_Assert( dst->rows == 3 && dst->cols == 3 );
  63. cvConvert( src, &_r );
  64. theta = sqrt(r[0]*r[0] + r[1]*r[1] + r[2]*r[2]);
  65. if( theta < DBL_EPSILON )
  66. {
  67. cvSetIdentity( dst );
  68. if( jacobian )
  69. {
  70. memset( J, 0, sizeof(J) );
  71. J[5] = J[15] = J[19] = 1;
  72. J[7] = J[11] = J[21] = -1;
  73. }
  74. }
  75. else
  76. {
  77. // omega = r/theta (~[w1, w2, w3])
  78. double itheta = 1./theta;
  79. double w1 = r[0]*itheta, w2 = r[1]*itheta, w3 = r[2]*itheta;
  80. double alpha = cos(theta);
  81. double beta = sin(theta);
  82. double gamma = 1 - alpha;
  83. double omegav[] =
  84. {
  85. 0, -w3, w2,
  86. w3, 0, -w1,
  87. -w2, w1, 0
  88. };
  89. double A[] =
  90. {
  91. w1*w1, w1*w2, w1*w3,
  92. w2*w1, w2*w2, w2*w3,
  93. w3*w1, w3*w2, w3*w3
  94. };
  95. double R[9];
  96. CvMat _omegav = cvMat(3, 3, CV_64F, omegav);
  97. CvMat matA = cvMat(3, 3, CV_64F, A);
  98. CvMat matR = cvMat(3, 3, CV_64F, R);
  99. cvSetIdentity( &matR, cvRealScalar(alpha) );
  100. cvScaleAdd( &_omegav, cvRealScalar(beta), &matR, &matR );
  101. cvScaleAdd( &matA, cvRealScalar(gamma), &matR, &matR );
  102. cvConvert( &matR, dst );
  103. if( jacobian )
  104. {
  105. // m3 = [r, theta]
  106. double dm3din[] =
  107. {
  108. 1, 0, 0,
  109. 0, 1, 0,
  110. 0, 0, 1,
  111. w1, w2, w3
  112. };
  113. // m2 = [omega, theta]
  114. double dm2dm3[] =
  115. {
  116. itheta, 0, 0, -w1*itheta,
  117. 0, itheta, 0, -w2*itheta,
  118. 0, 0, itheta, -w3*itheta,
  119. 0, 0, 0, 1
  120. };
  121. double t0[9*4];
  122. double dm1dm2[21*4];
  123. double dRdm1[9*21];
  124. CvMat _dm3din = cvMat( 4, 3, CV_64FC1, dm3din );
  125. CvMat _dm2dm3 = cvMat( 4, 4, CV_64FC1, dm2dm3 );
  126. CvMat _dm1dm2 = cvMat( 21, 4, CV_64FC1, dm1dm2 );
  127. CvMat _dRdm1 = cvMat( 9, 21, CV_64FC1, dRdm1 );
  128. CvMat _dRdm1_part;
  129. CvMat _t0 = cvMat( 9, 4, CV_64FC1, t0 );
  130. CvMat _t1 = cvMat( 9, 4, CV_64FC1, dRdm1 );
  131. // m1 = [alpha, beta, gamma, omegav; A]
  132. memset( dm1dm2, 0, sizeof(dm1dm2) );
  133. dm1dm2[3] = -beta;
  134. dm1dm2[7] = alpha;
  135. dm1dm2[11] = beta;
  136. // dm1dm2(4:12,1:3) = [0 0 0 0 0 1 0 -1 0;
  137. // 0 0 -1 0 0 0 1 0 0;
  138. // 0 1 0 -1 0 0 0 0 0]'
  139. // -------------------
  140. // 0 0 0 0 0 0 0 0 0
  141. dm1dm2[12 + 6] = dm1dm2[12 + 20] = dm1dm2[12 + 25] = 1;
  142. dm1dm2[12 + 9] = dm1dm2[12 + 14] = dm1dm2[12 + 28] = -1;
  143. double dm1dw[] =
  144. {
  145. 2*w1, w2, w3, w2, 0, 0, w3, 0, 0,
  146. 0, w1, 0, w1, 2*w2, w3, 0, w3, 0,
  147. 0, 0, w1, 0, 0, w2, w1, w2, 2*w3
  148. };
  149. CvMat _dm1dw = cvMat( 3, 9, CV_64FC1, dm1dw );
  150. CvMat _dm1dm2_part;
  151. cvGetSubRect( &_dm1dm2, &_dm1dm2_part, cvRect(0,12,3,9) );
  152. cvTranspose( &_dm1dw, &_dm1dm2_part );
  153. memset( dRdm1, 0, sizeof(dRdm1) );
  154. dRdm1[0*21] = dRdm1[4*21] = dRdm1[8*21] = 1;
  155. cvGetCol( &_dRdm1, &_dRdm1_part, 1 );
  156. cvTranspose( &_omegav, &_omegav );
  157. cvReshape( &_omegav, &_omegav, 1, 1 );
  158. cvTranspose( &_omegav, &_dRdm1_part );
  159. cvGetCol( &_dRdm1, &_dRdm1_part, 2 );
  160. cvReshape( &matA, &matA, 1, 1 );
  161. cvTranspose( &matA, &_dRdm1_part );
  162. cvGetSubRect( &_dRdm1, &_dRdm1_part, cvRect(3,0,9,9) );
  163. cvSetIdentity( &_dRdm1_part, cvScalarAll(beta) );
  164. cvGetSubRect( &_dRdm1, &_dRdm1_part, cvRect(12,0,9,9) );
  165. cvSetIdentity( &_dRdm1_part, cvScalarAll(gamma) );
  166. matJ = cvMat( 9, 3, CV_64FC1, J );
  167. cvMatMul( &_dRdm1, &_dm1dm2, &_t0 );
  168. cvMatMul( &_t0, &_dm2dm3, &_t1 );
  169. cvMatMul( &_t1, &_dm3din, &matJ );
  170. _t0 = cvMat( 3, 9, CV_64FC1, t0 );
  171. cvTranspose( &matJ, &_t0 );
  172. for( i = 0; i < 3; i++ )
  173. {
  174. _t1 = cvMat( 3, 3, CV_64FC1, t0 + i*9 );
  175. cvTranspose( &_t1, &_t1 );
  176. }
  177. cvTranspose( &_t0, &matJ );
  178. }
  179. }
  180. }
  181. else if( src->cols == 3 && src->rows == 3 )
  182. {
  183. double R[9], A[9], I[9], r[3], W[3], U[9], V[9];
  184. double tr, alpha, beta, theta;
  185. CvMat matR = cvMat( 3, 3, CV_64F, R );
  186. CvMat matA = cvMat( 3, 3, CV_64F, A );
  187. CvMat matI = cvMat( 3, 3, CV_64F, I );
  188. CvMat _r = cvMat( dst->rows, dst->cols, CV_MAKETYPE(CV_64F, CV_MAT_CN(dst->type)), r );
  189. CvMat matW = cvMat( 1, 3, CV_64F, W );
  190. CvMat matU = cvMat( 3, 3, CV_64F, U );
  191. CvMat matV = cvMat( 3, 3, CV_64F, V );
  192. cvConvert( src, &matR );
  193. cvSVD( &matR, &matW, &matU, &matV, CV_SVD_MODIFY_A + CV_SVD_U_T + CV_SVD_V_T );
  194. cvGEMM( &matU, &matV, 1, 0, 0, &matR, CV_GEMM_A_T );
  195. cvMulTransposed( &matR, &matA, 0 );
  196. cvSetIdentity( &matI );
  197. if( cvNorm( &matA, &matI, CV_C ) > 1e-3 ||
  198. fabs( cvDet(&matR) - 1 ) > 1e-3 )
  199. return 0;
  200. tr = (cvTrace(&matR).val[0] - 1.)*0.5;
  201. tr = tr > 1. ? 1. : tr < -1. ? -1. : tr;
  202. theta = acos(tr);
  203. alpha = cos(theta);
  204. beta = sin(theta);
  205. if( beta >= 1e-5 )
  206. {
  207. double dtheta_dtr = -1./sqrt(1 - tr*tr);
  208. double vth = 1/(2*beta);
  209. // om1 = [R(3,2) - R(2,3), R(1,3) - R(3,1), R(2,1) - R(1,2)]'
  210. double om1[] = { R[7] - R[5], R[2] - R[6], R[3] - R[1] };
  211. // om = om1*vth
  212. // r = om*theta
  213. double d3 = vth*theta;
  214. r[0] = om1[0]*d3; r[1] = om1[1]*d3; r[2] = om1[2]*d3;
  215. cvConvert( &_r, dst );
  216. if( jacobian )
  217. {
  218. // var1 = [vth;theta]
  219. // var = [om1;var1] = [om1;vth;theta]
  220. double dvth_dtheta = -vth*alpha/beta;
  221. double d1 = 0.5*dvth_dtheta*dtheta_dtr;
  222. double d2 = 0.5*dtheta_dtr;
  223. // dvar1/dR = dvar1/dtheta*dtheta/dR = [dvth/dtheta; 1] * dtheta/dtr * dtr/dR
  224. double dvardR[5*9] =
  225. {
  226. 0, 0, 0, 0, 0, 1, 0, -1, 0,
  227. 0, 0, -1, 0, 0, 0, 1, 0, 0,
  228. 0, 1, 0, -1, 0, 0, 0, 0, 0,
  229. d1, 0, 0, 0, d1, 0, 0, 0, d1,
  230. d2, 0, 0, 0, d2, 0, 0, 0, d2
  231. };
  232. // var2 = [om;theta]
  233. double dvar2dvar[] =
  234. {
  235. vth, 0, 0, om1[0], 0,
  236. 0, vth, 0, om1[1], 0,
  237. 0, 0, vth, om1[2], 0,
  238. 0, 0, 0, 0, 1
  239. };
  240. double domegadvar2[] =
  241. {
  242. theta, 0, 0, om1[0]*vth,
  243. 0, theta, 0, om1[1]*vth,
  244. 0, 0, theta, om1[2]*vth
  245. };
  246. CvMat _dvardR = cvMat( 5, 9, CV_64FC1, dvardR );
  247. CvMat _dvar2dvar = cvMat( 4, 5, CV_64FC1, dvar2dvar );
  248. CvMat _domegadvar2 = cvMat( 3, 4, CV_64FC1, domegadvar2 );
  249. double t0[3*5];
  250. CvMat _t0 = cvMat( 3, 5, CV_64FC1, t0 );
  251. cvMatMul( &_domegadvar2, &_dvar2dvar, &_t0 );
  252. cvMatMul( &_t0, &_dvardR, &matJ );
  253. }
  254. }
  255. else if( tr > 0 )
  256. {
  257. cvZero( dst );
  258. if( jacobian )
  259. {
  260. memset( J, 0, sizeof(J) );
  261. J[5] = J[15] = J[19] = 0.5;
  262. J[7] = J[11] = J[21] = -0.5;
  263. }
  264. }
  265. else
  266. {
  267. r[0] = theta*sqrt((R[0] + 1)*0.5);
  268. r[1] = theta*sqrt((R[4] + 1)*0.5)*(R[1] >= 0 ? 1 : -1);
  269. r[2] = theta*sqrt((R[8] + 1)*0.5)*(R[2] >= 0 ? 1 : -1);
  270. cvConvert( &_r, dst );
  271. if( jacobian )
  272. memset( J, 0, sizeof(J) );
  273. }
  274. if( jacobian )
  275. {
  276. for( i = 0; i < 3; i++ )
  277. {
  278. CvMat t = cvMat( 3, 3, CV_64F, J + i*9 );
  279. cvTranspose( &t, &t );
  280. }
  281. }
  282. }
  283. else
  284. {
  285. CV_Assert(0);
  286. return 0;
  287. }
  288. if( jacobian )
  289. {
  290. if( depth == CV_32F )
  291. {
  292. if( jacobian->rows == matJ.rows )
  293. cvConvert( &matJ, jacobian );
  294. else
  295. {
  296. _Jf = cvMat( matJ.rows, matJ.cols, CV_32FC1, Jf );
  297. cvConvert( &matJ, &_Jf );
  298. cvTranspose( &_Jf, jacobian );
  299. }
  300. }
  301. else if( jacobian->rows == matJ.rows )
  302. cvCopy( &matJ, jacobian );
  303. else
  304. cvTranspose( &matJ, jacobian );
  305. }
  306. return 1;
  307. }
  308. /*extern*/ void Rodrigues(const Mat& src, Mat& dst, Mat* jac)
  309. {
  310. if(src.rows == 1 || src.cols == 1)
  311. dst.create(3, 3, src.depth());
  312. else
  313. dst.create(3, 1, src.depth());
  314. CvMat _src = cvMat(src), _dst = cvMat(dst), _jac;
  315. if( jac )
  316. _jac = cvMat(*jac);
  317. cvTsRodrigues(&_src, &_dst, jac ? &_jac : 0);
  318. }
  319. } // namespace
  320. namespace opencv_test {
  321. static void test_convertHomogeneous( const Mat& _src, Mat& _dst )
  322. {
  323. Mat src = _src, dst = _dst;
  324. int i, count, sdims, ddims;
  325. int sstep1, sstep2, dstep1, dstep2;
  326. if( src.depth() != CV_64F )
  327. _src.convertTo(src, CV_64F);
  328. if( dst.depth() != CV_64F )
  329. dst.create(dst.size(), CV_MAKETYPE(CV_64F, _dst.channels()));
  330. if( src.rows > src.cols )
  331. {
  332. count = src.rows;
  333. sdims = src.channels()*src.cols;
  334. sstep1 = (int)(src.step/sizeof(double));
  335. sstep2 = 1;
  336. }
  337. else
  338. {
  339. count = src.cols;
  340. sdims = src.channels()*src.rows;
  341. if( src.rows == 1 )
  342. {
  343. sstep1 = sdims;
  344. sstep2 = 1;
  345. }
  346. else
  347. {
  348. sstep1 = 1;
  349. sstep2 = (int)(src.step/sizeof(double));
  350. }
  351. }
  352. if( dst.rows > dst.cols )
  353. {
  354. CV_Assert( count == dst.rows );
  355. ddims = dst.channels()*dst.cols;
  356. dstep1 = (int)(dst.step/sizeof(double));
  357. dstep2 = 1;
  358. }
  359. else
  360. {
  361. CV_Assert( count == dst.cols );
  362. ddims = dst.channels()*dst.rows;
  363. if( dst.rows == 1 )
  364. {
  365. dstep1 = ddims;
  366. dstep2 = 1;
  367. }
  368. else
  369. {
  370. dstep1 = 1;
  371. dstep2 = (int)(dst.step/sizeof(double));
  372. }
  373. }
  374. double* s = src.ptr<double>();
  375. double* d = dst.ptr<double>();
  376. if( sdims <= ddims )
  377. {
  378. int wstep = dstep2*(ddims - 1);
  379. for( i = 0; i < count; i++, s += sstep1, d += dstep1 )
  380. {
  381. double x = s[0];
  382. double y = s[sstep2];
  383. d[wstep] = 1;
  384. d[0] = x;
  385. d[dstep2] = y;
  386. if( sdims >= 3 )
  387. {
  388. d[dstep2*2] = s[sstep2*2];
  389. if( sdims == 4 )
  390. d[dstep2*3] = s[sstep2*3];
  391. }
  392. }
  393. }
  394. else
  395. {
  396. int wstep = sstep2*(sdims - 1);
  397. for( i = 0; i < count; i++, s += sstep1, d += dstep1 )
  398. {
  399. double w = s[wstep];
  400. double x = s[0];
  401. double y = s[sstep2];
  402. w = w ? 1./w : 1;
  403. d[0] = x*w;
  404. d[dstep2] = y*w;
  405. if( ddims == 3 )
  406. d[dstep2*2] = s[sstep2*2]*w;
  407. }
  408. }
  409. if( dst.data != _dst.data )
  410. dst.convertTo(_dst, _dst.depth());
  411. }
  412. namespace {
  413. void
  414. test_projectPoints( const Mat& _3d, const Mat& Rt, const Mat& A, Mat& _2d, RNG* rng, double sigma )
  415. {
  416. CV_Assert( _3d.isContinuous() );
  417. double p[12];
  418. Mat P( 3, 4, CV_64F, p );
  419. gemm(A, Rt, 1, Mat(), 0, P);
  420. int i, count = _3d.cols;
  421. Mat noise;
  422. if( rng )
  423. {
  424. if( sigma == 0 )
  425. rng = 0;
  426. else
  427. {
  428. noise.create( 1, _3d.cols, CV_64FC2 );
  429. rng->fill(noise, RNG::NORMAL, Scalar::all(0), Scalar::all(sigma) );
  430. }
  431. }
  432. Mat temp( 1, count, CV_64FC3 );
  433. for( i = 0; i < count; i++ )
  434. {
  435. const double* M = _3d.ptr<double>() + i*3;
  436. double* m = temp.ptr<double>() + i*3;
  437. double X = M[0], Y = M[1], Z = M[2];
  438. double u = p[0]*X + p[1]*Y + p[2]*Z + p[3];
  439. double v = p[4]*X + p[5]*Y + p[6]*Z + p[7];
  440. double s = p[8]*X + p[9]*Y + p[10]*Z + p[11];
  441. if( !noise.empty() )
  442. {
  443. u += noise.at<Point2d>(i).x*s;
  444. v += noise.at<Point2d>(i).y*s;
  445. }
  446. m[0] = u;
  447. m[1] = v;
  448. m[2] = s;
  449. }
  450. test_convertHomogeneous( temp, _2d );
  451. }
  452. /********************************** Rodrigues transform ********************************/
  453. class CV_RodriguesTest : public cvtest::ArrayTest
  454. {
  455. public:
  456. CV_RodriguesTest();
  457. protected:
  458. int read_params( const cv::FileStorage& fs );
  459. void fill_array( int test_case_idx, int i, int j, Mat& arr );
  460. int prepare_test_case( int test_case_idx );
  461. void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  462. double get_success_error_level( int test_case_idx, int i, int j );
  463. void run_func();
  464. void prepare_to_validation( int );
  465. bool calc_jacobians;
  466. bool test_cpp;
  467. };
  468. CV_RodriguesTest::CV_RodriguesTest()
  469. {
  470. test_array[INPUT].push_back(NULL); // rotation vector
  471. test_array[OUTPUT].push_back(NULL); // rotation matrix
  472. test_array[OUTPUT].push_back(NULL); // jacobian (J)
  473. test_array[OUTPUT].push_back(NULL); // rotation vector (backward transform result)
  474. test_array[OUTPUT].push_back(NULL); // inverse transform jacobian (J1)
  475. test_array[OUTPUT].push_back(NULL); // J*J1 (or J1*J) == I(3x3)
  476. test_array[REF_OUTPUT].push_back(NULL);
  477. test_array[REF_OUTPUT].push_back(NULL);
  478. test_array[REF_OUTPUT].push_back(NULL);
  479. test_array[REF_OUTPUT].push_back(NULL);
  480. test_array[REF_OUTPUT].push_back(NULL);
  481. element_wise_relative_error = false;
  482. calc_jacobians = false;
  483. test_cpp = false;
  484. }
  485. int CV_RodriguesTest::read_params( const cv::FileStorage& fs )
  486. {
  487. int code = cvtest::ArrayTest::read_params( fs );
  488. return code;
  489. }
  490. void CV_RodriguesTest::get_test_array_types_and_sizes(
  491. int /*test_case_idx*/, vector<vector<Size> >& sizes, vector<vector<int> >& types )
  492. {
  493. RNG& rng = ts->get_rng();
  494. int depth = cvtest::randInt(rng) % 2 == 0 ? CV_32F : CV_64F;
  495. int i, code;
  496. code = cvtest::randInt(rng) % 3;
  497. types[INPUT][0] = CV_MAKETYPE(depth, 1);
  498. if( code == 0 )
  499. {
  500. sizes[INPUT][0] = cvSize(1,1);
  501. types[INPUT][0] = CV_MAKETYPE(depth, 3);
  502. }
  503. else if( code == 1 )
  504. sizes[INPUT][0] = cvSize(3,1);
  505. else
  506. sizes[INPUT][0] = cvSize(1,3);
  507. sizes[OUTPUT][0] = cvSize(3, 3);
  508. types[OUTPUT][0] = CV_MAKETYPE(depth, 1);
  509. types[OUTPUT][1] = CV_MAKETYPE(depth, 1);
  510. if( cvtest::randInt(rng) % 2 )
  511. sizes[OUTPUT][1] = cvSize(3,9);
  512. else
  513. sizes[OUTPUT][1] = cvSize(9,3);
  514. types[OUTPUT][2] = types[INPUT][0];
  515. sizes[OUTPUT][2] = sizes[INPUT][0];
  516. types[OUTPUT][3] = types[OUTPUT][1];
  517. sizes[OUTPUT][3] = cvSize(sizes[OUTPUT][1].height, sizes[OUTPUT][1].width);
  518. types[OUTPUT][4] = types[OUTPUT][1];
  519. sizes[OUTPUT][4] = cvSize(3,3);
  520. calc_jacobians = cvtest::randInt(rng) % 3 != 0;
  521. if( !calc_jacobians )
  522. sizes[OUTPUT][1] = sizes[OUTPUT][3] = sizes[OUTPUT][4] = cvSize(0,0);
  523. for( i = 0; i < 5; i++ )
  524. {
  525. types[REF_OUTPUT][i] = types[OUTPUT][i];
  526. sizes[REF_OUTPUT][i] = sizes[OUTPUT][i];
  527. }
  528. test_cpp = (cvtest::randInt(rng) & 256) == 0;
  529. }
  530. double CV_RodriguesTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int j )
  531. {
  532. return j == 4 ? 1e-2 : 1e-2;
  533. }
  534. void CV_RodriguesTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
  535. {
  536. if( i == INPUT && j == 0 )
  537. {
  538. double r[3], theta0, theta1, f;
  539. Mat _r( arr.rows, arr.cols, CV_MAKETYPE(CV_64F,arr.channels()), r );
  540. RNG& rng = ts->get_rng();
  541. r[0] = cvtest::randReal(rng)*CV_PI*2;
  542. r[1] = cvtest::randReal(rng)*CV_PI*2;
  543. r[2] = cvtest::randReal(rng)*CV_PI*2;
  544. theta0 = sqrt(r[0]*r[0] + r[1]*r[1] + r[2]*r[2]);
  545. theta1 = fmod(theta0, CV_PI*2);
  546. if( theta1 > CV_PI )
  547. theta1 = -(CV_PI*2 - theta1);
  548. f = theta1/(theta0 ? theta0 : 1);
  549. r[0] *= f;
  550. r[1] *= f;
  551. r[2] *= f;
  552. cvtest::convert( _r, arr, arr.type() );
  553. }
  554. else
  555. cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
  556. }
  557. int CV_RodriguesTest::prepare_test_case( int test_case_idx )
  558. {
  559. int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
  560. return code;
  561. }
  562. void CV_RodriguesTest::run_func()
  563. {
  564. cv::Mat v = test_mat[INPUT][0], M = test_mat[OUTPUT][0], v2 = test_mat[OUTPUT][2];
  565. cv::Mat M0 = M, v2_0 = v2;
  566. if( !calc_jacobians )
  567. {
  568. cv::Rodrigues(v, M);
  569. cv::Rodrigues(M, v2);
  570. }
  571. else
  572. {
  573. cv::Mat J1 = test_mat[OUTPUT][1], J2 = test_mat[OUTPUT][3];
  574. cv::Mat J1_0 = J1, J2_0 = J2;
  575. cv::Rodrigues(v, M, J1);
  576. cv::Rodrigues(M, v2, J2);
  577. if( J1.data != J1_0.data )
  578. {
  579. if( J1.size() != J1_0.size() )
  580. J1 = J1.t();
  581. J1.convertTo(J1_0, J1_0.type());
  582. }
  583. if( J2.data != J2_0.data )
  584. {
  585. if( J2.size() != J2_0.size() )
  586. J2 = J2.t();
  587. J2.convertTo(J2_0, J2_0.type());
  588. }
  589. }
  590. if( M.data != M0.data )
  591. M.reshape(M0.channels(), M0.rows).convertTo(M0, M0.type());
  592. if( v2.data != v2_0.data )
  593. v2.reshape(v2_0.channels(), v2_0.rows).convertTo(v2_0, v2_0.type());
  594. }
  595. void CV_RodriguesTest::prepare_to_validation( int /*test_case_idx*/ )
  596. {
  597. const Mat& vec = test_mat[INPUT][0];
  598. Mat& m = test_mat[REF_OUTPUT][0];
  599. Mat& vec2 = test_mat[REF_OUTPUT][2];
  600. Mat* v2m_jac = 0, *m2v_jac = 0;
  601. double theta0, theta1;
  602. if( calc_jacobians )
  603. {
  604. v2m_jac = &test_mat[REF_OUTPUT][1];
  605. m2v_jac = &test_mat[REF_OUTPUT][3];
  606. }
  607. cvtest::Rodrigues( vec, m, v2m_jac );
  608. cvtest::Rodrigues( m, vec2, m2v_jac );
  609. cvtest::copy( vec, vec2 );
  610. theta0 = cvtest::norm( vec2, CV_L2 );
  611. theta1 = fmod( theta0, CV_PI*2 );
  612. if( theta1 > CV_PI )
  613. theta1 = -(CV_PI*2 - theta1);
  614. vec2 *= theta1/(theta0 ? theta0 : 1);
  615. if( calc_jacobians )
  616. {
  617. //cvInvert( v2m_jac, m2v_jac, CV_SVD );
  618. double nrm = cvtest::norm(test_mat[REF_OUTPUT][3], CV_C);
  619. if( FLT_EPSILON < nrm && nrm < 1000 )
  620. {
  621. gemm( test_mat[OUTPUT][1], test_mat[OUTPUT][3],
  622. 1, Mat(), 0, test_mat[OUTPUT][4],
  623. v2m_jac->rows == 3 ? 0 : CV_GEMM_A_T + CV_GEMM_B_T );
  624. }
  625. else
  626. {
  627. setIdentity(test_mat[OUTPUT][4], Scalar::all(1.));
  628. cvtest::copy( test_mat[REF_OUTPUT][2], test_mat[OUTPUT][2] );
  629. }
  630. setIdentity(test_mat[REF_OUTPUT][4], Scalar::all(1.));
  631. }
  632. }
  633. /********************************** fundamental matrix *********************************/
  634. class CV_FundamentalMatTest : public cvtest::ArrayTest
  635. {
  636. public:
  637. CV_FundamentalMatTest();
  638. protected:
  639. int read_params( const cv::FileStorage& fs );
  640. void fill_array( int test_case_idx, int i, int j, Mat& arr );
  641. int prepare_test_case( int test_case_idx );
  642. void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  643. double get_success_error_level( int test_case_idx, int i, int j );
  644. void run_func();
  645. void prepare_to_validation( int );
  646. int method;
  647. int img_size;
  648. int cube_size;
  649. int dims;
  650. int f_result;
  651. double min_f, max_f;
  652. double sigma;
  653. bool test_cpp;
  654. };
  655. CV_FundamentalMatTest::CV_FundamentalMatTest()
  656. {
  657. // input arrays:
  658. // 0, 1 - arrays of 2d points that are passed to %func%.
  659. // Can have different data type, layout, be stored in homogeneous coordinates or not.
  660. // 2 - array of 3d points that are projected to both view planes
  661. // 3 - [R|t] matrix for the second view plane (for the first one it is [I|0]
  662. // 4, 5 - intrinsic matrices
  663. test_array[INPUT].push_back(NULL);
  664. test_array[INPUT].push_back(NULL);
  665. test_array[INPUT].push_back(NULL);
  666. test_array[INPUT].push_back(NULL);
  667. test_array[INPUT].push_back(NULL);
  668. test_array[INPUT].push_back(NULL);
  669. test_array[TEMP].push_back(NULL);
  670. test_array[TEMP].push_back(NULL);
  671. test_array[OUTPUT].push_back(NULL);
  672. test_array[OUTPUT].push_back(NULL);
  673. test_array[REF_OUTPUT].push_back(NULL);
  674. test_array[REF_OUTPUT].push_back(NULL);
  675. element_wise_relative_error = false;
  676. method = 0;
  677. img_size = 10;
  678. cube_size = 10;
  679. dims = 0;
  680. min_f = 1;
  681. max_f = 3;
  682. sigma = 0;//0.1;
  683. f_result = 0;
  684. test_cpp = false;
  685. }
  686. int CV_FundamentalMatTest::read_params( const cv::FileStorage& fs )
  687. {
  688. int code = cvtest::ArrayTest::read_params( fs );
  689. return code;
  690. }
  691. void CV_FundamentalMatTest::get_test_array_types_and_sizes( int /*test_case_idx*/,
  692. vector<vector<Size> >& sizes, vector<vector<int> >& types )
  693. {
  694. RNG& rng = ts->get_rng();
  695. int pt_depth = cvtest::randInt(rng) % 2 == 0 ? CV_32F : CV_64F;
  696. double pt_count_exp = cvtest::randReal(rng)*6 + 1;
  697. int pt_count = cvRound(exp(pt_count_exp));
  698. dims = cvtest::randInt(rng) % 2 + 2;
  699. method = 1 << (cvtest::randInt(rng) % 4);
  700. if( method == CV_FM_7POINT )
  701. pt_count = 7;
  702. else
  703. {
  704. pt_count = MAX( pt_count, 8 + (method == CV_FM_8POINT) );
  705. if( pt_count >= 8 && cvtest::randInt(rng) % 2 )
  706. method |= CV_FM_8POINT;
  707. }
  708. types[INPUT][0] = CV_MAKETYPE(pt_depth, 1);
  709. sizes[INPUT][0] = cvSize(dims, pt_count);
  710. if( cvtest::randInt(rng) % 2 )
  711. {
  712. types[INPUT][0] = CV_MAKETYPE(pt_depth, dims);
  713. if( cvtest::randInt(rng) % 2 )
  714. sizes[INPUT][0] = cvSize(pt_count, 1);
  715. else
  716. sizes[INPUT][0] = cvSize(1, pt_count);
  717. }
  718. sizes[INPUT][1] = sizes[INPUT][0];
  719. types[INPUT][1] = types[INPUT][0];
  720. sizes[INPUT][2] = cvSize(pt_count, 1 );
  721. types[INPUT][2] = CV_64FC3;
  722. sizes[INPUT][3] = cvSize(4,3);
  723. types[INPUT][3] = CV_64FC1;
  724. sizes[INPUT][4] = sizes[INPUT][5] = cvSize(3,3);
  725. types[INPUT][4] = types[INPUT][5] = CV_MAKETYPE(CV_64F, 1);
  726. sizes[TEMP][0] = cvSize(3,3);
  727. types[TEMP][0] = CV_64FC1;
  728. sizes[TEMP][1] = cvSize(pt_count,1);
  729. types[TEMP][1] = CV_8UC1;
  730. sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(3,1);
  731. types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC1;
  732. sizes[OUTPUT][1] = sizes[REF_OUTPUT][1] = cvSize(pt_count,1);
  733. types[OUTPUT][1] = types[REF_OUTPUT][1] = CV_8UC1;
  734. test_cpp = (cvtest::randInt(rng) & 256) == 0;
  735. }
  736. double CV_FundamentalMatTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
  737. {
  738. return 1e-2;
  739. }
  740. void CV_FundamentalMatTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
  741. {
  742. double t[12]={0};
  743. RNG& rng = ts->get_rng();
  744. if( i != INPUT )
  745. {
  746. cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
  747. return;
  748. }
  749. switch( j )
  750. {
  751. case 0:
  752. case 1:
  753. return; // fill them later in prepare_test_case
  754. case 2:
  755. {
  756. double* p = arr.ptr<double>();
  757. for( i = 0; i < arr.cols*3; i += 3 )
  758. {
  759. p[i] = cvtest::randReal(rng)*cube_size;
  760. p[i+1] = cvtest::randReal(rng)*cube_size;
  761. p[i+2] = cvtest::randReal(rng)*cube_size + cube_size;
  762. }
  763. }
  764. break;
  765. case 3:
  766. {
  767. double r[3];
  768. Mat rot_vec( 3, 1, CV_64F, r );
  769. Mat rot_mat( 3, 3, CV_64F, t, 4*sizeof(t[0]) );
  770. r[0] = cvtest::randReal(rng)*CV_PI*2;
  771. r[1] = cvtest::randReal(rng)*CV_PI*2;
  772. r[2] = cvtest::randReal(rng)*CV_PI*2;
  773. cvtest::Rodrigues( rot_vec, rot_mat );
  774. t[3] = cvtest::randReal(rng)*cube_size;
  775. t[7] = cvtest::randReal(rng)*cube_size;
  776. t[11] = cvtest::randReal(rng)*cube_size;
  777. Mat( 3, 4, CV_64F, t ).convertTo(arr, arr.type());
  778. }
  779. break;
  780. case 4:
  781. case 5:
  782. t[0] = t[4] = cvtest::randReal(rng)*(max_f - min_f) + min_f;
  783. t[2] = (img_size*0.5 + cvtest::randReal(rng)*4. - 2.)*t[0];
  784. t[5] = (img_size*0.5 + cvtest::randReal(rng)*4. - 2.)*t[4];
  785. t[8] = 1.;
  786. Mat( 3, 3, CV_64F, t ).convertTo( arr, arr.type() );
  787. break;
  788. }
  789. }
  790. int CV_FundamentalMatTest::prepare_test_case( int test_case_idx )
  791. {
  792. int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
  793. if( code > 0 )
  794. {
  795. const Mat& _3d = test_mat[INPUT][2];
  796. RNG& rng = ts->get_rng();
  797. double Idata[] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 };
  798. Mat I( 3, 4, CV_64F, Idata );
  799. int k;
  800. for( k = 0; k < 2; k++ )
  801. {
  802. const Mat& Rt = k == 0 ? I : test_mat[INPUT][3];
  803. const Mat& A = test_mat[INPUT][k == 0 ? 4 : 5];
  804. Mat& _2d = test_mat[INPUT][k];
  805. test_projectPoints( _3d, Rt, A, _2d, &rng, sigma );
  806. }
  807. }
  808. return code;
  809. }
  810. void CV_FundamentalMatTest::run_func()
  811. {
  812. // cvFindFundamentalMat calls cv::findFundamentalMat
  813. cv::Mat _input0 = test_mat[INPUT][0], _input1 = test_mat[INPUT][1];
  814. cv::Mat& F = test_mat[TEMP][0], &mask = test_mat[TEMP][1];
  815. F = cv::findFundamentalMat( _input0, _input1, method, MAX(sigma*3, 0.01), 0, mask );
  816. f_result = !F.empty();
  817. }
  818. void CV_FundamentalMatTest::prepare_to_validation( int test_case_idx )
  819. {
  820. const Mat& Rt = test_mat[INPUT][3];
  821. const Mat& A1 = test_mat[INPUT][4];
  822. const Mat& A2 = test_mat[INPUT][5];
  823. double f0[9], f[9];
  824. Mat F0(3, 3, CV_64FC1, f0), F(3, 3, CV_64F, f);
  825. Mat invA1, invA2, R=Rt.colRange(0, 3), T;
  826. cv::invert(A1, invA1, CV_SVD);
  827. cv::invert(A2, invA2, CV_SVD);
  828. double tx = Rt.at<double>(0, 3);
  829. double ty = Rt.at<double>(1, 3);
  830. double tz = Rt.at<double>(2, 3);
  831. double _t_x[] = { 0, -tz, ty, tz, 0, -tx, -ty, tx, 0 };
  832. // F = (A2^-T)*[t]_x*R*(A1^-1)
  833. cv::gemm( invA2, Mat( 3, 3, CV_64F, _t_x ), 1, Mat(), 0, T, CV_GEMM_A_T );
  834. cv::gemm( R, invA1, 1, Mat(), 0, invA2 );
  835. cv::gemm( T, invA2, 1, Mat(), 0, F0 );
  836. F0 *= 1./f0[8];
  837. uchar* status = test_mat[TEMP][1].ptr();
  838. double err_level = get_success_error_level( test_case_idx, OUTPUT, 1 );
  839. uchar* mtfm1 = test_mat[REF_OUTPUT][1].ptr();
  840. uchar* mtfm2 = test_mat[OUTPUT][1].ptr();
  841. double* f_prop1 = test_mat[REF_OUTPUT][0].ptr<double>();
  842. double* f_prop2 = test_mat[OUTPUT][0].ptr<double>();
  843. int i, pt_count = test_mat[INPUT][2].cols;
  844. Mat p1( 1, pt_count, CV_64FC2 );
  845. Mat p2( 1, pt_count, CV_64FC2 );
  846. test_convertHomogeneous( test_mat[INPUT][0], p1 );
  847. test_convertHomogeneous( test_mat[INPUT][1], p2 );
  848. Mat Fsrc = test_mat[TEMP][0];
  849. if( Fsrc.rows > 3 )
  850. Fsrc = Fsrc.rowRange(0, 3);
  851. cvtest::convert(Fsrc, F, F.type());
  852. if( method <= CV_FM_8POINT )
  853. memset( status, 1, pt_count );
  854. for( i = 0; i < pt_count; i++ )
  855. {
  856. double x1 = p1.at<Point2d>(i).x;
  857. double y1 = p1.at<Point2d>(i).y;
  858. double x2 = p2.at<Point2d>(i).x;
  859. double y2 = p2.at<Point2d>(i).y;
  860. double n1 = 1./sqrt(x1*x1 + y1*y1 + 1);
  861. double n2 = 1./sqrt(x2*x2 + y2*y2 + 1);
  862. double t0 = fabs(f0[0]*x2*x1 + f0[1]*x2*y1 + f0[2]*x2 +
  863. f0[3]*y2*x1 + f0[4]*y2*y1 + f0[5]*y2 +
  864. f0[6]*x1 + f0[7]*y1 + f0[8])*n1*n2;
  865. double t = fabs(f[0]*x2*x1 + f[1]*x2*y1 + f[2]*x2 +
  866. f[3]*y2*x1 + f[4]*y2*y1 + f[5]*y2 +
  867. f[6]*x1 + f[7]*y1 + f[8])*n1*n2;
  868. mtfm1[i] = 1;
  869. mtfm2[i] = !status[i] || t0 > err_level || t < err_level;
  870. }
  871. f_prop1[0] = 1;
  872. f_prop1[1] = 1;
  873. f_prop1[2] = 0;
  874. f_prop2[0] = f_result != 0;
  875. f_prop2[1] = f[8];
  876. f_prop2[2] = cv::determinant( F );
  877. }
  878. /******************************* find essential matrix ***********************************/
  879. class CV_EssentialMatTest : public cvtest::ArrayTest
  880. {
  881. public:
  882. CV_EssentialMatTest();
  883. protected:
  884. int read_params( const cv::FileStorage& fs );
  885. void fill_array( int test_case_idx, int i, int j, Mat& arr );
  886. int prepare_test_case( int test_case_idx );
  887. void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  888. double get_success_error_level( int test_case_idx, int i, int j );
  889. void run_func();
  890. void prepare_to_validation( int );
  891. #if 0
  892. double sampson_error(const double* f, double x1, double y1, double x2, double y2);
  893. #endif
  894. int method;
  895. int img_size;
  896. int cube_size;
  897. int dims;
  898. double min_f, max_f;
  899. double sigma;
  900. };
  901. CV_EssentialMatTest::CV_EssentialMatTest()
  902. {
  903. // input arrays:
  904. // 0, 1 - arrays of 2d points that are passed to %func%.
  905. // Can have different data type, layout, be stored in homogeneous coordinates or not.
  906. // 2 - array of 3d points that are projected to both view planes
  907. // 3 - [R|t] matrix for the second view plane (for the first one it is [I|0]
  908. // 4 - intrinsic matrix for both camera
  909. test_array[INPUT].push_back(NULL);
  910. test_array[INPUT].push_back(NULL);
  911. test_array[INPUT].push_back(NULL);
  912. test_array[INPUT].push_back(NULL);
  913. test_array[INPUT].push_back(NULL);
  914. test_array[TEMP].push_back(NULL);
  915. test_array[TEMP].push_back(NULL);
  916. test_array[TEMP].push_back(NULL);
  917. test_array[TEMP].push_back(NULL);
  918. test_array[TEMP].push_back(NULL);
  919. test_array[OUTPUT].push_back(NULL); // Essential Matrix singularity
  920. test_array[OUTPUT].push_back(NULL); // Inliers mask
  921. test_array[OUTPUT].push_back(NULL); // Translation error
  922. test_array[OUTPUT].push_back(NULL); // Positive depth count
  923. test_array[REF_OUTPUT].push_back(NULL);
  924. test_array[REF_OUTPUT].push_back(NULL);
  925. test_array[REF_OUTPUT].push_back(NULL);
  926. test_array[REF_OUTPUT].push_back(NULL);
  927. element_wise_relative_error = false;
  928. method = 0;
  929. img_size = 10;
  930. cube_size = 10;
  931. dims = 0;
  932. min_f = 1;
  933. max_f = 3;
  934. sigma = 0;
  935. }
  936. int CV_EssentialMatTest::read_params( const cv::FileStorage& fs )
  937. {
  938. int code = cvtest::ArrayTest::read_params( fs );
  939. return code;
  940. }
  941. void CV_EssentialMatTest::get_test_array_types_and_sizes( int /*test_case_idx*/,
  942. vector<vector<Size> >& sizes, vector<vector<int> >& types )
  943. {
  944. RNG& rng = ts->get_rng();
  945. int pt_depth = cvtest::randInt(rng) % 2 == 0 ? CV_32F : CV_64F;
  946. double pt_count_exp = cvtest::randReal(rng)*6 + 1;
  947. int pt_count = MAX(5, cvRound(exp(pt_count_exp)));
  948. dims = cvtest::randInt(rng) % 2 + 2;
  949. dims = 2;
  950. method = CV_LMEDS << (cvtest::randInt(rng) % 2);
  951. types[INPUT][0] = CV_MAKETYPE(pt_depth, 1);
  952. sizes[INPUT][0] = cvSize(dims, pt_count);
  953. if( cvtest::randInt(rng) % 2 )
  954. {
  955. types[INPUT][0] = CV_MAKETYPE(pt_depth, dims);
  956. if( cvtest::randInt(rng) % 2 )
  957. sizes[INPUT][0] = cvSize(pt_count, 1);
  958. else
  959. sizes[INPUT][0] = cvSize(1, pt_count);
  960. }
  961. sizes[INPUT][1] = sizes[INPUT][0];
  962. types[INPUT][1] = types[INPUT][0];
  963. sizes[INPUT][2] = cvSize(pt_count, 1 );
  964. types[INPUT][2] = CV_64FC3;
  965. sizes[INPUT][3] = cvSize(4,3);
  966. types[INPUT][3] = CV_64FC1;
  967. sizes[INPUT][4] = cvSize(3,3);
  968. types[INPUT][4] = CV_MAKETYPE(CV_64F, 1);
  969. sizes[TEMP][0] = cvSize(3,3);
  970. types[TEMP][0] = CV_64FC1;
  971. sizes[TEMP][1] = cvSize(pt_count,1);
  972. types[TEMP][1] = CV_8UC1;
  973. sizes[TEMP][2] = cvSize(3,3);
  974. types[TEMP][2] = CV_64FC1;
  975. sizes[TEMP][3] = cvSize(3, 1);
  976. types[TEMP][3] = CV_64FC1;
  977. sizes[TEMP][4] = cvSize(pt_count,1);
  978. types[TEMP][4] = CV_8UC1;
  979. sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(3,1);
  980. types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC1;
  981. sizes[OUTPUT][1] = sizes[REF_OUTPUT][1] = cvSize(pt_count,1);
  982. types[OUTPUT][1] = types[REF_OUTPUT][1] = CV_8UC1;
  983. sizes[OUTPUT][2] = sizes[REF_OUTPUT][2] = cvSize(1,1);
  984. types[OUTPUT][2] = types[REF_OUTPUT][2] = CV_64FC1;
  985. sizes[OUTPUT][3] = sizes[REF_OUTPUT][3] = cvSize(1,1);
  986. types[OUTPUT][3] = types[REF_OUTPUT][3] = CV_8UC1;
  987. }
  988. double CV_EssentialMatTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
  989. {
  990. return 1e-2;
  991. }
  992. void CV_EssentialMatTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
  993. {
  994. double t[12]={0};
  995. RNG& rng = ts->get_rng();
  996. if( i != INPUT )
  997. {
  998. cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
  999. return;
  1000. }
  1001. switch( j )
  1002. {
  1003. case 0:
  1004. case 1:
  1005. return; // fill them later in prepare_test_case
  1006. case 2:
  1007. {
  1008. double* p = arr.ptr<double>();
  1009. for( i = 0; i < arr.cols*3; i += 3 )
  1010. {
  1011. p[i] = cvtest::randReal(rng)*cube_size;
  1012. p[i+1] = cvtest::randReal(rng)*cube_size;
  1013. p[i+2] = cvtest::randReal(rng)*cube_size + cube_size;
  1014. }
  1015. }
  1016. break;
  1017. case 3:
  1018. {
  1019. double r[3];
  1020. Mat rot_vec( 3, 1, CV_64F, r );
  1021. Mat rot_mat( 3, 3, CV_64F, t, 4*sizeof(t[0]) );
  1022. r[0] = cvtest::randReal(rng)*CV_PI*2;
  1023. r[1] = cvtest::randReal(rng)*CV_PI*2;
  1024. r[2] = cvtest::randReal(rng)*CV_PI*2;
  1025. cvtest::Rodrigues( rot_vec, rot_mat );
  1026. t[3] = cvtest::randReal(rng)*cube_size;
  1027. t[7] = cvtest::randReal(rng)*cube_size;
  1028. t[11] = cvtest::randReal(rng)*cube_size;
  1029. Mat( 3, 4, CV_64F, t ).convertTo(arr, arr.type());
  1030. }
  1031. break;
  1032. case 4:
  1033. t[0] = t[4] = cvtest::randReal(rng)*(max_f - min_f) + min_f;
  1034. t[2] = (img_size*0.5 + cvtest::randReal(rng)*4. - 2.)*t[0];
  1035. t[5] = (img_size*0.5 + cvtest::randReal(rng)*4. - 2.)*t[4];
  1036. t[8] = 1.;
  1037. Mat( 3, 3, CV_64F, t ).convertTo( arr, arr.type() );
  1038. break;
  1039. }
  1040. }
  1041. int CV_EssentialMatTest::prepare_test_case( int test_case_idx )
  1042. {
  1043. int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
  1044. if( code > 0 )
  1045. {
  1046. const Mat& _3d = test_mat[INPUT][2];
  1047. RNG& rng = ts->get_rng();
  1048. double Idata[] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 };
  1049. Mat I( 3, 4, CV_64F, Idata );
  1050. int k;
  1051. for( k = 0; k < 2; k++ )
  1052. {
  1053. const Mat& Rt = k == 0 ? I : test_mat[INPUT][3];
  1054. const Mat& A = test_mat[INPUT][4];
  1055. Mat& _2d = test_mat[INPUT][k];
  1056. test_projectPoints( _3d, Rt, A, _2d, &rng, sigma );
  1057. }
  1058. }
  1059. return code;
  1060. }
  1061. void CV_EssentialMatTest::run_func()
  1062. {
  1063. Mat _input0(test_mat[INPUT][0]), _input1(test_mat[INPUT][1]);
  1064. Mat K(test_mat[INPUT][4]);
  1065. double focal(K.at<double>(0, 0));
  1066. cv::Point2d pp(K.at<double>(0, 2), K.at<double>(1, 2));
  1067. RNG& rng = ts->get_rng();
  1068. Mat E, mask1(test_mat[TEMP][1]);
  1069. E = cv::findEssentialMat( _input0, _input1, focal, pp, method, 0.99, MAX(sigma*3, 0.0001), mask1 );
  1070. if (E.rows > 3)
  1071. {
  1072. int count = E.rows / 3;
  1073. int row = (cvtest::randInt(rng) % count) * 3;
  1074. E = E.rowRange(row, row + 3) * 1.0;
  1075. }
  1076. E.copyTo(test_mat[TEMP][0]);
  1077. Mat R, t, mask2;
  1078. recoverPose( E, _input0, _input1, R, t, focal, pp, mask2 );
  1079. R.copyTo(test_mat[TEMP][2]);
  1080. t.copyTo(test_mat[TEMP][3]);
  1081. mask2.copyTo(test_mat[TEMP][4]);
  1082. }
  1083. #if 0
  1084. double CV_EssentialMatTest::sampson_error(const double * f, double x1, double y1, double x2, double y2)
  1085. {
  1086. double Fx1[3] = {
  1087. f[0] * x1 + f[1] * y1 + f[2],
  1088. f[3] * x1 + f[4] * y1 + f[5],
  1089. f[6] * x1 + f[7] * y1 + f[8]
  1090. };
  1091. double Ftx2[3] = {
  1092. f[0] * x2 + f[3] * y2 + f[6],
  1093. f[1] * x2 + f[4] * y2 + f[7],
  1094. f[2] * x2 + f[5] * y2 + f[8]
  1095. };
  1096. double x2tFx1 = Fx1[0] * x2 + Fx1[1] * y2 + Fx1[2];
  1097. double error = x2tFx1 * x2tFx1 / (Fx1[0] * Fx1[0] + Fx1[1] * Fx1[1] + Ftx2[0] * Ftx2[0] + Ftx2[1] * Ftx2[1]);
  1098. error = sqrt(error);
  1099. return error;
  1100. }
  1101. #endif
  1102. void CV_EssentialMatTest::prepare_to_validation( int test_case_idx )
  1103. {
  1104. const Mat& Rt0 = test_mat[INPUT][3];
  1105. const Mat& A = test_mat[INPUT][4];
  1106. double f0[9], f[9], e[9];
  1107. Mat F0(3, 3, CV_64FC1, f0), F(3, 3, CV_64F, f);
  1108. Mat E(3, 3, CV_64F, e);
  1109. Mat invA, R=Rt0.colRange(0, 3), T1, T2;
  1110. cv::invert(A, invA, CV_SVD);
  1111. double tx = Rt0.at<double>(0, 3);
  1112. double ty = Rt0.at<double>(1, 3);
  1113. double tz = Rt0.at<double>(2, 3);
  1114. double _t_x[] = { 0, -tz, ty, tz, 0, -tx, -ty, tx, 0 };
  1115. // F = (A2^-T)*[t]_x*R*(A1^-1)
  1116. cv::gemm( invA, Mat( 3, 3, CV_64F, _t_x ), 1, Mat(), 0, T1, CV_GEMM_A_T );
  1117. cv::gemm( R, invA, 1, Mat(), 0, T2 );
  1118. cv::gemm( T1, T2, 1, Mat(), 0, F0 );
  1119. F0 *= 1./f0[8];
  1120. uchar* status = test_mat[TEMP][1].ptr();
  1121. double err_level = get_success_error_level( test_case_idx, OUTPUT, 1 );
  1122. uchar* mtfm1 = test_mat[REF_OUTPUT][1].ptr();
  1123. uchar* mtfm2 = test_mat[OUTPUT][1].ptr();
  1124. double* e_prop1 = test_mat[REF_OUTPUT][0].ptr<double>();
  1125. double* e_prop2 = test_mat[OUTPUT][0].ptr<double>();
  1126. Mat E_prop2 = Mat(3, 1, CV_64F, e_prop2);
  1127. int i, pt_count = test_mat[INPUT][2].cols;
  1128. Mat p1( 1, pt_count, CV_64FC2 );
  1129. Mat p2( 1, pt_count, CV_64FC2 );
  1130. test_convertHomogeneous( test_mat[INPUT][0], p1 );
  1131. test_convertHomogeneous( test_mat[INPUT][1], p2 );
  1132. cvtest::convert(test_mat[TEMP][0], E, E.type());
  1133. cv::gemm( invA, E, 1, Mat(), 0, T1, CV_GEMM_A_T );
  1134. cv::gemm( T1, invA, 1, Mat(), 0, F );
  1135. for( i = 0; i < pt_count; i++ )
  1136. {
  1137. double x1 = p1.at<Point2d>(i).x;
  1138. double y1 = p1.at<Point2d>(i).y;
  1139. double x2 = p2.at<Point2d>(i).x;
  1140. double y2 = p2.at<Point2d>(i).y;
  1141. // double t0 = sampson_error(f0, x1, y1, x2, y2);
  1142. // double t = sampson_error(f, x1, y1, x2, y2);
  1143. double n1 = 1./sqrt(x1*x1 + y1*y1 + 1);
  1144. double n2 = 1./sqrt(x2*x2 + y2*y2 + 1);
  1145. double t0 = fabs(f0[0]*x2*x1 + f0[1]*x2*y1 + f0[2]*x2 +
  1146. f0[3]*y2*x1 + f0[4]*y2*y1 + f0[5]*y2 +
  1147. f0[6]*x1 + f0[7]*y1 + f0[8])*n1*n2;
  1148. double t = fabs(f[0]*x2*x1 + f[1]*x2*y1 + f[2]*x2 +
  1149. f[3]*y2*x1 + f[4]*y2*y1 + f[5]*y2 +
  1150. f[6]*x1 + f[7]*y1 + f[8])*n1*n2;
  1151. mtfm1[i] = 1;
  1152. mtfm2[i] = !status[i] || t0 > err_level || t < err_level;
  1153. }
  1154. e_prop1[0] = sqrt(0.5);
  1155. e_prop1[1] = sqrt(0.5);
  1156. e_prop1[2] = 0;
  1157. e_prop2[0] = 0;
  1158. e_prop2[1] = 0;
  1159. e_prop2[2] = 0;
  1160. SVD::compute(E, E_prop2);
  1161. double* pose_prop1 = test_mat[REF_OUTPUT][2].ptr<double>();
  1162. double* pose_prop2 = test_mat[OUTPUT][2].ptr<double>();
  1163. double terr1 = cvtest::norm(Rt0.col(3) / cvtest::norm(Rt0.col(3), NORM_L2) + test_mat[TEMP][3], NORM_L2);
  1164. double terr2 = cvtest::norm(Rt0.col(3) / cvtest::norm(Rt0.col(3), NORM_L2) - test_mat[TEMP][3], NORM_L2);
  1165. Mat rvec(3, 1, CV_32F);
  1166. cvtest::Rodrigues(Rt0.colRange(0, 3), rvec);
  1167. pose_prop1[0] = 0;
  1168. // No check for CV_LMeDS on translation. Since it
  1169. // involves with some degraded problem, when data is exact inliers.
  1170. pose_prop2[0] = method == CV_LMEDS || pt_count == 5 ? 0 : MIN(terr1, terr2);
  1171. // int inliers_count = countNonZero(test_mat[TEMP][1]);
  1172. // int good_count = countNonZero(test_mat[TEMP][4]);
  1173. test_mat[OUTPUT][3] = true; //good_count >= inliers_count / 2;
  1174. test_mat[REF_OUTPUT][3] = true;
  1175. }
  1176. /********************************** convert homogeneous *********************************/
  1177. class CV_ConvertHomogeneousTest : public cvtest::ArrayTest
  1178. {
  1179. public:
  1180. CV_ConvertHomogeneousTest();
  1181. protected:
  1182. int read_params( const cv::FileStorage& fs );
  1183. void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  1184. void fill_array( int test_case_idx, int i, int j, Mat& arr );
  1185. double get_success_error_level( int test_case_idx, int i, int j );
  1186. void run_func();
  1187. void prepare_to_validation( int );
  1188. int dims1, dims2;
  1189. int pt_count;
  1190. };
  1191. CV_ConvertHomogeneousTest::CV_ConvertHomogeneousTest()
  1192. {
  1193. test_array[INPUT].push_back(NULL);
  1194. test_array[OUTPUT].push_back(NULL);
  1195. test_array[REF_OUTPUT].push_back(NULL);
  1196. element_wise_relative_error = false;
  1197. pt_count = dims1 = dims2 = 0;
  1198. }
  1199. int CV_ConvertHomogeneousTest::read_params( const cv::FileStorage& fs )
  1200. {
  1201. int code = cvtest::ArrayTest::read_params( fs );
  1202. return code;
  1203. }
  1204. void CV_ConvertHomogeneousTest::get_test_array_types_and_sizes( int /*test_case_idx*/,
  1205. vector<vector<Size> >& sizes, vector<vector<int> >& types )
  1206. {
  1207. RNG& rng = ts->get_rng();
  1208. int pt_depth1 = cvtest::randInt(rng) % 2 == 0 ? CV_32F : CV_64F;
  1209. int pt_depth2 = pt_depth1;//cvtest::randInt(rng) % 2 == 0 ? CV_32F : CV_64F;
  1210. double pt_count_exp = cvtest::randReal(rng)*6 + 1;
  1211. int t;
  1212. pt_count = cvRound(exp(pt_count_exp));
  1213. pt_count = MAX( pt_count, 5 );
  1214. dims1 = 2 + (cvtest::randInt(rng) % 2);
  1215. dims2 = dims1 + 1;
  1216. if( cvtest::randInt(rng) % 2 )
  1217. CV_SWAP( dims1, dims2, t );
  1218. types[INPUT][0] = CV_MAKETYPE(pt_depth1, 1);
  1219. sizes[INPUT][0] = cvSize(dims1, pt_count);
  1220. if( cvtest::randInt(rng) % 2 )
  1221. {
  1222. types[INPUT][0] = CV_MAKETYPE(pt_depth1, dims1);
  1223. if( cvtest::randInt(rng) % 2 )
  1224. sizes[INPUT][0] = cvSize(pt_count, 1);
  1225. else
  1226. sizes[INPUT][0] = cvSize(1, pt_count);
  1227. }
  1228. types[OUTPUT][0] = CV_MAKETYPE(pt_depth2, dims2);
  1229. sizes[OUTPUT][0] = cvSize(1, pt_count);
  1230. types[REF_OUTPUT][0] = types[OUTPUT][0];
  1231. sizes[REF_OUTPUT][0] = sizes[OUTPUT][0];
  1232. }
  1233. double CV_ConvertHomogeneousTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
  1234. {
  1235. return 1e-5;
  1236. }
  1237. void CV_ConvertHomogeneousTest::fill_array( int /*test_case_idx*/, int /*i*/, int /*j*/, Mat& arr )
  1238. {
  1239. Mat temp( 1, pt_count, CV_MAKETYPE(CV_64FC1,dims1) );
  1240. RNG& rng = ts->get_rng();
  1241. CvScalar low = cvScalarAll(0), high = cvScalarAll(10);
  1242. if( dims1 > dims2 )
  1243. low.val[dims1-1] = 1.;
  1244. cvtest::randUni( rng, temp, low, high );
  1245. test_convertHomogeneous( temp, arr );
  1246. }
  1247. void CV_ConvertHomogeneousTest::run_func()
  1248. {
  1249. cv::Mat _input = test_mat[INPUT][0], &_output = test_mat[OUTPUT][0];
  1250. if( dims1 > dims2 )
  1251. cv::convertPointsFromHomogeneous(_input, _output);
  1252. else
  1253. cv::convertPointsToHomogeneous(_input, _output);
  1254. }
  1255. void CV_ConvertHomogeneousTest::prepare_to_validation( int /*test_case_idx*/ )
  1256. {
  1257. test_convertHomogeneous( test_mat[INPUT][0], test_mat[REF_OUTPUT][0] );
  1258. }
  1259. /************************** compute corresponding epipolar lines ************************/
  1260. class CV_ComputeEpilinesTest : public cvtest::ArrayTest
  1261. {
  1262. public:
  1263. CV_ComputeEpilinesTest();
  1264. protected:
  1265. int read_params( const cv::FileStorage& fs );
  1266. void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  1267. void fill_array( int test_case_idx, int i, int j, Mat& arr );
  1268. double get_success_error_level( int test_case_idx, int i, int j );
  1269. void run_func();
  1270. void prepare_to_validation( int );
  1271. int which_image;
  1272. int dims;
  1273. int pt_count;
  1274. };
  1275. CV_ComputeEpilinesTest::CV_ComputeEpilinesTest()
  1276. {
  1277. test_array[INPUT].push_back(NULL);
  1278. test_array[INPUT].push_back(NULL);
  1279. test_array[OUTPUT].push_back(NULL);
  1280. test_array[REF_OUTPUT].push_back(NULL);
  1281. element_wise_relative_error = false;
  1282. pt_count = dims = which_image = 0;
  1283. }
  1284. int CV_ComputeEpilinesTest::read_params( const cv::FileStorage& fs )
  1285. {
  1286. int code = cvtest::ArrayTest::read_params( fs );
  1287. return code;
  1288. }
  1289. void CV_ComputeEpilinesTest::get_test_array_types_and_sizes( int /*test_case_idx*/,
  1290. vector<vector<Size> >& sizes, vector<vector<int> >& types )
  1291. {
  1292. RNG& rng = ts->get_rng();
  1293. int fm_depth = cvtest::randInt(rng) % 2 == 0 ? CV_32F : CV_64F;
  1294. int pt_depth = cvtest::randInt(rng) % 2 == 0 ? CV_32F : CV_64F;
  1295. int ln_depth = pt_depth;
  1296. double pt_count_exp = cvtest::randReal(rng)*6;
  1297. which_image = 1 + (cvtest::randInt(rng) % 2);
  1298. pt_count = cvRound(exp(pt_count_exp));
  1299. pt_count = MAX( pt_count, 1 );
  1300. bool few_points = pt_count < 5;
  1301. dims = 2 + (cvtest::randInt(rng) % 2);
  1302. types[INPUT][0] = CV_MAKETYPE(pt_depth, 1);
  1303. sizes[INPUT][0] = cvSize(dims, pt_count);
  1304. if( cvtest::randInt(rng) % 2 || few_points )
  1305. {
  1306. types[INPUT][0] = CV_MAKETYPE(pt_depth, dims);
  1307. if( cvtest::randInt(rng) % 2 )
  1308. sizes[INPUT][0] = cvSize(pt_count, 1);
  1309. else
  1310. sizes[INPUT][0] = cvSize(1, pt_count);
  1311. }
  1312. types[INPUT][1] = CV_MAKETYPE(fm_depth, 1);
  1313. sizes[INPUT][1] = cvSize(3, 3);
  1314. types[OUTPUT][0] = CV_MAKETYPE(ln_depth, 3);
  1315. sizes[OUTPUT][0] = cvSize(1, pt_count);
  1316. types[REF_OUTPUT][0] = types[OUTPUT][0];
  1317. sizes[REF_OUTPUT][0] = sizes[OUTPUT][0];
  1318. }
  1319. double CV_ComputeEpilinesTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
  1320. {
  1321. return 1e-5;
  1322. }
  1323. void CV_ComputeEpilinesTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
  1324. {
  1325. RNG& rng = ts->get_rng();
  1326. if( i == INPUT && j == 0 )
  1327. {
  1328. Mat temp( 1, pt_count, CV_MAKETYPE(CV_64FC1,dims) );
  1329. cvtest::randUni( rng, temp, cvScalar(0,0,1), cvScalarAll(10) );
  1330. test_convertHomogeneous( temp, arr );
  1331. }
  1332. else if( i == INPUT && j == 1 )
  1333. cvtest::randUni( rng, arr, cvScalarAll(0), cvScalarAll(10) );
  1334. else
  1335. cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
  1336. }
  1337. void CV_ComputeEpilinesTest::run_func()
  1338. {
  1339. cv::Mat _points = test_mat[INPUT][0], _F = test_mat[INPUT][1], &_lines = test_mat[OUTPUT][0];
  1340. cv::computeCorrespondEpilines( _points, which_image, _F, _lines );
  1341. }
  1342. void CV_ComputeEpilinesTest::prepare_to_validation( int /*test_case_idx*/ )
  1343. {
  1344. Mat pt( 1, pt_count, CV_MAKETYPE(CV_64F, 3) );
  1345. Mat lines( 1, pt_count, CV_MAKETYPE(CV_64F, 3) );
  1346. double f[9];
  1347. Mat F( 3, 3, CV_64F, f );
  1348. test_convertHomogeneous( test_mat[INPUT][0], pt );
  1349. test_mat[INPUT][1].convertTo(F, CV_64F);
  1350. if( which_image == 2 )
  1351. cv::transpose( F, F );
  1352. for( int i = 0; i < pt_count; i++ )
  1353. {
  1354. double* p = pt.ptr<double>() + i*3;
  1355. double* l = lines.ptr<double>() + i*3;
  1356. double t0 = f[0]*p[0] + f[1]*p[1] + f[2]*p[2];
  1357. double t1 = f[3]*p[0] + f[4]*p[1] + f[5]*p[2];
  1358. double t2 = f[6]*p[0] + f[7]*p[1] + f[8]*p[2];
  1359. double d = sqrt(t0*t0 + t1*t1);
  1360. d = d ? 1./d : 1.;
  1361. l[0] = t0*d; l[1] = t1*d; l[2] = t2*d;
  1362. }
  1363. test_convertHomogeneous( lines, test_mat[REF_OUTPUT][0] );
  1364. }
  1365. TEST(Calib3d_Rodrigues, accuracy) { CV_RodriguesTest test; test.safe_run(); }
  1366. TEST(Calib3d_FindFundamentalMat, accuracy) { CV_FundamentalMatTest test; test.safe_run(); }
  1367. TEST(Calib3d_ConvertHomogeneoous, accuracy) { CV_ConvertHomogeneousTest test; test.safe_run(); }
  1368. TEST(Calib3d_ComputeEpilines, accuracy) { CV_ComputeEpilinesTest test; test.safe_run(); }
  1369. TEST(Calib3d_FindEssentialMat, accuracy) { CV_EssentialMatTest test; test.safe_run(); }
  1370. TEST(Calib3d_FindFundamentalMat, correctMatches)
  1371. {
  1372. double fdata[] = {0, 0, 0, 0, 0, -1, 0, 1, 0};
  1373. double p1data[] = {200, 0, 1};
  1374. double p2data[] = {170, 0, 1};
  1375. Mat F(3, 3, CV_64F, fdata);
  1376. Mat p1(1, 1, CV_64FC2, p1data);
  1377. Mat p2(1, 1, CV_64FC2, p2data);
  1378. Mat np1, np2;
  1379. correctMatches(F, p1, p2, np1, np2);
  1380. cout << np1 << endl;
  1381. cout << np2 << endl;
  1382. }
  1383. }} // namespace
  1384. /* End of file. */