OpenCV 2.3:将Mat转换为RGBA像素数组。

时间:2022-12-14 04:26:07

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

我正在尝试使用OpenCV从网络摄像头获取帧,并在窗口中使用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.

VideoCapture以OpenCV的Mat格式返回帧。为了显示帧,SFML需要一个uint8格式的1D像素数组,这(据我所知)与uchar是可互换的。这个数组将表示每个像素RGBA的32位。

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

因此,我有一个uchar数组,我在Mat数据上循环,并复制每个像素:

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.

不幸的是,这并不奏效。在这个循环中,有些东西是错误的,当我加载和显示camData的时候,结果图像是混乱的。

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.

据我所知,我在循环中的数学是错误的,所以像素被分配错了,或者Mat数据的格式不是BGR。

Any ideas?

什么好主意吗?

3 个解决方案

#1


10  

OpenCV can do all job for you:

OpenCV可以为你做所有的工作:

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

#2


3  

I like the accepted answer better but this snippet helps you understand what's going on.

我更喜欢被接受的答案,但是这段代码可以帮助您理解发生了什么。

 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


1  

For me worked following code:

对我来说,工作的代码如下:

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 premultiply image!

结果(newSrc)是一个预乘图像!

#1


10  

OpenCV can do all job for you:

OpenCV可以为你做所有的工作:

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

#2


3  

I like the accepted answer better but this snippet helps you understand what's going on.

我更喜欢被接受的答案,但是这段代码可以帮助您理解发生了什么。

 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


1  

For me worked following code:

对我来说,工作的代码如下:

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 premultiply image!

结果(newSrc)是一个预乘图像!