python RGB图片转YUYV

时间:2018-08-31 07:32:47

标签: python yuv

我想将位图转换为YUV422(YUYV)格式。 我已经在Google上搜索YUYV格式,并尝试编写此代码。

path = "C:/Users/hogan/Desktop/red.bmp"
image = Image.open(path).convert("YCbCr")  # YUV
image = np.asarray(image)
width, height, YUYV = image.shape[1], image.shape[0], 4
array = np.empty((height * width * 3), dtype="uint8")
Y, U, V = 0, 1, 2
count = 0
for i in range(len(image)):
    for j in range(len(image[i])):
        for k in range(len(image[i][j])):
            if (count % 4 == 0):
                array[count] = image[i][j][Y]
            if (count % 4 == 1):
                array[count] = image[i][j][U]
            if (count % 4 == 2):
                array[count] = image[i][j][Y]
            if (count % 4 == 3):
                array[count] = image[i][j][V]
            count = count + 1
array.astype('uint8').tofile("C:/Users/hogan/Desktop/tmpdir/1.raw")

我阅读了这张图片,知道我的代码是错误的,但不知道如何正确处理。 enter image description here 例如 :   YUV中的红色(255,0,0)是(76,84,255),如果我有很多像素,我不知道应该删除哪个“ U”和“ V”。

如果使用我的代码转换480 * 640(W * H),它将是960 * 480。

1 个答案:

答案 0 :(得分:0)

您可以在此处使用numpy高级索引和广播。

假设您有一张图片:

ycbcr = np.array([
    [['Y00', 'U00', 'V00'], ['Y01', 'U01', 'V01'], ['Y02', 'U02', 'V02']],
    [['Y10', 'U10', 'V10'], ['Y11', 'U11', 'V11'], ['Y12', 'U12', 'V12']],
    [['Y20', 'U20', 'V20'], ['Y21', 'U21', 'V21'], ['Y22', 'U22', 'V22']],
], dtype=str)

使用3D数组将很麻烦,因此让我们将其转换为1D:

ycbcr = ycbcr.reshape(27)

然后,我将为YUYV流分配一个数组:

yuyv = np.array(['   ' for _ in range(18)])  # '   ' is basically because
# I use strings in this example. You'd probably want to use arrays of uint8

第一步是最简单的-我们将ycbcr(Y分量)的每个第三个值取到yuyv的偶数位置:

yuyv[::2] = ycbcr[::3]

然后我们继续其他字节。 U00从位置1移至位置1,V00从2移至3,U01V01被省略,U02从7移至5,{ {1}}从8变为7,V02被省略,依此类推:

U03

因此,您得到以下yuyv[1::4] = ycbcr[1::6] # Moving U, every sixth byte starting from position 1 yuyv[3::4] = ycbcr[2::6][:-1] # Moving V, dropping last element of V ,就像建议的图像一样:

yuyv

如果您想遵循@alkanen的建议,该方法也是可行的,您只需要在两个数组中采样U和V字节并取平均值即可。也许看起来像这样:(未经测试)

array(['Y00', 'U00', 'Y01', 'V00', 'Y02', 'U02', 'Y10', 'V02', 'Y11',
       'U11', 'Y12', 'V11', 'Y20', 'U20', 'Y21', 'V20', 'Y22', 'U22'],
dtype='<U3')

也将遇到更复杂的边境案件。