尝试将cvtColor与cv2.COLOR_YUV2BGR_Y422一起使用时出错 - 错误:(-215)scn == 2&&函数cv :: cvtColor中的depth == 0

时间:2018-03-19 11:12:25

标签: python python-3.x opencv image-processing yuv

我想用openCV阅读YUV视频。 YUV视频是1920 * 1080并使用YUV422格式(我已经尝试用yuviewer阅读此视频并且它有效)

我正在使用带有OpenCV 3.3.1的Anaconda环境的Python3.6.4

首先我尝试了这个脚本https://stackoverflow.com/a/47815385/8236556,但是这行

cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_Y422)

给了我这个错误。

  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

尝试从Y444或Y420转换为RGB或RGBA或GRAY时,我也遇到此错误。 我没有在google或stackoverflow上找到完全相同的错误。 我试图重新安装opencv软件包,但它没有用。

在我的脚本下面,除了最后一个cvtColor之外,每个cvtColor都有效。通过工作我的意思是它显示图像,但错误的颜色。

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)

修改

scn == 2表示该功能需要2通道图像。 我改变了这些路线:

frame_len = 1920 * 1080 * 2 # 4 Bytes for 2 pixels
shape = (height, width, 2) # To have a 2 channels image (not really working obviously)

和cv2.cvtColor不再抛出错误但仍无法正常工作。我认为我的重塑是完全错误的。

我的结果:

我在numpy.array中手动查看并与YUView比较像素的值和形状对应于我所期望的(Y值然后是U然后是V)但是这不是opencv正在显示的内容。 / p>

为什么原始帧中的Y矩阵下面有4个图像?

更准确地说,在我的情况下,cv2.cvtColor函数的输入中应该如何形成数据?

1 个答案:

答案 0 :(得分:0)

由于YUV 4:2:2有一些变体,因此,如果您确切地找到YUV格式是什么会更容易。我使用Logitech Brio网络摄像头通过ffmpeg拍摄YUV视频,这使我在(YUY2 / 0x32595559), yuyv422中获得YUV。这也是YUV 4:2:2,但字节顺序有所不同。

由于YUV 4:2:2的压缩率为2/3,因此正确使用2个字节表示1个像素。这对我有用。

frame_len = int(width * height * 2)
shape = (height, width, 2)

并从YUV转换为BGR(opencv格式):

bgr = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_YUY2)