Python-Opencv 在内存缓冲区上写入 x264 视频

Posted

技术标签:

【中文标题】Python-Opencv 在内存缓冲区上写入 x264 视频【英文标题】:Python-Opencv Write x264 video on memory buffer 【发布时间】:2016-11-07 17:29:07 【问题描述】:

我在内存缓冲区上写入 x264 视频(或单帧)时遇到问题。在用于图像的 opencv 中,imencode 和 imdecode 执行此任务。但我想保存 x264 视频帧以降低内存使用率并在互联网上发送。我可以使用 jpeg,但 jpeg 大小比 x264 视频帧大,质量更差。我进行了搜索,但找不到如何在缓冲区上写入视频帧。

这是在网络摄像头上拍摄帧的示例代码

        import numpy as np
        import cv2


        cap = cv2.VideoCapture(0)
        cap.set(3,320)
        cap.set(4,240)
        cap.set(5,30)
        # Define the codec and create VideoWriter object
        fourcc = cv2.VideoWriter_fourcc(*'x264')
        out = cv2.VideoWriter('.....sample.avi',fourcc, 30.0, (320,240))

        while(cap.isOpened()):
            ret, frame = cap.read()
            if ret==True:
                cv2.imshow('frame',frame)
                out.write(frame) #I want to write memory not disk
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break
            else:
                break

        # Release everything if job is finished
        cap.release()
        out.release()
        cv2.destroyAllWindows()

【问题讨论】:

你能详细说明一下吗,因为我不知道你想要完成什么。您要创建包含图像帧的视频文件吗?或者是其他东西?无论哪种方式,我都不确定 x264 能否与 AVI 容器兼容,我会尝试 MKV 实际上我正在尝试使用 udp 或 tcp/ip 通过网络发送相机帧。我成功发送了jpg图像(一帧发送并发送下一帧)。但是我想发送 x264 压缩的 mkv 或 avi 视频(或顺序一帧)文件,因为 x264 压缩比 jpg 更有效。(我认为质量也更好)我可以在磁盘上写,但我想在内存上写(比如 numpy数组..)x264视频帧,因为我必须序列化(使用pickle或json)视频帧并通过套接字发送。我在网上搜索但我找不到我该怎么办?我觉得这个解释很清楚。这是我的问题。 我不确定这是否可行,因为 OpenCV 的 python 版本仅使用 numpy 作为矩阵,可以进行腌制、序列化等。对于视频流,OpenCV(C++ 和 Python)使用 FFMPEG (libav),您不能以相同的方式使用其对象。您要在流式传输之前修改内容吗? IE。您真的需要 OpenCV,还是可以使用另一个库直接流式传输内容? 我可能使用了另一个库。但由于互联网上传带宽,我必须流式传输 x264 编码帧(x264 上的内存使用量较少)。 我认为您现在正在用大炮射击鸟类 :) 查看 FFMPEG,这可能正是您正在寻找的工具。例如。 trac.ffmpeg.org/wiki/EncodingForStreamingSites。由于此解决方案与您的要求相去甚远,因此我不会将其作为答案发布,但 FFMPEG 是大多数视频相关的 首选解决方案,并且在 OpenCV、VLC 等内部也使用。它易于使用,命令行并且可以将您的内容(例如网络摄像头)直接流式传输到 twitch 或其他东西。现在我不知道你将要做什么,但如果它不能这样做,我会感到惊讶。 【参考方案1】:

很遗憾,没有办法处理 cv2.VideoWriter,因为您无法在 out.release() 之前访问编码的视频帧。

我为我的项目找到的方法是从 D:\your_directory\opencv\sources\modules\highgui\src 实现 cap_ffmpeg_impl.hpp 并将您捕获的帧发送到该库中。您将通过 UDP 或 TCP/IP 发送编码帧,并使用同一个库对它们到达的位置进行解码。还要记住,你需要编译正确的ffmpeg 版本才能使用它。

【讨论】:

如何将这些帧发送到库以及如何进行套接字发送? 你可以找到一个sample project,它使用 cap_ffmpeg_impl.hpp 通过 opencv 和 x264 视频编解码器进行视频流。

以上是关于Python-Opencv 在内存缓冲区上写入 x264 视频的主要内容,如果未能解决你的问题,请参考以下文章

使用缓冲区写入文件时c ++内存泄漏

python-opencv读取显示写入图像

python-opencv读取显示写入图像

在内存有限的系统上写入大文件时如何避免 mapFailed() 错误

直写与回写

“CRT 检测到应用程序在堆缓冲区结束后写入内存”是啥意思?