根据write_video 文档,video_array 参数格式是“包含单个帧的张量,作为 [T, H, W, C] 格式的 uint8 张量”。
entire_video 的维度是 (1, 3, 45, 256, 128),所以有 5 个维度而不是 4 个维度。
异常说 ndim 3 但得到 4(不是 4 和 5),因为在内部循环中检测到尺寸不匹配。
维度的顺序也是错误的(3 应用颜色通道数,应该是最后一个维度)。
entire_video 的类型也是错误的 - 类型是 float32 而不是 uint8。
假设entire_video 驻留在GPU 内存中,我们还必须在使用write_video 之前将张量复制到CPU 内存中。
在使用write_video之前,我们可能会应用以下阶段:
-
将视频从 GPU 内存复制到 CPU 内存(并删除冗余轴):
entire_video = entire_video[0].detach().cpu()
-
从 float32 转换为 uint8 应用偏移和缩放。
以下代码使用全局最小值和最大值(转换不是最佳的 - 用作示例):
min_val = entire_video.min()
max_val = entire_video.max()
entire_video_as_uint8 = ((entire_video - min_val) * 255/(max_val min_val)).to(torch.uint8)
-
将要排序的轴重新排序为 [T, H, W, C]:
-
第一个轴应用帧索引(当有 45 个视频帧时,形状值为 45)。
-
第二个轴应用行索引(当每帧有 256 行时,形状值为 256)。
-
第三轴应用列索引(当每帧有 128 列时,形状值为 128)。
-
第四轴应用颜色通道(形状值为 3,因为有 3 个颜色通道 - 红色、绿色和蓝色)。
vid_arr = torch.permute(entire_video_as_uint8, (1, 2, 3, 0))
完整的代码示例:
import torch
from phenaki_pytorch import CViViT, MaskGit, Phenaki
from phenaki_pytorch import make_video
import torchvision
maskgit = MaskGit(
num_tokens = 5000,
max_seq_len = 1024,
dim = 512,
dim_context = 768,
depth = 6,
)
cvivit = CViViT(
dim = 512,
codebook_size = 5000,
image_size = (256, 128), # video with rectangular screen allowed
patch_size = 32,
temporal_patch_size = 2,
spatial_depth = 4,
temporal_depth = 4,
dim_head = 64,
heads = 8
)
phenaki = Phenaki(
cvivit = cvivit,
maskgit = maskgit
).cuda()
entire_video, scenes = make_video(phenaki, texts = [
'blah blah'
], num_frames=(45, 14, 14), prime_lengths=(5, 5))
print(entire_video.shape) # (1, 3, 45, 256, 128)
# Copy the video from the GPU memory to CPU memory.
# Apply entire_video[0] for removing redundant axis.
entire_video = entire_video[0].detach().cpu() # https://stackoverflow.com/a/66754525/4926757
# Convert from float32 to uint8, use global minimum and global maximum - this is not the best solution
min_val = entire_video.min()
max_val = entire_video.max()
entire_video_as_uint8 = ((entire_video - min_val) * 255/(max_val-min_val)).to(torch.uint8)
# https://pytorch.org/vision/stable/generated/torchvision.io.write_video.html
# video_array - (Tensor[T, H, W, C]) – tensor containing the individual frames, as a uint8 tensor in [T, H, W, C] format
# https://pytorch.org/docs/stable/generated/torch.permute.html
vid_arr = torch.permute(entire_video_as_uint8, (1, 2, 3, 0)) # Reorder the axes to be ordered as [T, H, W, C]
print(vid_arr.shape) # (45, 3, 256, 128)
torchvision.io.write_video(filename="test.mp4", video_array=vid_arr, fps=24)
毕竟,创建的视频文件看起来像随机噪音......
看起来这是make_video 的输出,与帖子主题无关。