繁体   English   中英

在 OpenCV 中使用 H.264 压缩写入视频文件

[英]Writing a video file using H.264 compression in OpenCV

如何在OpenCV中使用VideoWriter class编写使用H.264压缩的视频? 我基本上想从网络摄像头获取视频并在按下一个字符后保存它。 使用 MPEG4 Part 2 压缩时输出的视频文件很大。

您当然可以使用VideoWriter类,但是您需要使用代表 H264 标准的正确 FourCC 代码 FourCC 代表四字符代码,它是媒体文件中使用的视频编解码器、压缩格式、颜色或像素格式的标识符。

具体来说,当您创建VideoWriter对象时,您在构造它时指定 FourCC 代码。 有关更多详细信息,请参阅 OpenCV 文档: http : //docs.opencv.org/trunk/modules/highgui/doc/reading_and_writing_images_and_video.html#videowriter-videowriter

我假设您使用的是 C++,因此VideoWriter构造函数的定义是:

VideoWriter::VideoWriter(const String& filename, int fourcc, 
                         double fps, Size frameSize, bool isColor=true)

filename是视频文件的输出, fourcc是您希望使用的代码的 FourCC 代码, fps是所需的帧速率, frameSize是所需的视频尺寸, isColor指定您是否想要视频颜色。 尽管 FourCC 使用四个字符,OpenCV 有一个实用程序可以解析 FourCC 并输出单个整数 ID,该 ID 用作查找以便能够将正确的视频格式写入文件。 您使用CV_FOURCC函数,并指定四个单个字符 - 每个字符对应于所需编解码器的 FourCC 代码中的单个字符。 请注意, CV_FOURCC适用于 OpenCV 2.x。 对于 OpenCV 3.x 及更高版本,建议您使用cv::Videowriter::fourcc

具体来说,你会这样称呼它:

int fourcc = CV_FOURCC('X', 'X', 'X', 'X');
int fourcc = VideoWriter::fourcc('X', 'X', 'X', 'X');

用属于 FourCC 的每个字符替换X (按顺序)。 因为您需要 H264 标准,所以您将创建一个VideoWriter对象,如下所示:

#include <iostream> // for standard I/O
#include <string>   // for strings

#include <opencv2/core/core.hpp>        // Basic OpenCV structures (cv::Mat)
#include <opencv2/highgui/highgui.hpp>  // Video write

using namespace std;
using namespace cv;

int main()
{
    VideoWriter outputVideo; // For writing the video

    int width = ...; // Declare width here
    int height = ...; // Declare height here
    Size S = Size(width, height); // Declare Size structure

    // Open up the video for writing
    const string filename = ...; // Declare name of file here

    // Declare FourCC code - OpenCV 2.x
    // int fourcc = CV_FOURCC('H','2','6','4');
    // Declare FourCC code - OpenCV 3.x and beyond
    int fourcc = VideoWriter::fourcc('H','2','6','4');

    // Declare FPS here
    double fps = ...;
    outputVideo.open(filename, fourcc, fps, S);

    // Put your processing code here
    // ...

    // Logic to write frames here... see below for more details
    // ...

    return 0;
}

或者,您可以在声明VideoWriter对象时简单地执行此VideoWriter

VideoWriter outputVideo(filename, fourcc, fps, S);

如果您使用上述方法,则不需要调用open因为这将自动打开编写器以将帧写入文件。


如果您不确定您的计算机是否支持 H.264,请将-1指定为 FourCC 代码,当您运行该代码时,应该会弹出一个窗口,该窗口显示您计算机上的所有可用视频编解码器。 我想提一下,这仅适用于 Windows。 当您指定-1时,Linux 或 Mac OS 不会弹出此窗口。 换句话说:

VideoWriter outputVideo(filename, -1, fps, S);

如果您的计算机上不存在 H.264,您可以选择最合适的一种。 完成后,OpenCV 将创建正确的 FourCC 代码以输入到VideoWriter构造函数中,以便您将获得一个 VideoWriter 实例,该实例表示将将该类型的视频写入文件的VideoWriter

准备好框架并存储在frm以写入文件后,您可以执行以下任一操作:

outputVideo << frm; 

或者

outputVideo.write(frm);

作为奖励,这里有一个关于如何在 OpenCV 中读/写视频的教程: http : //docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_video_display/py_video_display.html - 但是,它是为 Python 编写的,但值得一提的是在链接底部附近,有一个已知适用于每个操作系统的 FourCC 代码列表。 顺便说一句,他们为 H264 标准指定的 FourCC 代码实际上是'X','2','6','4' ,所以如果'H','2','6','4'不起作用, 用X替换H

另一个小笔记。 如果您使用的是 Mac OS,那么您需要使用的是'A','V','C','1''M','P','4','V' 根据经验,尝试指定 FourCC 代码时, 'H','2','6','4''X','2','6','4'似乎不起作用。

对于 H.264,大多数人使用 AVC,所以

cv2.VideoWriter_fourcc('a','v','c','1')

mp4v似乎也适用于许多人。

我有点晚了,但是我强大的VidGear Python 库的WriteGear API可以硬件编码器支持下实时自动将 OpenCV 帧流水线化为 FFmpeg 的过程,同时提供相同的 opencv-python 语法 这是一个使用它编码 H.264 视频的基本 Python 示例:

# import libraries
from vidgear.gears import WriteGear
import cv2

output_params = {"-vcodec":"libx264", "-crf": 0, "-preset": "fast"} #define (Codec,CRF,preset) FFmpeg tweak parameters for writer

stream = cv2.VideoCapture(0) #Open live webcam video stream on first index(i.e. 0) device

writer = WriteGear(output_filename = 'Output.mp4', compression_mode = True, logging = True, **output_params) #Define writer with output filename 'Output.mp4' 

# infinite loop
while True:
    
    (grabbed, frame) = stream.read()
    # read frames

    # check if frame empty
    if not is grabbed:
        #if True break the infinite loop
        break
    

    # {do something with frame here}
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # write a modified frame to writer
    writer.write(gray) 
       
    # Show output window
    cv2.imshow("Output Frame", frame)

    key = cv2.waitKey(1) & 0xFF
    # check for 'q' key-press
    if key == ord("q"):
        #if 'q' key-pressed break out
        break

cv2.destroyAllWindows()
# close output window

stream.release()
# safely close video stream
writer.close()
# safely close writer

来源: https : //abhitronix.github.io/vidgear/latest/gears/writegear/compression/usage/#using-compression-mode-with-opencv

您可以查看VidGear Docs以获取更高级的应用程序和功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM