我正在尝试从灰度帧创建视频,但视频仅显示一种颜色(绿色)。帧是 numpy 数组
import av
import numpy as np
output = av.open("myvideo.mp4", 'w')
ovstream = output.add_stream('h264')
ovstream.width = 514
ovstream.height = 616
for frame in frames:
packet = av.packet.Packet(frame.data)
packet.stream = ovstream
output.mux(packet)
output.close()
试图强制 流到灰色不会做任何事情。
ovstream.codec_context.pix_fmt = 'gray'
有可能强制流进入灰色模式(在混合之前),但我想避免这种情况,因为它增加了计算的复杂性。有了这个,视频就会以正确的颜色显示。
ovstream.encode(av.VideoFrame.from_ndarray(frame.data, format="gray"))
有什么方法可以让我获得正确的颜色,而不必重新编码为灰色?
如果您有任何提示,谢谢。
问题在于正在尝试将原始帧数据打包到没有足够元数据的
av.packet.Packet
中。PyAV 无法推断出颜色格式,并且很可能默认采用了错误的格式(在本例中,可能是某种将绿色通道解释为亮度的格式)。
无需进行灰色编码,也不必手动创建
av.packet.Packet
。PyAV 已经提供了处理这种情况的功能。
以下是修复后的代码:
import av
import numpy as np
frames = [np.random.randint(0, 256, (616, 514), dtype=np.uint8) for _ in range(100)] # 示例灰度帧
output = av.open("myvideo.mp4", 'w')
ovstream = output.add_stream('h264')
ovstream.width = 514
ovstream.height = 616
# 显式设置像素格式为灰度
ovstream.pix_fmt = 'gray'
for frame_data in frames:
# 从 numpy 数组创建 av.VideoFrame,指定格式为 gray
frame = av.VideoFrame.from_ndarray(frame_data, format='gray')
# 编码并混合帧
for packet in ovstream.encode(frame):
output.mux(packet)
# 刷新编码器
for packet in ovstream.encode():
output.mux(packet)
output.close()
解释:
-
设置像素格式: 我们在创建流时显式设置
ovstream.pix_fmt = 'gray'
,以便 PyAV 知道如何正确处理帧数据。 -
使用
av.VideoFrame.from_ndarray
: 我们使用此函数从 NumPy 数组创建av.VideoFrame
,并传递format='gray'
参数以确保正确解释数据。 -
使用
ovstream.encode
: 我们将av.VideoFrame
传递给encode
方法,该方法处理编码并将结果打包成av.packet.Packet
,然后将其传递给output.mux
进行混合。
通过这些更改,的视频现在应该以正确的灰度显示,而无需进行不必要的重新编码。
标签:python,video,video-streaming,pixelformat,pyav From: 78811882