Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read a frame from YUV file in OpenCV?

How to read a frame from YUV file in OpenCV?

like image 318
Jason Avatar asked Feb 09 '10 18:02

Jason


People also ask

What is YUV video format?

YUV formats are divided into packed formats and planar formats. In a packed format, the Y, U, and V components are stored in a single array. Pixels are organized into groups of macropixels, whose layout depends on the format. In a planar format, the Y, U, and V components are stored as three separate planes.


2 Answers

I wrote a very simple python code to read YUV NV21 stream from binary file.

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
like image 156
xianyanlin Avatar answered Sep 16 '22 12:09

xianyanlin


As mentioned, there are MANY types of YUV formats:

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

To convert to RGB from a YUV format in OpenCV is very simple:

  1. Create a one-dimensional OpenCV Mat of the appropriate size for that frame data
  2. Create an empty Mat for the RGB data with the desired dimension AND with 3 channels
  3. Finally use cvtColor to convert between the two Mats, using the correct conversion flag enum

Here is an example for a YUV buffer in YV12 format:

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

The key trick is to define the dimensions of your RGB Mat before you convert.

like image 22
Aaron Becker Avatar answered Sep 18 '22 12:09

Aaron Becker