python - cv2 videowriter,写得很好,但在应用程序关闭时抛出错误

标签 python opencv ffmpeg mp4

这确实是一个小小的不便。应用程序按预期运行,但是当我关闭应用程序时 OpenCV仅在那时引发错误。
我正在获取一个包含数百帧的数据文件并将它们合并到一个视频文件中。这是我采取的步骤。

def createMovie(self):
    print("CREATE Movie")

    fileName = self.generateFilename()

    minV = self._data.min()
    maxV = self._data.max()

    nFrames = self._data.nframes
    width, height = self._data.frame().shape[0], self._data.frame().shape[1]
    fps = 16

    fourcc = cv2.VideoWriter_fourcc(*'MP44')
    out = cv2.VideoWriter(fileName, fourcc, float(fps), (width, height))

    for frame in range(nFrames):
        myImg = self._data.frame(frame)
        global_norm = np.true_divide((myImg - minV), (maxV - minV))
        norm = (global_norm * 255)
        intNorm = norm.astype(int)

        rotated = cv2.rotate(intNorm, cv2.cv2.ROTATE_90_COUNTERCLOCKWISE)
        flipped = cv2.flip(rotated, 0)
        temp = np.uint8(flipped)

        out.write(temp)
        
    out.release()
如您所见,我将帧数据标准化为与帧相关的全局最小值/最大值的一部分。我正在将视频文件写为 mp4,所以我可以使用 MP44MP42 fourcc编解码器。
在离开该功能之前,我确保释放视频作者。我已经验证发生在 isopen()称呼。
所有帧都毫无问题地写入视频文件。播放正常,不会抛出任何错误,直到!
直到我关闭应用程序。我正在使用 pyqt5开发 GUI。当我单击关闭按钮时,我收到此错误。

OpenCV: FFMPEG: tag 0x3434504d/'MP44' is not found (format 'mp4 / MP4 (MPEG-4 Part 14)')'


或者

OpenCV: FFMPEG: tag 0x3234504d/'MP42' is not supported with codec id 15 and format 'mp4 / MP4 (MPEG-4 Part 14)' [mp4 @ 000002e39f4769c0] Could not find tag for codec msmpeg4v2 in stream #0, codec not currently supported in container


我尝试过任何数量的其他编解码器,但 MP44MP42是唯一允许我写 mp4 的人。是的,我需要将文件写为 mp4。其他选项创建了一个可行的文件,但在运行时抛出了错误,未能写入可行的文件但没有抛出错误,或者无法写入文件并抛出了错误。
尝试的编解码器:mp4v、avc1、avc3、hev1、hvc1、mp44、mp42
我可以忍受这个错误,我只想了解正在发生的事情并清理代码。 OpenCV 没有其他用途应用程序中的其他任何地方。所以我很好奇为什么当我关闭应用程序时它只会在最后抛出错误。

最佳答案

阅读其文档,opencv 在其站点包文件夹 (OPENCV_SOURCE_CODE/3rdparty/ffmpeg/) 中安装 FFmpeg 二进制文件。您的应用程序中可能发生的情况是,包含的 FFmpeg 构建没有附带您想要使用的这 2 个编解码器,并且以某种方式退回到可用的兼容编解码器(可能是“h264”),并将 FFmpeg 错误消息保存到非常结尾。因此,请尝试“h264”或@Christoph Rackwitz 的“avcl”建议,看看错误是否消失。
(无耻的插头)如果你想用我的 ffmpegio库,您可以尝试以下操作(在将 FFmpeg 正确安装到您的系统后):

import ffmpegio

def createMovie(self):
    print("CREATE Movie")

    fileName = self.generateFilename() # assume it ends with '.mp4'

    minV = self._data.min()
    maxV = self._data.max()

    nFrames = self._data.nframes
    fps = 16

    with ffmpegio.open(fileName, 'wv', rate=fps, vf='vflip,hflip,transpose') as out:

        for frame in range(nFrames):
            myImg = self._data.frame(frame)
            norm = np.true_divide((myImg - minV), (maxV - minV))
            out.write(norm.astype('f4')) # float32 grayscale image
我相信vflip - hflip - transpose组合做你打算做的,但请仔细检查。
FFmpeg 有 pix_fmt='grayf32le' 这是一个浮点灰度,像素值定义在 0.0 和 1.0 之间。
您可以添加show_log=Trueopen命令查看 FFmpeg 日志(ffmpegio 的错误处理现在非常糟糕)。
另外,您可以添加 overwrite=True让 FFmpeg 覆盖之前的运行(或等效地 y=None 直接设置 FFmpeg 标志)。
这个库还很年轻,需要测试。如果您遇到任何错误,请报告 GitHub 问题。

关于python - cv2 videowriter,写得很好,但在应用程序关闭时抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70849018/

相关文章:

python - 从 Numpy Ndarray 构建字典和列表

c++ - 为什么我的 .exe 文件崩溃,但在调试和发布版本中工作正常?

php - 由于使用 PHP 进行 FFMPEG 转换,Jquery 上传文件出错

image - 是否可以通过从 B 或 P 帧重构 I 帧来撤销时间压缩?

ffmpeg - 使用 ffmpeg 加入多个 flv

python - Django - 根据用户组显示/隐藏基本 html 中的 url?

python - 如何以多线程方式将 Python Dict 转换为 JSON

Python字符串比较最小/最大str

opencv - 在OpenCV中读取YAML文件

javascript - 使用 tracking.js 进行人脸识别