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

ama*_*ion 6 python opencv image-processing yuv python-3.x

我想用openCV阅读YUV视频。YUV视频为1920 * 1080,并使用YUV422格式(我已经尝试使用yuviewer读取此视频,并且可以正常工作)

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

首先我尝试了这个脚本/sf/answers/3347076981/但是这行

cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_Y422)
Run Code Online (Sandbox Code Playgroud)

给我这个错误。

  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
Run Code Online (Sandbox Code Playgroud)

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

在我下面的脚本中,除最后一个之外,所有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)
Run Code Online (Sandbox Code Playgroud)

编辑

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)
Run Code Online (Sandbox Code Playgroud)

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

我的结果:

我在numpy.array中手动查看,并与YUView进行了比较,像素值和形状与我期望的一致(Y值然后是U,然后是V),但这不是opencv所显示的。

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

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

bie*_*ltb 1

由于 YUV 4:2:2 有一些变体,如果您能准确找到您的 YUV 格式,会更容易。我使用 Logitech Brio 网络摄像头通过 ffmpeg 拍摄 YUV 视频,它为我提供了(YUY2 / 0x32595559), yuyv422. 这也是 YUV 4:2:2,但字节顺序有一些差异。

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

frame_len = int(width * height * 2)
shape = (height, width, 2)
Run Code Online (Sandbox Code Playgroud)

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

bgr = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_YUY2)
Run Code Online (Sandbox Code Playgroud)