I want to read a YUV video with openCV. The YUV video is 1920*1080 and use the YUV422 format (I already tried to read this video with yuviewer and it worked)
I am using Python3.6.4 with an Anaconda environnement with OpenCV 3.3.1
First I tried this script https://stackoverflow.com/a/47815385/8236556 but this line
cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_Y422)
is giving me this error.
File "read-yuv-video.py", line 29, in <module>
bgr = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_UYVY)
cv2.error: C:\ci\opencv_1512688052760\work\modules\imgproc\src\color.cpp:11228: error: (-215) scn == 2 && depth == 0 in function cv::cvtColor
I also have this error when try to convert from Y444 or Y420 to RGB or RGBA or GREY. I didn't find the exact same error on google or stackoverflow. I tried to reinstall the opencv package but it didn't worked.
In my script below every cvtColor works except the last one. By working I mean it display the image but the wrong colors.
import numpy as np
import cv2
# filename = r'C:\myPath\voile.yuv'
filename = r'C:\myPath\credits.yuv'
yuv_file = open(filename, 'rb')
frame_len = 1920 * 1080 * 3/2
shape = (int(1080 * 1.5), 1920)
raw = yuv_file.read(int(frame_len))
yuv = np.frombuffer(raw, dtype=np.uint8)
yuv = yuv.reshape(shape)
yuv = cv2.resize(yuv, (0, 0), fx=0.5, fy=0.5)
cv2.imshow("raw yuv", yuv)
cv2.waitKey(0)
bgr = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_NV21)
cv2.imshow("YUV2BGR_NV21", bgr)
cv2.waitKey(0)
bgr = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_NV12)
cv2.imshow("YUV2BGR_NV12", bgr)
cv2.waitKey(0)
bgr = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_I420)
cv2.imshow("YUV2BGR_I420", bgr)
cv2.waitKey(0)
bgr = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_Y422)
cv2.imshow("YUV2BGR_Y422", bgr)
cv2.waitKey(0)
Edit
scn == 2 means the function needs a 2 channels image. I changed these lines:
frame_len = 1920 * 1080 * 2 # 4 Bytes for 2 pixels
shape = (height, width, 2) # To have a 2 channels image (not really working obviously)
and cv2.cvtColor is not throwing an error anymore but still not working properly. I assume my reshape is completely wrong.
My results:
I looked manually in the numpy.array and compared with YUView the value of pixels and the shape correspond to what I am expecting (the Y values then U then V) but that's not what opencv is displaying.
Why there is 4 images below the Y matrix in the raw frame?
More precisely, how should be the shape of the datas in input of the cv2.cvtColor function in my case?
cv2. cvtColor() method is used to convert an image from one color space to another. There are more than 150 color-space conversion methods available in OpenCV. We will use some of color space conversion codes below.
cv2 rectangle implementation in Python: Only 4 Steps importerror no module named cv2 error occurs when cv2 module is not properly installed or its path is not properly set or configured.
As YUV 4:2:2 has some variants, it would be easier if you can find exactly what is your YUV format. I use Logitech Brio Webcam to shoot YUV videos with ffmpeg which gives me the YUV in (YUY2 / 0x32595559), yuyv422
. This is also the YUV 4:2:2 but has some differences in the order of bytes.
As YUV 4:2:2 compression ratio is 2/3, you were correct to use 2 bytes for 1 pixel. This worked for me.
frame_len = int(width * height * 2)
shape = (height, width, 2)
And to convert from YUV to BGR (opencv format):
bgr = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_YUY2)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With