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