2015-01-21 7 views
0

Я пытаюсь получить каждый кадр потока, созданный камерой RGB Kinect (с использованием SDK версии 1.8), в OpenCV (2.4.10) Mat_<Vec3b>. Это мой текущий алгоритм, который не совсем быстро:Отображение потоков Kinect с использованием OpenCV (C++)

Mat_<Vec3b> mat = Mat::zeros(480, 640, CV_8UC3); 

NUI_IMAGE_FRAME imageFrame; 
NUI_LOCKED_RECT lockedRect; 

if (sensor->NuiImageStreamGetNextFrame(colorStream, 0, &imageFrame) < 0) { return; } 

INuiFrameTexture* texture = imageFrame.pFrameTexture; 
texture->LockRect(0, &lockedRect, NULL, 0); 


if (lockedRect.Pitch != 0) 
{ 
    BYTE* upperLeftCorner = (BYTE*)lockedRect.pBits; 
    BYTE* pointerToTheByteBeingRead = upperLeftCorner; 

    for (int i = 0; i < 480; i++) 
    { 
     for (int j = 0; j < 640; j++) 
     { 
      unsigned char r = *pointerToTheByteBeingRead; 
      pointerToTheByteBeingRead += 1; 
      unsigned char g = *pointerToTheByteBeingRead; 
      pointerToTheByteBeingRead += 1; 
      unsigned char b = *pointerToTheByteBeingRead; 
      pointerToTheByteBeingRead += 2; //So to skip the alpha channel 

      mat.at<Vec3b>(Point(j, i))[0] = r; 
      mat.at<Vec3b>(Point(j, i))[1] = g; 
      mat.at<Vec3b>(Point(j, i))[2] = b; 
     } 
    } 

} 

texture->UnlockRect(0); 
sensor->NuiImageStreamReleaseFrame(colorStream, &imageFrame); 

Я проверил the OpenCV documentation и я понимаю, что я должен использовать доступ указателя для повышения эффективности. Являются ли Mat_<Vec3b> s сохранены в памяти так же, как Mat, или я должен сделать другую арифметику указателя?

Кроме того, я понимаю, что обновление каждого пикселя каждый раз не является самым эффективным способом достижения отображения потока через Mat. Что еще я мог сделать?

ответ

0

Наконец-то выяснилось, как использовать арифметику указателя. Код не требует пояснений:

Mat_<Vec3b> mat = Mat::zeros(480, 640, CV_8UC3); 

NUI_IMAGE_FRAME imageFrame; 
NUI_LOCKED_RECT lockedRect; 

if (sensor->NuiImageStreamGetNextFrame(colorStream, 0, &imageFrame) < 0) { return; } 

INuiFrameTexture* texture = imageFrame.pFrameTexture; 
texture->LockRect(0, &lockedRect, NULL, 0); 


if (lockedRect.Pitch != 0) 
{ 
    BYTE* upperLeftCorner = (BYTE*)lockedRect.pBits; 
    BYTE* pointerToTheByteBeingRead = upperLeftCorner; 

    for (int i = 0; i < 480; i++) 
    { 
     Vec3b *pointerToRow = mat.ptr<Vec3b>(i); 

     for (int j = 0; j < 640; j++) 
     { 
      unsigned char r = *pointerToTheByteBeingRead; 
      pointerToTheByteBeingRead += 1; 
      unsigned char g = *pointerToTheByteBeingRead; 
      pointerToTheByteBeingRead += 1; 
      unsigned char b = *pointerToTheByteBeingRead; 
      pointerToTheByteBeingRead += 2; //So to skip the alpha channel 

      pointerToRow[j] = Vec3b(r, g, b); 
     } 
    } 

} 

texture->UnlockRect(0); 
sensor->NuiImageStreamReleaseFrame(colorStream, &imageFrame); 
Смежные вопросы