如何从 yuv 帧中获取形状(宽度、高度、3)的额外维度值

How to get extra dimension value in shape (width, height, 3) from yuv frame

我有一些代码可以读取一些 yuv 帧和 returns 单独的组件,我试图将其集成到一些读取 mp4 文件并在之后进行一些处理的代码中,调用的函数取决于形状的形式是(宽度,高度,3),单独的 y u v 组件返回的只是(宽度,高度),所以我如何才能获得额外的 3 的维度和什么样的值包含在第 3 个维度中?一切尽在 python

所以我的视频是1920,1080,

y, u, v = getComponents(video,60) #60 是帧

newFrame = modifyFrame(frames) # 这是来自原始代码,期望数组形状为 (1920,1080,3)

如果我执行 print(y.shape) 我会得到没有第三维的 (1920,1080),我需要输入表单是 modifyFrame 方法所需的表单。也许有可能以某种方式组合 y、u、v 组件并获得第三个维度,老实说我不确定

抱歉,如果答案可能很明显我是新手

谢谢

你可以试试

>>> y.shape, u.shape, v.shape

((1920, 1080), (1920, 1080), (1920, 1080))

>>> frame = np.r_[y,u,v]
>>> frame = frame.reshape(-1,frame.shape[1],3)
>>> frame.shape
(1920, 1080, 3)

它会做的是堆叠 y uv 帧。 希望有帮助

您必须合并所有帧或为每个堆叠的 yuv 帧组合调用您的函数。这将取决于您的用例和性能要求

编辑

如果你的 Y, U, V 有不同的形状,试试这个。

>>> y.shape, u.shape, v.shape
((1080, 1920), (540, 960), (540, 960))

>>> u1 = np.pad(u, ((0, 540), (0, 960)), 'constant')
>>> v1 = np.pad(v, ((0, 540), (0, 960)), 'constant')
>>> u1.shape
(1080, 1920)
>>> v1.shape
(1080, 1920)

>>> frame = np.r_[y,u1,v1].reshape(-1,1920,3)
>>> frame.shape
(1080, 1920, 3)

更新

要取回您可以做的值

>>> y2 = frame.T[0]
>>> y2.shape
(1080, 1920)
>>> u2 = frame.T[1][0:540,0:960]
>>> u2.shape
(540, 960)
>>> v2 = frame.T[2][0:540,0:960]
>>> v2.shape
(540, 960)

顺便说一句,对于第一部分,您还可以完成以下操作,这样会容易得多:)

>>> u1 = np.pad(u, ((0, 540), (0, 960)), 'constant')
>>> v1 = np.pad(v, ((0, 540), (0, 960)), 'constant')

>>> frame = np.array([y,u1,v1]).T
>>> frame.shape
(1920, 1080, 3)

根据维度,视频帧数据格式为YUV 420

为了将 3 个矩阵 YUV 从 420 格式转换为 3 维 YUV 矩阵,您首先需要调整大小 UVY 相同的分辨率,然后将它们堆叠到 3D 矩阵。

备注:YUV shape约定为(height, width, 3), as (1080, 1920, 3).

  • 要调整大小,您可以使用 cv2.resize
    建议使用三次插值(比线性插值质量更好)。
  • 对于 3D 堆叠,可以使用 numpy dstack 函数。

这是一个代码示例:

import cv2
import numpy as np

# Upscale u and v to be same resolution as y (1920 columns by 1080 rows)
u = cv2.resize(u, dsize=y.shape[::-1], interpolation=cv2.INTER_CUBIC)  # Use shape[::-1], to reverse the order of shape to be (cols, rows)
v = cv2.resize(v, dsize=y.shape[::-1], interpolation=cv2.INTER_CUBIC)

# Stack y, u, v in the third dimension
yuv = np.dstack([y, u, v])