使用 OpenCV (C++) 显示 Kinect 流

Displaying Kinect streams using OpenCV (C++)

我正在尝试将 Kinect 的 RGB 相机(使用 SDK 版本 1.8)生成的流的每一帧导入 OpenCV (2.4.10) Mat_<Vec3b>。这是我目前的算法,一点也不快:

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 存储在内存中的方式是否与 Mats 相同,还是我应该做一些其他的指针运算?

此外,我了解每次更新每个像素并不是通过 Mat 实现流显示的最有效方式。我还能做什么?

终于想通了如何使用指针运算。代码不言自明:

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);