PageRenderTime 95ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/opencv_source/src/cv/cvoptflowgf.cpp

https://bitbucket.org/m4271n/opencv
C++ | 636 lines | 464 code | 95 blank | 77 comment | 68 complexity | 62e9194f8b8e9e1c519351b946522c99 MD5 | raw file
Possible License(s): BSD-3-Clause
  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. // License Agreement
  11. // For Open Source Computer Vision Library
  12. //
  13. // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
  14. // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
  15. // Third party copyrights are property of their respective owners.
  16. //
  17. // Redistribution and use in source and binary forms, with or without modification,
  18. // are permitted provided that the following conditions are met:
  19. //
  20. // * Redistribution's of source code must retain the above copyright notice,
  21. // this list of conditions and the following disclaimer.
  22. //
  23. // * Redistribution's in binary form must reproduce the above copyright notice,
  24. // this list of conditions and the following disclaimer in the documentation
  25. // and/or other materials provided with the distribution.
  26. //
  27. // * The name of the copyright holders may not be used to endorse or promote products
  28. // derived from this software without specific prior written permission.
  29. //
  30. // This software is provided by the copyright holders and contributors "as is" and
  31. // any express or implied warranties, including, but not limited to, the implied
  32. // warranties of merchantability and fitness for a particular purpose are disclaimed.
  33. // In no event shall the Intel Corporation or contributors be liable for any direct,
  34. // indirect, incidental, special, exemplary, or consequential damages
  35. // (including, but not limited to, procurement of substitute goods or services;
  36. // loss of use, data, or profits; or business interruption) however caused
  37. // and on any theory of liability, whether in contract, strict liability,
  38. // or tort (including negligence or otherwise) arising in any way out of
  39. // the use of this software, even if advised of the possibility of such damage.
  40. //
  41. //M*/
  42. #include "_cv.h"
  43. //
  44. // 2D dense optical flow algorithm from the following paper:
  45. // Gunnar Farneback. "Two-Frame Motion Estimation Based on Polynomial Expansion".
  46. // Proceedings of the 13th Scandinavian Conference on Image Analysis, Gothenburg, Sweden
  47. //
  48. namespace cv
  49. {
  50. static void
  51. FarnebackPolyExp( const Mat& src, Mat& dst, int n, double sigma )
  52. {
  53. int k, x, y;
  54. assert( src.type() == CV_32FC1 );
  55. int width = src.cols;
  56. int height = src.rows;
  57. AutoBuffer<float> kbuf(n*6 + 3), _row((width + n*2)*3);
  58. float* g = kbuf + n;
  59. float* xg = g + n*2 + 1;
  60. float* xxg = xg + n*2 + 1;
  61. float *row = (float*)_row + n*3;
  62. if( sigma < FLT_EPSILON )
  63. sigma = n*0.3;
  64. double s = 0.;
  65. for( x = -n; x <= n; x++ )
  66. {
  67. g[x] = (float)std::exp(-x*x/(2*sigma*sigma));
  68. s += g[x];
  69. }
  70. s = 1./s;
  71. for( x = -n; x <= n; x++ )
  72. {
  73. g[x] = (float)(g[x]*s);
  74. xg[x] = (float)(x*g[x]);
  75. xxg[x] = (float)(x*x*g[x]);
  76. }
  77. Mat_<double> G = Mat_<double>::zeros(6, 6);
  78. for( y = -n; y <= n; y++ )
  79. for( x = -n; x <= n; x++ )
  80. {
  81. G(0,0) += g[y]*g[x];
  82. G(1,1) += g[y]*g[x]*x*x;
  83. G(3,3) += g[y]*g[x]*x*x*x*x;
  84. G(5,5) += g[y]*g[x]*x*x*y*y;
  85. }
  86. //G[0][0] = 1.;
  87. G(2,2) = G(0,3) = G(0,4) = G(3,0) = G(4,0) = G(1,1);
  88. G(4,4) = G(3,3);
  89. G(3,4) = G(4,3) = G(5,5);
  90. // invG:
  91. // [ x e e ]
  92. // [ y ]
  93. // [ y ]
  94. // [ e z ]
  95. // [ e z ]
  96. // [ u ]
  97. Mat_<double> invG = G.inv(DECOMP_CHOLESKY);
  98. double ig11 = invG(1,1), ig03 = invG(0,3), ig33 = invG(3,3), ig55 = invG(5,5);
  99. dst.create( height, width, CV_32FC(5));
  100. for( y = 0; y < height; y++ )
  101. {
  102. float g0 = g[0], g1, g2;
  103. float *srow0 = (float*)(src.data + src.step*y), *srow1 = 0;
  104. float *drow = (float*)(dst.data + dst.step*y);
  105. // vertical part of convolution
  106. for( x = 0; x < width; x++ )
  107. {
  108. row[x*3] = srow0[x]*g0;
  109. row[x*3+1] = row[x*3+2] = 0.f;
  110. }
  111. for( k = 1; k <= n; k++ )
  112. {
  113. g0 = g[k]; g1 = xg[k]; g2 = xxg[k];
  114. srow0 = (float*)(src.data + src.step*std::max(y-k,0));
  115. srow1 = (float*)(src.data + src.step*std::min(y+k,height-1));
  116. for( x = 0; x < width; x++ )
  117. {
  118. float p = srow0[x] + srow1[x];
  119. float t0 = row[x*3] + g0*p;
  120. float t1 = row[x*3+1] + g1*(srow1[x] - srow0[x]);
  121. float t2 = row[x*3+2] + g2*p;
  122. row[x*3] = t0;
  123. row[x*3+1] = t1;
  124. row[x*3+2] = t2;
  125. }
  126. }
  127. // horizontal part of convolution
  128. for( x = 0; x < n*3; x++ )
  129. {
  130. row[-1-x] = row[2-x];
  131. row[width*3+x] = row[width*3+x-3];
  132. }
  133. for( x = 0; x < width; x++ )
  134. {
  135. g0 = g[0];
  136. // r1 ~ 1, r2 ~ x, r3 ~ y, r4 ~ x^2, r5 ~ y^2, r6 ~ xy
  137. double b1 = row[x*3]*g0, b2 = 0, b3 = row[x*3+1]*g0,
  138. b4 = 0, b5 = row[x*3+2]*g0, b6 = 0;
  139. for( k = 1; k <= n; k++ )
  140. {
  141. double tg = row[(x+k)*3] + row[(x-k)*3];
  142. g0 = g[k];
  143. b1 += tg*g0;
  144. b4 += tg*xxg[k];
  145. b2 += (row[(x+k)*3] - row[(x-k)*3])*xg[k];
  146. b3 += (row[(x+k)*3+1] + row[(x-k)*3+1])*g0;
  147. b6 += (row[(x+k)*3+1] - row[(x-k)*3+1])*xg[k];
  148. b5 += (row[(x+k)*3+2] + row[(x-k)*3+2])*g0;
  149. }
  150. // do not store r1
  151. drow[x*5+1] = (float)(b2*ig11);
  152. drow[x*5] = (float)(b3*ig11);
  153. drow[x*5+3] = (float)(b1*ig03 + b4*ig33);
  154. drow[x*5+2] = (float)(b1*ig03 + b5*ig33);
  155. drow[x*5+4] = (float)(b6*ig55);
  156. }
  157. }
  158. row -= n*3;
  159. }
  160. /*static void
  161. FarnebackPolyExpPyr( const Mat& src0, Vector<Mat>& pyr, int maxlevel, int n, double sigma )
  162. {
  163. Vector<Mat> imgpyr;
  164. buildPyramid( src0, imgpyr, maxlevel );
  165. for( int i = 0; i <= maxlevel; i++ )
  166. FarnebackPolyExp( imgpyr[i], pyr[i], n, sigma );
  167. }*/
  168. static void
  169. FarnebackUpdateMatrices( const Mat& _R0, const Mat& _R1, const Mat& _flow, Mat& _M, int _y0, int _y1 )
  170. {
  171. const int BORDER = 5;
  172. static const float border[BORDER] = {0.14f, 0.14f, 0.4472f, 0.4472f, 0.4472f};
  173. int x, y, width = _flow.cols, height = _flow.rows;
  174. const float* R1 = (float*)_R1.data;
  175. size_t step1 = _R1.step/sizeof(R1[0]);
  176. _M.create(height, width, CV_32FC(5));
  177. for( y = _y0; y < _y1; y++ )
  178. {
  179. const float* flow = (float*)(_flow.data + y*_flow.step);
  180. const float* R0 = (float*)(_R0.data + y*_R0.step);
  181. float* M = (float*)(_M.data + y*_M.step);
  182. for( x = 0; x < width; x++ )
  183. {
  184. float dx = flow[x*2], dy = flow[x*2+1];
  185. float fx = x + dx, fy = y + dy;
  186. #if 1
  187. int x1 = cvFloor(fx), y1 = cvFloor(fy);
  188. const float* ptr = R1 + y1*step1 + x1*5;
  189. float r2, r3, r4, r5, r6;
  190. fx -= x1; fy -= y1;
  191. if( (unsigned)x1 < (unsigned)(width-1) &&
  192. (unsigned)y1 < (unsigned)(height-1) )
  193. {
  194. float a00 = (1.f-fx)*(1.f-fy), a01 = fx*(1.f-fy),
  195. a10 = (1.f-fx)*fy, a11 = fx*fy;
  196. r2 = a00*ptr[0] + a01*ptr[5] + a10*ptr[step1] + a11*ptr[step1+5];
  197. r3 = a00*ptr[1] + a01*ptr[6] + a10*ptr[step1+1] + a11*ptr[step1+6];
  198. r4 = a00*ptr[2] + a01*ptr[7] + a10*ptr[step1+2] + a11*ptr[step1+7];
  199. r5 = a00*ptr[3] + a01*ptr[8] + a10*ptr[step1+3] + a11*ptr[step1+8];
  200. r6 = a00*ptr[4] + a01*ptr[9] + a10*ptr[step1+4] + a11*ptr[step1+9];
  201. r4 = (R0[x*5+2] + r4)*0.5f;
  202. r5 = (R0[x*5+3] + r5)*0.5f;
  203. r6 = (R0[x*5+4] + r6)*0.25f;
  204. }
  205. #else
  206. int x1 = cvRound(fx), y1 = cvRound(fy);
  207. const float* ptr = R1 + y1*step1 + x1*5;
  208. float r2, r3, r4, r5, r6;
  209. if( (unsigned)x1 < (unsigned)width &&
  210. (unsigned)y1 < (unsigned)height )
  211. {
  212. r2 = ptr[0];
  213. r3 = ptr[1];
  214. r4 = (R0[x*5+2] + ptr[2])*0.5f;
  215. r5 = (R0[x*5+3] + ptr[3])*0.5f;
  216. r6 = (R0[x*5+4] + ptr[4])*0.25f;
  217. }
  218. #endif
  219. else
  220. {
  221. r2 = r3 = 0.f;
  222. r4 = R0[x*5+2];
  223. r5 = R0[x*5+3];
  224. r6 = R0[x*5+4]*0.5f;
  225. }
  226. r2 = (R0[x*5] - r2)*0.5f;
  227. r3 = (R0[x*5+1] - r3)*0.5f;
  228. r2 += r4*dy + r6*dx;
  229. r3 += r6*dy + r5*dx;
  230. if( (unsigned)(x - BORDER) >= (unsigned)(width - BORDER*2) ||
  231. (unsigned)(y - BORDER) >= (unsigned)(height - BORDER*2))
  232. {
  233. float scale = (x < BORDER ? border[x] : 1.f)*
  234. (x >= width - BORDER ? border[width - x - 1] : 1.f)*
  235. (y < BORDER ? border[y] : 1.f)*
  236. (y >= height - BORDER ? border[height - y - 1] : 1.f);
  237. r2 *= scale; r3 *= scale; r4 *= scale;
  238. r5 *= scale; r6 *= scale;
  239. }
  240. M[x*5] = r4*r4 + r6*r6; // G(1,1)
  241. M[x*5+1] = (r4 + r5)*r6; // G(1,2)=G(2,1)
  242. M[x*5+2] = r5*r5 + r6*r6; // G(2,2)
  243. M[x*5+3] = r4*r2 + r6*r3; // h(1)
  244. M[x*5+4] = r6*r2 + r5*r3; // h(2)
  245. }
  246. }
  247. }
  248. static void
  249. FarnebackUpdateFlow_Blur( const Mat& _R0, const Mat& _R1,
  250. Mat& _flow, Mat& _M, int block_size,
  251. bool update_matrices )
  252. {
  253. int x, y, width = _flow.cols, height = _flow.rows;
  254. int m = block_size/2;
  255. int y0 = 0, y1;
  256. int min_update_stripe = std::max((1 << 10)/width, block_size);
  257. double scale = 1./(block_size*block_size);
  258. AutoBuffer<double> _vsum((width+m*2+2)*5);
  259. double* vsum = _vsum + (m+1)*5;
  260. // init vsum
  261. const float* srow0 = (const float*)_M.data;
  262. for( x = 0; x < width*5; x++ )
  263. vsum[x] = srow0[x]*(m+2);
  264. for( y = 1; y < m; y++ )
  265. {
  266. srow0 = (float*)(_M.data + _M.step*std::min(y,height-1));
  267. for( x = 0; x < width*5; x++ )
  268. vsum[x] += srow0[x];
  269. }
  270. // compute blur(G)*flow=blur(h)
  271. for( y = 0; y < height; y++ )
  272. {
  273. double g11, g12, g22, h1, h2;
  274. float* flow = (float*)(_flow.data + _flow.step*y);
  275. srow0 = (const float*)(_M.data + _M.step*std::max(y-m-1,0));
  276. const float* srow1 = (const float*)(_M.data + _M.step*std::min(y+m,height-1));
  277. // vertical blur
  278. for( x = 0; x < width*5; x++ )
  279. vsum[x] += srow1[x] - srow0[x];
  280. // update borders
  281. for( x = 0; x < (m+1)*5; x++ )
  282. {
  283. vsum[-1-x] = vsum[4-x];
  284. vsum[width*5+x] = vsum[width*5+x-5];
  285. }
  286. // init g** and h*
  287. g11 = vsum[0]*(m+2);
  288. g12 = vsum[1]*(m+2);
  289. g22 = vsum[2]*(m+2);
  290. h1 = vsum[3]*(m+2);
  291. h2 = vsum[4]*(m+2);
  292. for( x = 1; x < m; x++ )
  293. {
  294. g11 += vsum[x*5];
  295. g12 += vsum[x*5+1];
  296. g22 += vsum[x*5+2];
  297. h1 += vsum[x*5+3];
  298. h2 += vsum[x*5+4];
  299. }
  300. // horizontal blur
  301. for( x = 0; x < width; x++ )
  302. {
  303. g11 += vsum[(x+m)*5] - vsum[(x-m)*5 - 5];
  304. g12 += vsum[(x+m)*5 + 1] - vsum[(x-m)*5 - 4];
  305. g22 += vsum[(x+m)*5 + 2] - vsum[(x-m)*5 - 3];
  306. h1 += vsum[(x+m)*5 + 3] - vsum[(x-m)*5 - 2];
  307. h2 += vsum[(x+m)*5 + 4] - vsum[(x-m)*5 - 1];
  308. double g11_ = g11*scale;
  309. double g12_ = g12*scale;
  310. double g22_ = g22*scale;
  311. double h1_ = h1*scale;
  312. double h2_ = h2*scale;
  313. double idet = 1./(g11_*g22_ - g12_*g12_+1e-3);
  314. flow[x*2] = (float)((g11_*h2_-g12_*h1_)*idet);
  315. flow[x*2+1] = (float)((g22_*h1_-g12_*h2_)*idet);
  316. }
  317. y1 = y == height - 1 ? height : y - block_size;
  318. if( update_matrices && (y1 == height || y1 >= y0 + min_update_stripe) )
  319. {
  320. FarnebackUpdateMatrices( _R0, _R1, _flow, _M, y0, y1 );
  321. y0 = y1;
  322. }
  323. }
  324. }
  325. static void
  326. FarnebackUpdateFlow_GaussianBlur( const Mat& _R0, const Mat& _R1,
  327. Mat& _flow, Mat& _M, int block_size,
  328. bool update_matrices )
  329. {
  330. int x, y, i, width = _flow.cols, height = _flow.rows;
  331. int m = block_size/2;
  332. int y0 = 0, y1;
  333. int min_update_stripe = std::max((1 << 10)/width, block_size);
  334. double sigma = m*0.3, s = 1;
  335. AutoBuffer<float> _vsum((width+m*2+2)*5 + 16), _hsum(width*5 + 16);
  336. AutoBuffer<float, 4096> _kernel((m+1)*5 + 16);
  337. AutoBuffer<float*, 1024> _srow(m*2+1);
  338. float *vsum = alignPtr((float*)_vsum + (m+1)*5, 16), *hsum = alignPtr((float*)_hsum, 16);
  339. float* kernel = (float*)_kernel;
  340. const float** srow = (const float**)&_srow[0];
  341. kernel[0] = (float)s;
  342. for( i = 1; i <= m; i++ )
  343. {
  344. float t = (float)std::exp(-i*i/(2*sigma*sigma) );
  345. kernel[i] = t;
  346. s += t*2;
  347. }
  348. s = 1./s;
  349. for( i = 0; i <= m; i++ )
  350. kernel[i] = (float)(kernel[i]*s);
  351. #if CV_SSE2
  352. float* simd_kernel = alignPtr(kernel + m+1, 16);
  353. for( i = 0; i <= m; i++ )
  354. _mm_store_ps(simd_kernel + i*4, _mm_set1_ps(kernel[i]));
  355. #endif
  356. // compute blur(G)*flow=blur(h)
  357. for( y = 0; y < height; y++ )
  358. {
  359. double g11, g12, g22, h1, h2;
  360. float* flow = (float*)(_flow.data + _flow.step*y);
  361. // vertical blur
  362. for( i = 0; i <= m; i++ )
  363. {
  364. srow[m-i] = (const float*)(_M.data + _M.step*std::max(y-i,0));
  365. srow[m+i] = (const float*)(_M.data + _M.step*std::min(y+i,height-1));
  366. }
  367. x = 0;
  368. #if CV_SSE2
  369. for( ; x <= width*5 - 16; x += 16 )
  370. {
  371. const float *sptr0 = srow[m], *sptr1;
  372. __m128 g4 = _mm_load_ps(simd_kernel);
  373. __m128 s0, s1, s2, s3;
  374. s0 = _mm_mul_ps(_mm_loadu_ps(sptr0 + x), g4);
  375. s1 = _mm_mul_ps(_mm_loadu_ps(sptr0 + x + 4), g4);
  376. s2 = _mm_mul_ps(_mm_loadu_ps(sptr0 + x + 8), g4);
  377. s3 = _mm_mul_ps(_mm_loadu_ps(sptr0 + x + 12), g4);
  378. for( i = 1; i <= m; i++ )
  379. {
  380. __m128 x0, x1;
  381. sptr0 = srow[m+i], sptr1 = srow[m-i];
  382. g4 = _mm_load_ps(simd_kernel + i*4);
  383. x0 = _mm_add_ps(_mm_loadu_ps(sptr0 + x), _mm_loadu_ps(sptr1 + x));
  384. x1 = _mm_add_ps(_mm_loadu_ps(sptr0 + x + 4), _mm_loadu_ps(sptr1 + x + 4));
  385. s0 = _mm_add_ps(s0, _mm_mul_ps(x0, g4));
  386. s1 = _mm_add_ps(s1, _mm_mul_ps(x1, g4));
  387. x0 = _mm_add_ps(_mm_loadu_ps(sptr0 + x + 8), _mm_loadu_ps(sptr1 + x + 8));
  388. x1 = _mm_add_ps(_mm_loadu_ps(sptr0 + x + 12), _mm_loadu_ps(sptr1 + x + 12));
  389. s2 = _mm_add_ps(s2, _mm_mul_ps(x0, g4));
  390. s3 = _mm_add_ps(s3, _mm_mul_ps(x1, g4));
  391. }
  392. _mm_store_ps(vsum + x, s0);
  393. _mm_store_ps(vsum + x + 4, s1);
  394. _mm_store_ps(vsum + x + 8, s2);
  395. _mm_store_ps(vsum + x + 12, s3);
  396. }
  397. for( ; x <= width*5 - 4; x += 4 )
  398. {
  399. const float *sptr0 = srow[m], *sptr1;
  400. __m128 g4 = _mm_load_ps(simd_kernel);
  401. __m128 s0 = _mm_mul_ps(_mm_loadu_ps(sptr0 + x), g4);
  402. for( i = 1; i <= m; i++ )
  403. {
  404. sptr0 = srow[m+i], sptr1 = srow[m-i];
  405. g4 = _mm_load_ps(simd_kernel + i*4);
  406. __m128 x0 = _mm_add_ps(_mm_loadu_ps(sptr0 + x), _mm_loadu_ps(sptr1 + x));
  407. s0 = _mm_add_ps(s0, _mm_mul_ps(x0, g4));
  408. }
  409. _mm_store_ps(vsum + x, s0);
  410. }
  411. #endif
  412. for( ; x < width*5; x++ )
  413. {
  414. float s0 = srow[m][x]*kernel[0];
  415. for( i = 1; i <= m; i++ )
  416. s0 += (srow[m+i][x] + srow[m-i][x])*kernel[i];
  417. vsum[x] = s0;
  418. }
  419. // update borders
  420. for( x = 0; x < m*5; x++ )
  421. {
  422. vsum[-1-x] = vsum[4-x];
  423. vsum[width*5+x] = vsum[width*5+x-5];
  424. }
  425. // horizontal blur
  426. x = 0;
  427. #if CV_SSE2
  428. for( ; x <= width*5 - 8; x += 8 )
  429. {
  430. __m128 g4 = _mm_load_ps(simd_kernel);
  431. __m128 s0 = _mm_mul_ps(_mm_loadu_ps(vsum + x), g4);
  432. __m128 s1 = _mm_mul_ps(_mm_loadu_ps(vsum + x + 4), g4);
  433. for( i = 1; i <= m; i++ )
  434. {
  435. g4 = _mm_load_ps(simd_kernel + i*4);
  436. __m128 x0 = _mm_add_ps(_mm_loadu_ps(vsum + x - i*5),
  437. _mm_loadu_ps(vsum + x + i*5));
  438. __m128 x1 = _mm_add_ps(_mm_loadu_ps(vsum + x - i*5 + 4),
  439. _mm_loadu_ps(vsum + x + i*5 + 4));
  440. s0 = _mm_add_ps(s0, _mm_mul_ps(x0, g4));
  441. s1 = _mm_add_ps(s1, _mm_mul_ps(x1, g4));
  442. }
  443. _mm_store_ps(hsum + x, s0);
  444. _mm_store_ps(hsum + x + 4, s1);
  445. }
  446. #endif
  447. for( ; x < width*5; x++ )
  448. {
  449. float s = vsum[x]*kernel[0];
  450. for( i = 1; i <= m; i++ )
  451. s += kernel[i]*(vsum[x - i*5] + vsum[x + i*5]);
  452. hsum[x] = s;
  453. }
  454. for( x = 0; x < width; x++ )
  455. {
  456. g11 = hsum[x*5];
  457. g12 = hsum[x*5+1];
  458. g22 = hsum[x*5+2];
  459. h1 = hsum[x*5+3];
  460. h2 = hsum[x*5+4];
  461. double idet = 1./(g11*g22 - g12*g12 + 1e-3);
  462. flow[x*2] = (float)((g11*h2-g12*h1)*idet);
  463. flow[x*2+1] = (float)((g22*h1-g12*h2)*idet);
  464. }
  465. y1 = y == height - 1 ? height : y - block_size;
  466. if( update_matrices && (y1 == height || y1 >= y0 + min_update_stripe) )
  467. {
  468. FarnebackUpdateMatrices( _R0, _R1, _flow, _M, y0, y1 );
  469. y0 = y1;
  470. }
  471. }
  472. }
  473. void calcOpticalFlowFarneback( const Mat& prev0, const Mat& next0,
  474. Mat& flow0, double pyr_scale, int levels, int winsize,
  475. int iterations, int poly_n, double poly_sigma, int flags )
  476. {
  477. const int min_size = 32;
  478. const Mat* img[2] = { &prev0, &next0 };
  479. Mat fimg;
  480. int i, k;
  481. double scale;
  482. Mat prevFlow, flow;
  483. CV_Assert( prev0.size() == next0.size() && prev0.channels() == next0.channels() &&
  484. prev0.channels() == 1 );
  485. flow0.create( prev0.size(), CV_32FC2 );
  486. for( k = 0, scale = 1; k < levels; k++ )
  487. {
  488. scale *= pyr_scale;
  489. if( prev0.cols*scale < min_size || prev0.rows*scale < min_size )
  490. break;
  491. }
  492. levels = k;
  493. for( k = levels; k >= 0; k-- )
  494. {
  495. for( i = 0, scale = 1; i < k; i++ )
  496. scale *= pyr_scale;
  497. double sigma = (1./scale-1)*0.5;
  498. int smooth_sz = cvRound(sigma*5)|1;
  499. smooth_sz = std::max(smooth_sz, 3);
  500. int width = cvRound(prev0.cols*scale);
  501. int height = cvRound(prev0.rows*scale);
  502. if( k > 0 )
  503. flow.create( height, width, CV_32FC2 );
  504. else
  505. flow = flow0;
  506. if( !prevFlow.data )
  507. {
  508. if( flags & OPTFLOW_USE_INITIAL_FLOW )
  509. {
  510. resize( flow0, flow, Size(width, height), 0, 0, INTER_AREA );
  511. flow *= scale;
  512. }
  513. else
  514. flow = Mat::zeros( height, width, CV_32FC2 );
  515. }
  516. else
  517. {
  518. resize( prevFlow, flow, Size(width, height), 0, 0, INTER_LINEAR );
  519. flow *= 1./pyr_scale;
  520. }
  521. Mat R[2], I, M;
  522. for( i = 0; i < 2; i++ )
  523. {
  524. img[i]->convertTo(fimg, CV_32F);
  525. GaussianBlur(fimg, fimg, Size(smooth_sz, smooth_sz), sigma, sigma);
  526. resize( fimg, I, Size(width, height), CV_INTER_LINEAR );
  527. FarnebackPolyExp( I, R[i], poly_n, poly_sigma );
  528. }
  529. FarnebackUpdateMatrices( R[0], R[1], flow, M, 0, flow.rows );
  530. for( i = 0; i < iterations; i++ )
  531. {
  532. if( flags & OPTFLOW_FARNEBACK_GAUSSIAN )
  533. FarnebackUpdateFlow_GaussianBlur( R[0], R[1], flow, M, winsize, i < iterations - 1 );
  534. else
  535. FarnebackUpdateFlow_Blur( R[0], R[1], flow, M, winsize, i < iterations - 1 );
  536. }
  537. prevFlow = flow;
  538. }
  539. }
  540. }