PageRenderTime 177ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/samples/gpu/opticalflow_nvidia_api.cpp

https://gitlab.com/generic-library/opencv
C++ | 649 lines | 528 code | 101 blank | 20 comment | 80 complexity | d68e09829354c6ba6733803a91fce0fb MD5 | raw file
  1. #if defined _MSC_VER && _MSC_VER >= 1400
  2. #pragma warning( disable : 4201 4408 4127 4100)
  3. #endif
  4. #include <iostream>
  5. #include <iomanip>
  6. #include <memory>
  7. #include <exception>
  8. #include <ctime>
  9. #include <ctype.h>
  10. #include "cvconfig.h"
  11. #include <iostream>
  12. #include <iomanip>
  13. #include "opencv2/core/cuda.hpp"
  14. #include "opencv2/cudalegacy.hpp"
  15. #include "opencv2/highgui.hpp"
  16. #if !defined(HAVE_CUDA)
  17. int main( int, const char** )
  18. {
  19. std::cout << "Please compile the library with CUDA support" << std::endl;
  20. return -1;
  21. }
  22. #else
  23. //using std::tr1::shared_ptr;
  24. using cv::Ptr;
  25. #define PARAM_LEFT "--left"
  26. #define PARAM_RIGHT "--right"
  27. #define PARAM_SCALE "--scale"
  28. #define PARAM_ALPHA "--alpha"
  29. #define PARAM_GAMMA "--gamma"
  30. #define PARAM_INNER "--inner"
  31. #define PARAM_OUTER "--outer"
  32. #define PARAM_SOLVER "--solver"
  33. #define PARAM_TIME_STEP "--time-step"
  34. #define PARAM_HELP "--help"
  35. Ptr<INCVMemAllocator> g_pGPUMemAllocator;
  36. Ptr<INCVMemAllocator> g_pHostMemAllocator;
  37. class RgbToMonochrome
  38. {
  39. public:
  40. float operator ()(unsigned char b, unsigned char g, unsigned char r)
  41. {
  42. float _r = static_cast<float>(r)/255.0f;
  43. float _g = static_cast<float>(g)/255.0f;
  44. float _b = static_cast<float>(b)/255.0f;
  45. return (_r + _g + _b)/3.0f;
  46. }
  47. };
  48. class RgbToR
  49. {
  50. public:
  51. float operator ()(unsigned char /*b*/, unsigned char /*g*/, unsigned char r)
  52. {
  53. return static_cast<float>(r)/255.0f;
  54. }
  55. };
  56. class RgbToG
  57. {
  58. public:
  59. float operator ()(unsigned char /*b*/, unsigned char g, unsigned char /*r*/)
  60. {
  61. return static_cast<float>(g)/255.0f;
  62. }
  63. };
  64. class RgbToB
  65. {
  66. public:
  67. float operator ()(unsigned char b, unsigned char /*g*/, unsigned char /*r*/)
  68. {
  69. return static_cast<float>(b)/255.0f;
  70. }
  71. };
  72. template<class T>
  73. NCVStatus CopyData(IplImage *image, Ptr<NCVMatrixAlloc<Ncv32f> >& dst)
  74. {
  75. dst = Ptr<NCVMatrixAlloc<Ncv32f> > (new NCVMatrixAlloc<Ncv32f> (*g_pHostMemAllocator, image->width, image->height));
  76. ncvAssertReturn (dst->isMemAllocated (), NCV_ALLOCATOR_BAD_ALLOC);
  77. unsigned char *row = reinterpret_cast<unsigned char*> (image->imageData);
  78. T convert;
  79. for (int i = 0; i < image->height; ++i)
  80. {
  81. for (int j = 0; j < image->width; ++j)
  82. {
  83. if (image->nChannels < 3)
  84. {
  85. dst->ptr ()[j + i*dst->stride ()] = static_cast<float> (*(row + j*image->nChannels))/255.0f;
  86. }
  87. else
  88. {
  89. unsigned char *color = row + j * image->nChannels;
  90. dst->ptr ()[j +i*dst->stride ()] = convert (color[0], color[1], color[2]);
  91. }
  92. }
  93. row += image->widthStep;
  94. }
  95. return NCV_SUCCESS;
  96. }
  97. template<class T>
  98. NCVStatus CopyData(const IplImage *image, const NCVMatrixAlloc<Ncv32f> &dst)
  99. {
  100. unsigned char *row = reinterpret_cast<unsigned char*> (image->imageData);
  101. T convert;
  102. for (int i = 0; i < image->height; ++i)
  103. {
  104. for (int j = 0; j < image->width; ++j)
  105. {
  106. if (image->nChannels < 3)
  107. {
  108. dst.ptr ()[j + i*dst.stride ()] = static_cast<float>(*(row + j*image->nChannels))/255.0f;
  109. }
  110. else
  111. {
  112. unsigned char *color = row + j * image->nChannels;
  113. dst.ptr ()[j +i*dst.stride()] = convert (color[0], color[1], color[2]);
  114. }
  115. }
  116. row += image->widthStep;
  117. }
  118. return NCV_SUCCESS;
  119. }
  120. static NCVStatus LoadImages (const char *frame0Name,
  121. const char *frame1Name,
  122. int &width,
  123. int &height,
  124. Ptr<NCVMatrixAlloc<Ncv32f> > &src,
  125. Ptr<NCVMatrixAlloc<Ncv32f> > &dst,
  126. IplImage *&firstFrame,
  127. IplImage *&lastFrame)
  128. {
  129. IplImage *image;
  130. image = cvLoadImage (frame0Name);
  131. if (image == 0)
  132. {
  133. std::cout << "Could not open '" << frame0Name << "'\n";
  134. return NCV_FILE_ERROR;
  135. }
  136. firstFrame = image;
  137. // copy data to src
  138. ncvAssertReturnNcvStat (CopyData<RgbToMonochrome> (image, src));
  139. IplImage *image2;
  140. image2 = cvLoadImage (frame1Name);
  141. if (image2 == 0)
  142. {
  143. std::cout << "Could not open '" << frame1Name << "'\n";
  144. return NCV_FILE_ERROR;
  145. }
  146. lastFrame = image2;
  147. ncvAssertReturnNcvStat (CopyData<RgbToMonochrome> (image2, dst));
  148. width = image->width;
  149. height = image->height;
  150. return NCV_SUCCESS;
  151. }
  152. template<typename T>
  153. inline T Clamp (T x, T a, T b)
  154. {
  155. return ((x) > (a) ? ((x) < (b) ? (x) : (b)) : (a));
  156. }
  157. template<typename T>
  158. inline T MapValue (T x, T a, T b, T c, T d)
  159. {
  160. x = Clamp (x, a, b);
  161. return c + (d - c) * (x - a) / (b - a);
  162. }
  163. static NCVStatus ShowFlow (NCVMatrixAlloc<Ncv32f> &u, NCVMatrixAlloc<Ncv32f> &v, const char *name)
  164. {
  165. IplImage *flowField;
  166. NCVMatrixAlloc<Ncv32f> host_u(*g_pHostMemAllocator, u.width(), u.height());
  167. ncvAssertReturn(host_u.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC);
  168. NCVMatrixAlloc<Ncv32f> host_v (*g_pHostMemAllocator, u.width (), u.height ());
  169. ncvAssertReturn (host_v.isMemAllocated (), NCV_ALLOCATOR_BAD_ALLOC);
  170. ncvAssertReturnNcvStat (u.copySolid (host_u, 0));
  171. ncvAssertReturnNcvStat (v.copySolid (host_v, 0));
  172. float *ptr_u = host_u.ptr ();
  173. float *ptr_v = host_v.ptr ();
  174. float maxDisplacement = 1.0f;
  175. for (Ncv32u i = 0; i < u.height (); ++i)
  176. {
  177. for (Ncv32u j = 0; j < u.width (); ++j)
  178. {
  179. float d = std::max ( fabsf(*ptr_u), fabsf(*ptr_v) );
  180. if (d > maxDisplacement) maxDisplacement = d;
  181. ++ptr_u;
  182. ++ptr_v;
  183. }
  184. ptr_u += u.stride () - u.width ();
  185. ptr_v += v.stride () - v.width ();
  186. }
  187. CvSize image_size = cvSize (u.width (), u.height ());
  188. flowField = cvCreateImage (image_size, IPL_DEPTH_8U, 4);
  189. if (flowField == 0) return NCV_NULL_PTR;
  190. unsigned char *row = reinterpret_cast<unsigned char *> (flowField->imageData);
  191. ptr_u = host_u.ptr();
  192. ptr_v = host_v.ptr();
  193. for (int i = 0; i < flowField->height; ++i)
  194. {
  195. for (int j = 0; j < flowField->width; ++j)
  196. {
  197. (row + j * flowField->nChannels)[0] = 0;
  198. (row + j * flowField->nChannels)[1] = static_cast<unsigned char> (MapValue (-(*ptr_v), -maxDisplacement, maxDisplacement, 0.0f, 255.0f));
  199. (row + j * flowField->nChannels)[2] = static_cast<unsigned char> (MapValue (*ptr_u , -maxDisplacement, maxDisplacement, 0.0f, 255.0f));
  200. (row + j * flowField->nChannels)[3] = 255;
  201. ++ptr_u;
  202. ++ptr_v;
  203. }
  204. row += flowField->widthStep;
  205. ptr_u += u.stride () - u.width ();
  206. ptr_v += v.stride () - v.width ();
  207. }
  208. cvShowImage (name, flowField);
  209. return NCV_SUCCESS;
  210. }
  211. static IplImage *CreateImage (NCVMatrixAlloc<Ncv32f> &h_r, NCVMatrixAlloc<Ncv32f> &h_g, NCVMatrixAlloc<Ncv32f> &h_b)
  212. {
  213. CvSize imageSize = cvSize (h_r.width (), h_r.height ());
  214. IplImage *image = cvCreateImage (imageSize, IPL_DEPTH_8U, 4);
  215. if (image == 0) return 0;
  216. unsigned char *row = reinterpret_cast<unsigned char*> (image->imageData);
  217. for (int i = 0; i < image->height; ++i)
  218. {
  219. for (int j = 0; j < image->width; ++j)
  220. {
  221. int offset = j * image->nChannels;
  222. int pos = i * h_r.stride () + j;
  223. row[offset + 0] = static_cast<unsigned char> (h_b.ptr ()[pos] * 255.0f);
  224. row[offset + 1] = static_cast<unsigned char> (h_g.ptr ()[pos] * 255.0f);
  225. row[offset + 2] = static_cast<unsigned char> (h_r.ptr ()[pos] * 255.0f);
  226. row[offset + 3] = 255;
  227. }
  228. row += image->widthStep;
  229. }
  230. return image;
  231. }
  232. static void PrintHelp ()
  233. {
  234. std::cout << "Usage help:\n";
  235. std::cout << std::setiosflags(std::ios::left);
  236. std::cout << "\t" << std::setw(15) << PARAM_ALPHA << " - set alpha\n";
  237. std::cout << "\t" << std::setw(15) << PARAM_GAMMA << " - set gamma\n";
  238. std::cout << "\t" << std::setw(15) << PARAM_INNER << " - set number of inner iterations\n";
  239. std::cout << "\t" << std::setw(15) << PARAM_LEFT << " - specify left image\n";
  240. std::cout << "\t" << std::setw(15) << PARAM_RIGHT << " - specify right image\n";
  241. std::cout << "\t" << std::setw(15) << PARAM_OUTER << " - set number of outer iterations\n";
  242. std::cout << "\t" << std::setw(15) << PARAM_SCALE << " - set pyramid scale factor\n";
  243. std::cout << "\t" << std::setw(15) << PARAM_SOLVER << " - set number of basic solver iterations\n";
  244. std::cout << "\t" << std::setw(15) << PARAM_TIME_STEP << " - set frame interpolation time step\n";
  245. std::cout << "\t" << std::setw(15) << PARAM_HELP << " - display this help message\n";
  246. }
  247. static int ProcessCommandLine(int argc, char **argv,
  248. Ncv32f &timeStep,
  249. char *&frame0Name,
  250. char *&frame1Name,
  251. NCVBroxOpticalFlowDescriptor &desc)
  252. {
  253. timeStep = 0.25f;
  254. for (int iarg = 1; iarg < argc; ++iarg)
  255. {
  256. if (strcmp(argv[iarg], PARAM_LEFT) == 0)
  257. {
  258. if (iarg + 1 < argc)
  259. {
  260. frame0Name = argv[++iarg];
  261. }
  262. else
  263. return -1;
  264. }
  265. if (strcmp(argv[iarg], PARAM_RIGHT) == 0)
  266. {
  267. if (iarg + 1 < argc)
  268. {
  269. frame1Name = argv[++iarg];
  270. }
  271. else
  272. return -1;
  273. }
  274. else if(strcmp(argv[iarg], PARAM_SCALE) == 0)
  275. {
  276. if (iarg + 1 < argc)
  277. desc.scale_factor = static_cast<Ncv32f>(atof(argv[++iarg]));
  278. else
  279. return -1;
  280. }
  281. else if(strcmp(argv[iarg], PARAM_ALPHA) == 0)
  282. {
  283. if (iarg + 1 < argc)
  284. desc.alpha = static_cast<Ncv32f>(atof(argv[++iarg]));
  285. else
  286. return -1;
  287. }
  288. else if(strcmp(argv[iarg], PARAM_GAMMA) == 0)
  289. {
  290. if (iarg + 1 < argc)
  291. desc.gamma = static_cast<Ncv32f>(atof(argv[++iarg]));
  292. else
  293. return -1;
  294. }
  295. else if(strcmp(argv[iarg], PARAM_INNER) == 0)
  296. {
  297. if (iarg + 1 < argc)
  298. desc.number_of_inner_iterations = static_cast<Ncv32u>(atoi(argv[++iarg]));
  299. else
  300. return -1;
  301. }
  302. else if(strcmp(argv[iarg], PARAM_OUTER) == 0)
  303. {
  304. if (iarg + 1 < argc)
  305. desc.number_of_outer_iterations = static_cast<Ncv32u>(atoi(argv[++iarg]));
  306. else
  307. return -1;
  308. }
  309. else if(strcmp(argv[iarg], PARAM_SOLVER) == 0)
  310. {
  311. if (iarg + 1 < argc)
  312. desc.number_of_solver_iterations = static_cast<Ncv32u>(atoi(argv[++iarg]));
  313. else
  314. return -1;
  315. }
  316. else if(strcmp(argv[iarg], PARAM_TIME_STEP) == 0)
  317. {
  318. if (iarg + 1 < argc)
  319. timeStep = static_cast<Ncv32f>(atof(argv[++iarg]));
  320. else
  321. return -1;
  322. }
  323. else if(strcmp(argv[iarg], PARAM_HELP) == 0)
  324. {
  325. PrintHelp ();
  326. return 0;
  327. }
  328. }
  329. return 0;
  330. }
  331. int main(int argc, char **argv)
  332. {
  333. char *frame0Name = 0, *frame1Name = 0;
  334. Ncv32f timeStep = 0.01f;
  335. NCVBroxOpticalFlowDescriptor desc;
  336. desc.alpha = 0.197f;
  337. desc.gamma = 50.0f;
  338. desc.number_of_inner_iterations = 10;
  339. desc.number_of_outer_iterations = 77;
  340. desc.number_of_solver_iterations = 10;
  341. desc.scale_factor = 0.8f;
  342. int result = ProcessCommandLine (argc, argv, timeStep, frame0Name, frame1Name, desc);
  343. if (argc == 1 || result)
  344. {
  345. PrintHelp();
  346. return result;
  347. }
  348. cv::cuda::printShortCudaDeviceInfo(cv::cuda::getDevice());
  349. std::cout << "OpenCV / NVIDIA Computer Vision\n";
  350. std::cout << "Optical Flow Demo: Frame Interpolation\n";
  351. std::cout << "=========================================\n";
  352. std::cout << "Press:\n ESC to quit\n 'a' to move to the previous frame\n 's' to move to the next frame\n";
  353. int devId;
  354. ncvAssertCUDAReturn(cudaGetDevice(&devId), -1);
  355. cudaDeviceProp devProp;
  356. ncvAssertCUDAReturn(cudaGetDeviceProperties(&devProp, devId), -1);
  357. std::cout << "Using GPU: " << devId << "(" << devProp.name <<
  358. "), arch=" << devProp.major << "." << devProp.minor << std::endl;
  359. g_pGPUMemAllocator = Ptr<INCVMemAllocator> (new NCVMemNativeAllocator (NCVMemoryTypeDevice, static_cast<Ncv32u>(devProp.textureAlignment)));
  360. ncvAssertPrintReturn (g_pGPUMemAllocator->isInitialized (), "Device memory allocator isn't initialized", -1);
  361. g_pHostMemAllocator = Ptr<INCVMemAllocator> (new NCVMemNativeAllocator (NCVMemoryTypeHostPageable, static_cast<Ncv32u>(devProp.textureAlignment)));
  362. ncvAssertPrintReturn (g_pHostMemAllocator->isInitialized (), "Host memory allocator isn't initialized", -1);
  363. int width, height;
  364. Ptr<NCVMatrixAlloc<Ncv32f> > src_host;
  365. Ptr<NCVMatrixAlloc<Ncv32f> > dst_host;
  366. IplImage *firstFrame, *lastFrame;
  367. if (frame0Name != 0 && frame1Name != 0)
  368. {
  369. ncvAssertReturnNcvStat (LoadImages (frame0Name, frame1Name, width, height, src_host, dst_host, firstFrame, lastFrame));
  370. }
  371. else
  372. {
  373. ncvAssertReturnNcvStat (LoadImages ("frame10.bmp", "frame11.bmp", width, height, src_host, dst_host, firstFrame, lastFrame));
  374. }
  375. Ptr<NCVMatrixAlloc<Ncv32f> > src (new NCVMatrixAlloc<Ncv32f> (*g_pGPUMemAllocator, src_host->width (), src_host->height ()));
  376. ncvAssertReturn(src->isMemAllocated(), -1);
  377. Ptr<NCVMatrixAlloc<Ncv32f> > dst (new NCVMatrixAlloc<Ncv32f> (*g_pGPUMemAllocator, src_host->width (), src_host->height ()));
  378. ncvAssertReturn (dst->isMemAllocated (), -1);
  379. ncvAssertReturnNcvStat (src_host->copySolid ( *src, 0 ));
  380. ncvAssertReturnNcvStat (dst_host->copySolid ( *dst, 0 ));
  381. #if defined SAFE_MAT_DECL
  382. #undef SAFE_MAT_DECL
  383. #endif
  384. #define SAFE_MAT_DECL(name, allocator, sx, sy) \
  385. NCVMatrixAlloc<Ncv32f> name(*allocator, sx, sy);\
  386. ncvAssertReturn(name.isMemAllocated(), -1);
  387. SAFE_MAT_DECL (u, g_pGPUMemAllocator, width, height);
  388. SAFE_MAT_DECL (v, g_pGPUMemAllocator, width, height);
  389. SAFE_MAT_DECL (uBck, g_pGPUMemAllocator, width, height);
  390. SAFE_MAT_DECL (vBck, g_pGPUMemAllocator, width, height);
  391. SAFE_MAT_DECL (h_r, g_pHostMemAllocator, width, height);
  392. SAFE_MAT_DECL (h_g, g_pHostMemAllocator, width, height);
  393. SAFE_MAT_DECL (h_b, g_pHostMemAllocator, width, height);
  394. std::cout << "Estimating optical flow\nForward...\n";
  395. if (NCV_SUCCESS != NCVBroxOpticalFlow (desc, *g_pGPUMemAllocator, *src, *dst, u, v, 0))
  396. {
  397. std::cout << "Failed\n";
  398. return -1;
  399. }
  400. std::cout << "Backward...\n";
  401. if (NCV_SUCCESS != NCVBroxOpticalFlow (desc, *g_pGPUMemAllocator, *dst, *src, uBck, vBck, 0))
  402. {
  403. std::cout << "Failed\n";
  404. return -1;
  405. }
  406. // matrix for temporary data
  407. SAFE_MAT_DECL (d_temp, g_pGPUMemAllocator, width, height);
  408. // first frame color components (GPU memory)
  409. SAFE_MAT_DECL (d_r, g_pGPUMemAllocator, width, height);
  410. SAFE_MAT_DECL (d_g, g_pGPUMemAllocator, width, height);
  411. SAFE_MAT_DECL (d_b, g_pGPUMemAllocator, width, height);
  412. // second frame color components (GPU memory)
  413. SAFE_MAT_DECL (d_rt, g_pGPUMemAllocator, width, height);
  414. SAFE_MAT_DECL (d_gt, g_pGPUMemAllocator, width, height);
  415. SAFE_MAT_DECL (d_bt, g_pGPUMemAllocator, width, height);
  416. // intermediate frame color components (GPU memory)
  417. SAFE_MAT_DECL (d_rNew, g_pGPUMemAllocator, width, height);
  418. SAFE_MAT_DECL (d_gNew, g_pGPUMemAllocator, width, height);
  419. SAFE_MAT_DECL (d_bNew, g_pGPUMemAllocator, width, height);
  420. // interpolated forward flow
  421. SAFE_MAT_DECL (ui, g_pGPUMemAllocator, width, height);
  422. SAFE_MAT_DECL (vi, g_pGPUMemAllocator, width, height);
  423. // interpolated backward flow
  424. SAFE_MAT_DECL (ubi, g_pGPUMemAllocator, width, height);
  425. SAFE_MAT_DECL (vbi, g_pGPUMemAllocator, width, height);
  426. // occlusion masks
  427. SAFE_MAT_DECL (occ0, g_pGPUMemAllocator, width, height);
  428. SAFE_MAT_DECL (occ1, g_pGPUMemAllocator, width, height);
  429. // prepare color components on host and copy them to device memory
  430. ncvAssertReturnNcvStat (CopyData<RgbToR> (firstFrame, h_r));
  431. ncvAssertReturnNcvStat (CopyData<RgbToG> (firstFrame, h_g));
  432. ncvAssertReturnNcvStat (CopyData<RgbToB> (firstFrame, h_b));
  433. ncvAssertReturnNcvStat (h_r.copySolid ( d_r, 0 ));
  434. ncvAssertReturnNcvStat (h_g.copySolid ( d_g, 0 ));
  435. ncvAssertReturnNcvStat (h_b.copySolid ( d_b, 0 ));
  436. ncvAssertReturnNcvStat (CopyData<RgbToR> (lastFrame, h_r));
  437. ncvAssertReturnNcvStat (CopyData<RgbToG> (lastFrame, h_g));
  438. ncvAssertReturnNcvStat (CopyData<RgbToB> (lastFrame, h_b));
  439. ncvAssertReturnNcvStat (h_r.copySolid ( d_rt, 0 ));
  440. ncvAssertReturnNcvStat (h_g.copySolid ( d_gt, 0 ));
  441. ncvAssertReturnNcvStat (h_b.copySolid ( d_bt, 0 ));
  442. std::cout << "Interpolating...\n";
  443. std::cout.precision (4);
  444. std::vector<IplImage*> frames;
  445. frames.push_back (firstFrame);
  446. // compute interpolated frames
  447. for (Ncv32f timePos = timeStep; timePos < 1.0f; timePos += timeStep)
  448. {
  449. ncvAssertCUDAReturn (cudaMemset (ui.ptr (), 0, ui.pitch () * ui.height ()), NCV_CUDA_ERROR);
  450. ncvAssertCUDAReturn (cudaMemset (vi.ptr (), 0, vi.pitch () * vi.height ()), NCV_CUDA_ERROR);
  451. ncvAssertCUDAReturn (cudaMemset (ubi.ptr (), 0, ubi.pitch () * ubi.height ()), NCV_CUDA_ERROR);
  452. ncvAssertCUDAReturn (cudaMemset (vbi.ptr (), 0, vbi.pitch () * vbi.height ()), NCV_CUDA_ERROR);
  453. ncvAssertCUDAReturn (cudaMemset (occ0.ptr (), 0, occ0.pitch () * occ0.height ()), NCV_CUDA_ERROR);
  454. ncvAssertCUDAReturn (cudaMemset (occ1.ptr (), 0, occ1.pitch () * occ1.height ()), NCV_CUDA_ERROR);
  455. NppStInterpolationState state;
  456. // interpolation state should be filled once except pSrcFrame0, pSrcFrame1, and pNewFrame
  457. // we will only need to reset buffers content to 0 since interpolator doesn't do this itself
  458. state.size = NcvSize32u (width, height);
  459. state.nStep = d_r.pitch ();
  460. state.pSrcFrame0 = d_r.ptr ();
  461. state.pSrcFrame1 = d_rt.ptr ();
  462. state.pFU = u.ptr ();
  463. state.pFV = v.ptr ();
  464. state.pBU = uBck.ptr ();
  465. state.pBV = vBck.ptr ();
  466. state.pos = timePos;
  467. state.pNewFrame = d_rNew.ptr ();
  468. state.ppBuffers[0] = occ0.ptr ();
  469. state.ppBuffers[1] = occ1.ptr ();
  470. state.ppBuffers[2] = ui.ptr ();
  471. state.ppBuffers[3] = vi.ptr ();
  472. state.ppBuffers[4] = ubi.ptr ();
  473. state.ppBuffers[5] = vbi.ptr ();
  474. // interpolate red channel
  475. nppiStInterpolateFrames (&state);
  476. // reset buffers
  477. ncvAssertCUDAReturn (cudaMemset (ui.ptr (), 0, ui.pitch () * ui.height ()), NCV_CUDA_ERROR);
  478. ncvAssertCUDAReturn (cudaMemset (vi.ptr (), 0, vi.pitch () * vi.height ()), NCV_CUDA_ERROR);
  479. ncvAssertCUDAReturn (cudaMemset (ubi.ptr (), 0, ubi.pitch () * ubi.height ()), NCV_CUDA_ERROR);
  480. ncvAssertCUDAReturn (cudaMemset (vbi.ptr (), 0, vbi.pitch () * vbi.height ()), NCV_CUDA_ERROR);
  481. ncvAssertCUDAReturn (cudaMemset (occ0.ptr (), 0, occ0.pitch () * occ0.height ()), NCV_CUDA_ERROR);
  482. ncvAssertCUDAReturn (cudaMemset (occ1.ptr (), 0, occ1.pitch () * occ1.height ()), NCV_CUDA_ERROR);
  483. // interpolate green channel
  484. state.pSrcFrame0 = d_g.ptr ();
  485. state.pSrcFrame1 = d_gt.ptr ();
  486. state.pNewFrame = d_gNew.ptr ();
  487. nppiStInterpolateFrames (&state);
  488. // reset buffers
  489. ncvAssertCUDAReturn (cudaMemset (ui.ptr (), 0, ui.pitch () * ui.height ()), NCV_CUDA_ERROR);
  490. ncvAssertCUDAReturn (cudaMemset (vi.ptr (), 0, vi.pitch () * vi.height ()), NCV_CUDA_ERROR);
  491. ncvAssertCUDAReturn (cudaMemset (ubi.ptr (), 0, ubi.pitch () * ubi.height ()), NCV_CUDA_ERROR);
  492. ncvAssertCUDAReturn (cudaMemset (vbi.ptr (), 0, vbi.pitch () * vbi.height ()), NCV_CUDA_ERROR);
  493. ncvAssertCUDAReturn (cudaMemset (occ0.ptr (), 0, occ0.pitch () * occ0.height ()), NCV_CUDA_ERROR);
  494. ncvAssertCUDAReturn (cudaMemset (occ1.ptr (), 0, occ1.pitch () * occ1.height ()), NCV_CUDA_ERROR);
  495. // interpolate blue channel
  496. state.pSrcFrame0 = d_b.ptr ();
  497. state.pSrcFrame1 = d_bt.ptr ();
  498. state.pNewFrame = d_bNew.ptr ();
  499. nppiStInterpolateFrames (&state);
  500. // copy to host memory
  501. ncvAssertReturnNcvStat (d_rNew.copySolid (h_r, 0));
  502. ncvAssertReturnNcvStat (d_gNew.copySolid (h_g, 0));
  503. ncvAssertReturnNcvStat (d_bNew.copySolid (h_b, 0));
  504. // convert to IplImage
  505. IplImage *newFrame = CreateImage (h_r, h_g, h_b);
  506. if (newFrame == 0)
  507. {
  508. std::cout << "Could not create new frame in host memory\n";
  509. break;
  510. }
  511. frames.push_back (newFrame);
  512. std::cout << timePos * 100.0f << "%\r";
  513. }
  514. std::cout << std::setw (5) << "100%\n";
  515. frames.push_back (lastFrame);
  516. Ncv32u currentFrame;
  517. currentFrame = 0;
  518. ShowFlow (u, v, "Forward flow");
  519. ShowFlow (uBck, vBck, "Backward flow");
  520. cvShowImage ("Interpolated frame", frames[currentFrame]);
  521. bool qPressed = false;
  522. while ( !qPressed )
  523. {
  524. int key = toupper (cvWaitKey (10));
  525. switch (key)
  526. {
  527. case 27:
  528. qPressed = true;
  529. break;
  530. case 'A':
  531. if (currentFrame > 0) --currentFrame;
  532. cvShowImage ("Interpolated frame", frames[currentFrame]);
  533. break;
  534. case 'S':
  535. if (currentFrame < frames.size()-1) ++currentFrame;
  536. cvShowImage ("Interpolated frame", frames[currentFrame]);
  537. break;
  538. }
  539. }
  540. cvDestroyAllWindows ();
  541. std::vector<IplImage*>::iterator iter;
  542. for (iter = frames.begin (); iter != frames.end (); ++iter)
  543. {
  544. cvReleaseImage (&(*iter));
  545. }
  546. return 0;
  547. }
  548. #endif