OpenCV - 从 BGRA 输出创建 CV_8UC3(3 通道)垫

OpenCV - Create CV_8UC3 (3 channel) Mat from BGRA output

本文关键字:8UC3 通道 CV BGRA 输出 创建 OpenCV      更新时间:2023-10-16

我有一个AVCaptureSession,它输出BGRA像素的CMSampleBuffer。我尝试仅从BGR创建对象Mat,以最有效的方式使用数据指针

 CVPixelBufferLockBaseAddress(imageBuffer,0);
 void *baseaddress = CVPixelBufferGetBaseAddress(imageBuffer);
 CGRect videoRect = CGRectMake(0.0f, 0.0f, CVPixelBufferGetWidth(imageBuffer), CVPixelBufferGetHeight(imageBuffer));
 size_t bytesPerRow = (((CVPixelBufferGetBytesPerRow(imageBuffer)
 cv::Mat frame(videoRect.size.height, videoRect.size.width,CV_8UC3  , baseaddress,    bytesPerRow);

但它似乎不起作用。有什么建议吗?

Mat中的数据必须是连续的(最终在每行末尾添加一些额外的填充)。

您的数据如下:

row 0: B G R A B G R A ... B G R A <padding>
row 1: B G R A B G R A ... B G R A <padding>
...

而且您无法读取以下数据:

row 0: B G R - B G R - ... B G R - <padding>
row 1: B G R - B G R - ... B G R - <padding>
...

您可以做的是将BGRA数据包装在CV_8UC4矩阵中(即在数据上构建矩阵标头):

cv::Mat frameBGRA (height, width, CV_8UC4, buffer);

,然后仅复制所需的字节:

cv::Mat frameBGR;
cv::cvtColor(frameBGRA, frameBGR, cv::COLOR_BGRA2BGR);

另一种解决方案是仅手动将所需的数据复制到 BGR 矩阵中(4 是 BGRA 中的通道数):

// Create the BGR (3 channel) matrix
cv::Mat3b frameBGR(height, width);

for(int r = 0; r < height; ++r) {
    for(int c = 0; c < width; ++c) {
        // Copy only BGR
        frameBGR(r,c)[0] = buffer((r * c * 4) + (c * 4) + 0); // Blue
        frameBGR(r,c)[1] = buffer((r * c * 4) + (c * 4) + 1); // Green
        frameBGR(r,c)[2] = buffer((r * c * 4) + (c * 4) + 2); // Red
        // Don't consider Alpha channel
        // buffer((r * c * 4) + (c * 4) + 3); // Alpha
    }
}