Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error trying to use cvtColor with cv2.COLOR_YUV2BGR_Y422 - error: (-215) scn == 2 && depth == 0 in function cv::cvtColor

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:

  • Original frame
  • Raw frame, reshape(height*2, width)
  • YUV2BGR_Y422, reshape(height, width, 2)

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?

like image 651
amarion Avatar asked Mar 19 '18 11:03

amarion


People also ask

What is cv2 cvtColor in Python?

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.

What is cv2 error?

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.


1 Answers

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)
like image 58
biendltb Avatar answered Sep 19 '22 19:09

biendltb