OpenCV 2.3: Convert Mat to RGBA pixel array

Thew picture Thew · Apr 22, 2012 · Viewed 30.5k times · Source

I am attempting to use OpenCV to grab frames from a webcam and display them in a window using SFML.

VideoCapture returns frames in OpenCV's Mat format. To display the frames, SFML requires a 1D array of pixels in its uint8 format, which (as far as I can tell) is interchangeable with uchar. This array is expected to represent 32 bits per pixel RGBA.

So, I have a uchar array, and I'm looping over the Mat data and copying each pixel:

VideoCapture cap(0);
Mat frame;
cap >> frame;

uchar* camData = new uchar[640*480*4];
uchar* pixelPtr = frame.data;
for(int i = 0; i < frame.rows; i++)
{
    for(int j = 0; j < frame.cols; j++)
    {
        camData[i*frame.cols + j + 2] = pixelPtr[i*frame.cols + j + 0]; // B
        camData[i*frame.cols + j + 1] = pixelPtr[i*frame.cols + j + 1]; // G
        camData[i*frame.cols + j + 0] = pixelPtr[i*frame.cols + j + 2]; // R
        camData[i*frame.cols + j + 3] = 255;

    }
}
img.LoadFromPixels(640, 480, camData); //Load pixels into SFML Image object for display

Unfortunately, this doesn't quite work. Something in that loop is wrong, as the resulting image when I load and display camData is scrambled.

As far as I can discern, either my math in the loop is wrong so the pixels are being assigned wrong, or the Mat data is in some format other than BGR.

Any ideas?

Answer

Andrey Kamaev picture Andrey Kamaev · Apr 22, 2012

OpenCV can do all job for you:

VideoCapture cap(0);
Mat frame;
cap >> frame;

uchar* camData = new uchar[frame.total()*4];
Mat continuousRGBA(frame.size(), CV_8UC4, camData);
cv::cvtColor(frame, continuousRGBA, CV_BGR2RGBA, 4);
img.LoadFromPixels(frame.cols, frame.rows, camData);