【问题标题】:writing a video without any loss in data or bitrate - opencv (python)编写视频而不会丢失数据或比特率 - opencv(python)
【发布时间】:2022-11-10 04:05:43
【问题描述】:

我正在尝试在 OpenCV 中编写一个没有任何损失的视频文件,但到目前为止,我从fourcc 编解码器列表中选择的任何编解码器都会以某种方式导致数据丢失。

关于我正在使用的记录参数:

fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

到目前为止使用了这些编解码器,但它们要么压缩要么提升视频比特率

fourcc = cv2.VideoWriter_fourcc(*'MP4V') 
fourcc = cv2.VideoWriter_fourcc(*'DIVX') 
fourcc = cv2.VideoWriter_fourcc(*'RGBA') 
fourcc = cv2.VideoWriter_fourcc(*'x265') 
fourcc = cv2.VideoWriter_fourcc('H','2','6','4')

我的视频编写器功能是:

writer= cv2.VideoWriter(out_dest, fourcc, fps, (width,height))

为了清楚起见,我不希望对输出视频进行任何形式的压缩。

我也用

vid_format = int(cap.get(cv2.CAP_PROP_FOURCC))

获取输出视频比特率并将其与原始视频进行比较。

我还在 GitHub 上发现有人使用 skvideo,但无法执行相同的代码

https://gist.github.com/docPhil99/a612c355cd31e69a0d3a6d2f87bfde8b

因为它一直显示扩展错误并且找不到有关如何使用它的正确文档!

先感谢您

关于该主题的更新:

最终的输出编写器编解码器将用作 OpenCV 中 BGR 到 RGB 转换的视频编写器,如果您有任何其他可以完成这项工作的想法或建议,我会全力以赴!

【问题讨论】:

  • 请参阅superuser.com/a/1429266/1669011 并将其转换为 OpenCV 调用。如果不支持,请使用 ffmpeg
  • 您打算录制的视频的来源是什么?您是打算录制已经编码的视频流(例如来自相机的视频),还是原始视频帧(存储在 NumPy 数组中)? “没有任何数据或比特率损失” - 分辨率是多少,比特率是多少?
  • @kesh 我尝试了 ffmpeg,但在此过程中丢失了 2/3 的比特率
  • @Rotem 源是本地加载的 .avi 视频(从网络摄像头录制)。最终目标是将视频格式从 BGR 转换为 RGB 以用于媒体管道。视频元数据如下: 格式:AVI 文件大小:220 MiB 持续时间:10 s 0 ms 总比特率:184 Mb/s 格式:RGB 持续时间:10 s 0 ms 比特率:184 Mb/s 宽度:640 像素高度:480 像素显示纵横比:4:3 帧速率:25.000 FPS 位深度:8 位位/(像素*帧):24.000 流大小:220 MiB (100%)
  • @kesh ffmpeg 结果:格式:MPEG-4 文件大小:37.8 MiB 持续时间:10 s 0 ms 总比特率:31.7 Mb/s 格式:AVC 格式设置,ReFrames:16 帧持续时间:10 s 0 ms 比特率:31.7 Mb /s 宽度:640 像素 高度:480 像素 显示纵横比:4:3 帧率模式:恒定帧率:25.000 FPS 位深度:8 位位/(像素*帧):4.126 流大小:37.8 MiB (100%)编写库:x264 core 164

标签: python opencv ffmpeg bitrate fourcc


【解决方案1】:

如果您需要做的只是从原始 AVI 文件中获取 RGB 数据并使用 MediaPipe 提供 RGB 帧数据,则不需要中间文件来存储 RGB 数据,因为 FFmpeg 可以通过指定输出@动态转换像素格式987654322@ 选项。

为此,您可以尝试我的ffmpegio package 来加载数据。我的包是为您的用例设计的,以消除设置 FFmpeg 调用的需要。安装:

pip install ffmpegio

您还需要系统中的 FFmpeg。

然后video.read() 加载视频数据:

import ffmpegio

fs, I = ffmpegio.video.read('datafile.avi',pix_fmt='rgb24')
# fs = framerate
# I = 250x480x640x3 numpy array containing RGB video data

如果您不想一次读取所有 250 帧,可以使用流接口一次处理 X 帧:

with ffmpegio.open('datafile.avi','rv', blocksize=25, pix_fmt='rgb24') as f:
    for I in f: # loops 10 times, 25 frames at a time
        # I = 25x480x640x3 numpy array

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 2015-08-11
    • 2011-07-22
    • 1970-01-01
    • 2017-05-17
    • 2012-01-30
    • 1970-01-01
    相关资源
    最近更新 更多