OpenCV 2.3: Convert Matrix to RGBA Matrix

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

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

So, I have a uchar array, and I iterate over the Mat data and copy 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 does not work. Something in this loop is incorrect, since the resulting image is scrambled when loading and displaying camData.

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

Any ideas?

+6
source share
3 answers

OpenCV can do all the work 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); 
+9
source

I like the accepted answer better, but this snippet helps to understand what is happening.

  for (int i=0; i<srcMat.rows; i++) { for (int j=0; j<srcMat.cols; j++) { int index = (i*srcMat.cols+j)*4; // copy while converting to RGBA order dstRBBA[index + 0] = srcMat[index + 2 ]; dstRBBA[index + 1] = srcMat[index + 1 ]; dstRBBA[index + 2] = srcMat[index + 0 ]; dstRBBA[index + 3] = srcMat[index + 3 ]; } } 
+3
source

The following code worked for me:

 VideoCapture capture(0); Mat mat_frame; capture >> mat_frame; // get a new frame from camera // Be sure that we are dealing with RGB colorspace... Mat rgbFrame(width, height, CV_8UC3); cvtColor(mat_frame, rgbFrame, CV_BGR2RGB); // ...now let it convert it to RGBA Mat newSrc = Mat(rgbFrame.rows, rgbFrame.cols, CV_8UC4); int from_to[] = { 0,0, 1,1, 2,2, 3,3 }; mixChannels(&rgbFrame, 2, &newSrc, 1, from_to, 4); 

The result (newSrc) is a premultiplom image!

+1
source

All Articles