从QByteArray创建一个合适的cv :: Mat,包含YUV420p帧

时间:2017-12-29 11:23:49

标签: c++ qt opencv

我有一个.yuv文件,其中包含YUV420p格式的560x320帧,我想通过使用opencv将每个帧解码为RGB来播放它。 我知道,一帧的大小必须是268800字节(560x320x12位/ 8,因为YUV420p每像素有12位)。

所以我打开文件并逐帧读取,将每个268800字节存储在QByteArray中:

qint64 SIZE_OF_YUV420p_FRAME = 268800;
QByteArray  sendBuffer;

   QFile file("/home/YUVdecoding/small.yuv");

if(file.open(QIODevice::ReadOnly))
    {
       while (!file.atEnd()) {

             sendBuffer = file.read(SIZE_OF_YUV420p_FRAME); //capture one frame
             cv::Mat yuvImg = cv::Mat(560+280,320,CV_8UC1,sendBuffer.data()); //translating QByteArray to Mat
             cv::Mat rgbImage;
             cv::cvtColor(yuvImg,rgbImage,cv::COLOR_YUV420p2RGB);// converting to RGB
             cv::imshow("bgr",rgbImage);
             cv::waitKey(30);
       }

    }
    file.close();

为什么yuvImg行是560 + 280?因为560有致命错误,我不知道为什么。然后我在互联网上找到了这段代码:

QVideoFrame copy(frame);
if (frame.isValid() && copy.map(QAbstractVideoBuffer::ReadOnly)) {
  Mat frameYUV=Mat(copy.height() + copy.height()/2, copy.width(),CV_8UC1, (void*)copy.bits() );

  Mat frameRGB;
  cvtColor(frameYUV, frameRGB, CV_YUV2BGRA_I420);

  imshow("Video", frameRGB);
}

所以这里它的高度+高度/ 2我尝试了它(560/2 = 280)。突然,它工作,视频播放很好,但所有帧看起来 像这样:

enter image description here

它甚至有错误的分辨率。

.yuv文件中的原始框架如下所示: enter image description here

我玩了另一种Mat尺寸,是的,它对图像显示的正确性有所了解,但我无法达到原始的框架外观。 如何正确地从QByteArray创建Mat?如何计算合适的垫尺寸?

1 个答案:

答案 0 :(得分:0)

成立解决方案: cv :: Mat行和列必须是560+280,320而不是vector<Observer>。 奇怪的是,它使用8位设置正确解码12位图像,但其工作正常