C++ OpenCV 2.3:将 Mat 转换为 RGBA 像素阵列
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10265125/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
OpenCV 2.3: Convert Mat to RGBA pixel array
提问by Thew
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 格式的一维像素数组,(据我所知)可以与 uchar 互换。该数组预计代表 32 位/像素 RGBA。
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?
有任何想法吗?
回答by Andrey Kamaev
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);
回答by Antzi
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 ];
}
}
回答by Go_Da
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) 是一个预乘图像!