【问题标题】:OpenCV 2.3: Convert Mat to RGBA pixel arrayOpenCV 2.3:将 Mat 转换为 RGBA 像素数组
【发布时间】:2012-05-03 03:42:25
【问题描述】:

我正在尝试使用 OpenCV 从网络摄像头抓取帧并使用 SFML 在窗口中显示它们。

VideoCapture 以 OpenCV 的 Mat 格式返回帧。为了显示帧,SFML 需要 uint8 格式的一维像素数组,(据我所知)可以与 uchar 互换。该数组预计代表每像素 32 位的 RGBA。

所以,我有一个 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

不幸的是,这并不完全奏效。该循环中的某些内容是错误的,因为当我加载和显示 camData 时生成的图像被打乱了。

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

有什么想法吗?

【问题讨论】:

  • 乱码到底是什么意思?您能否发布结果图像的示例?
  • Example。源图像中的像素数据没有在目标数组中的正确位置结束,因此会产生奇怪的交错模式。
  • 在从 gpu/opencl 拉回数据并将其转储到文件后具有相同的模式:D

标签: c++ opencv webcam sfml


【解决方案1】:

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】:

我更喜欢接受的答案,但这个 sn-p 可以帮助您了解正在发生的事情。

 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】:

    对我来说,代码如下:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-04
      • 1970-01-01
      • 1970-01-01
      • 2020-09-15
      • 2016-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多