Fastest way to iterate over all Mat_<Vec3b> pixels and change their value

asked 2015-01-21 11:33:09 -0500

I'm trying to display the Kinect stream (SDK v1.7) using a Mat_<Vec3b> Here's my code, which is not at all efficient.

void Sensor::getColorFrame(Mat_<Vec3b> mat)
{
    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);
}

Now, from the documentation I understand that I should use pointers to access pixels in order to speed this up. My question is are Mat_<Vec3b>s stored in the memory the same way as Mats are?

Code snippets would be greatly appreciated.

edit retag flag offensive close merge delete

Comments

2

the fastest way is usually not iterating over the pixels . try:

// create a new header w/o copying pixels
Mat m(480,640,CV_8UC4, pointerToTheByteBeingRead); 
Mat bgr; 
cvtColor(m,bgr,CV_BGRA2BGR); // devs have been working hard to make this fast !
berak gravatar imageberak ( 2015-01-21 12:17:58 -0500 )edit