小智 8

我写了一个非常简单的python代码来从二进制文件中读取YUV NV21流.

import cv2
import numpy as np

class VideoCaptureYUV:
    def __init__(self, filename, size):
        self.height, self.width = size
        self.frame_len = self.width * self.height * 3 / 2
        self.f = open(filename, 'rb')
        self.shape = (int(self.height*1.5), self.width)

    def read_raw(self):
        try:
            raw = self.f.read(self.frame_len)
            yuv = np.frombuffer(raw, dtype=np.uint8)
            yuv = yuv.reshape(self.shape)
        except Exception as e:
            print str(e)
            return False, None
        return True, yuv

    def read(self):
        ret, yuv = self.read_raw()
        if not ret:
            return ret, yuv
        bgr = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_NV21)
        return ret, bgr


if __name__ == "__main__":
    #filename = "data/20171214180916RGB.yuv"
    filename = "data/20171214180916IR.yuv"
    size = (480, 640)
    cap = VideoCaptureYUV(filename, size)

    while 1:
        ret, frame = cap.read()
        if ret:
            cv2.imshow("frame", frame)
            cv2.waitKey(30)
        else:
            break
Run Code Online (Sandbox Code Playgroud)


小智 5

如前所述,有很多类型的YUV格式:

http://www.fourcc.org/yuv.php

在OpenCV中从YUV格式转换为RGB非常简单:

  1. 为该框架数据创建一个适当大小的一维OpenCV Mat
  2. 为具有所需尺寸和3个通道的RGB数据创建一个空的Mat
  3. 最后,使用正确的转换标志枚举,使用cvtColor在两个Mats之间进行转换

这是YV12格式的YUV缓冲区的示例:

Mat mYUV(height + height/2, width, CV_8UC1, (void*) frameData);
Mat mRGB(height, width, CV_8UC3);
cvtColor(mYUV, mRGB, CV_YUV2RGB_YV12, 3);
Run Code Online (Sandbox Code Playgroud)

关键技巧是转换之前定义RGB Mat的尺寸。


Sté*_*ard 1

我认为至少在当前版本中这是不可能的。当然,这并不难做到,但它并不是一个有趣的功能,因为:

  • OpenCV通常适用于RGB格式的网络摄像头流,或直接解码为RGB以用于显示目的的编码文件;
  • OpenCV 致力于计算机视觉,例如,YUV 是一种不如编码社区常见的格式;
  • 有很多不同的 YUV 格式,这意味着实现它们需要大量的工作。

不过,使用 仍然可以进行转换cvCvtColor(),这意味着无论如何它还是有一定意义的。