- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
视频写入器类。
该类提供了用于写入视频文件或图像序列的 C++ API。
cv::VideoWriter 类是 OpenCV 库中用于创建和写入视频文件的一个类。它提供了用于设置视频编码器、帧率、文件路径等参数的方法,并允许用户将图像帧序列写入到视频文件中。
构造函数原型1
默认构造函数。
这些构造函数/函数初始化视频写入器。
- 在 Linux 上使用 FFMPEG 来写入视频;
- 在 Windows 上使用 FFMPEG 或 MSWF 或 DSHOW;
- 在 MacOSX 上使用 AVFoundation。
cpp
cv::VideoWriter::VideoWriter()
构造函数原型2
这是一个重载的成员函数,提供方便之用。它与上述函数的区别仅在于所接受的参数不同。
cpp
cv::VideoWriter::VideoWriter
(
const String & filename,
int fourcc,
double fps,
Size frameSize,
bool isColor = true
)
参数2
- 参数filename 输出视频文件的名称。
- 参数fourcc 用于压缩帧的编解码器的4字符代码。例如,VideoWriter::fourcc('P', 'I', 'M', '1') 是一个 MPEG-1 编码器,VideoWriter::fourcc('M', 'J', 'P', 'G') 是一个运动 JPEG 编码器等。代码列表可以在 MSDN 页面或 fourcc 站点的这个页面上获得,以获取更完整的列表。FFMPEG 后端与 MP4 容器原生使用其他值作为 fourcc 代码:参见 ObjectType,因此您可能会收到 OpenCV 关于 fourcc 代码转换的警告消息。
- 参数fps 创建的视频流的帧率。
- 参数frameSize 视频帧的大小。
- 参数isColor 如果不为零,编码器将期望并编码彩色帧,否则将处理灰度帧。
提示:
在某些后端中,fourcc = -1 会弹出系统中的编解码器选择对话框。
要保存图像序列,请使用适当的文件名(例如 img_%02d.jpg)并设置 fourcc = 0 或者 fps = 0。使用无压缩的图像格式(例如 img_%02d.BMP)来保存原始帧。
大多数编解码器都是有损的。如果你想创建无损视频文件,你需要使用无损编解码器(例如 FFMPEG FFV1、Huffman HFYU、Lagarith LAGS 等)。
如果启用了 FFMPEG,使用 codec = 0;fps = 0;你可以创建一个无压缩(原始)视频文件。
如果使用 FFMPEG,我们允许奇数宽度或高度的帧,但在这种情况下我们会截断最右侧的一列/最底部的一行。可能这应该处理得更优雅一些,但 FFMPEG swscale 中的一些内部函数需要偶数宽度/高度。
构造函数原型3
这是一个重载的成员函数,提供方便之用。它与上述函数的不同之处仅在于所接受的参数。apiPreference 参数允许指定要使用的 API 后端。如果存在多个可用的读取器实现,可以用来强制使用某个特定的实现:例如 cv::CAP_FFMPEG 或 cv::CAP_GSTREAMER。
cpp
cv::VideoWriter::VideoWriter
(
const String & filename,
int apiPreference,
int fourcc,
double fps,
Size frameSize,
bool isColor = true
)
参数3
- 参数filename:输出视频文件的名称。
- 参数apiPreference:指定要使用的 API 后端。如果存在多个可用的后端,可以用来强制使用某个特定的实现。例如 cv::CAP_FFMPEG 或 cv::CAP_GSTREAMER。
- 参数fourcc:用于压缩帧的编解码器的4字符代码。例如,VideoWriter::fourcc('X', 'V', 'I', 'D') 表示 XVID 编码器。
- 参数fps:创建的视频流的帧率(每秒帧数)。
- 参数frameSize:视频帧的大小(宽度和高度)。
- 参数isColor:如果为 true,则编码器将期望并编码彩色帧;如果为 false,则编码器将处理灰度帧。默认值为 true。
构造函数原型4
这是一个重载的成员函数,提供方便之用。它与上述函数的不同之处仅在于所接受的参数。params 参数允许指定额外的编码器参数,这些参数是以成对的形式编码的(paramId_1, paramValue_1, paramId_2, paramValue_2, ...)。参见 cv::VideoWriterProperties。
cpp
cv::VideoWriter::VideoWriter
(
const String & filename,
int fourcc,
double fps,
const Size & frameSize,
const std::vector< int > & params
)
参数4
- 参数filename:输出视频文件的名称。
- 参数fourcc:用于压缩帧的编解码器的4字符代码。例如,VideoWriter::fourcc('X', 'V', 'I', 'D') 表示 XVID 编码器。
- 参数fps:创建的视频流的帧率(每秒帧数)。
- 参数frameSize:视频帧的大小(宽度和高度)。
- 参数params:额外的编码器参数,存储在一个 std::vector 中。这些参数可以根据具体的编解码器进行配置。
构造函数5
这是一个重载的成员函数,提供方便之用。它与上述函数的不同之处仅在于所接受的参数。
cpp
cv::VideoWriter::VideoWriter
(
const String & filename,
int apiPreference,
int fourcc,
double fps,
const Size & frameSize,
const std::vector< int > & params
)
参数5
- 参数filename:输出视频文件的名称。
- 参数apiPreference:指定要使用的 API 后端。如果存在多个可用的后端,可以用来强制使用某个特定的实现。例如 cv::CAP_FFMPEG 或 cv::CAP_GSTREAMER。
- 参数fourcc:用于压缩帧的编解码器的4字符代码。例如,VideoWriter::fourcc('X', 'V', 'I', 'D') 表示 XVID 编码器。
- 参数fps:创建的视频流的帧率(每秒帧数)。
- 参数frameSize:视频帧的大小(宽度和高度)。
- 参数params:额外的编码器参数,存储在一个 std::vector 中。这些参数可以根据具体的编解码器进行配置
代码示例
cpp
#include <opencv2/opencv.hpp>
#include <iostream>
int main()
{
// 创建 VideoCapture 对象来捕获视频帧
cv::VideoCapture cap( 0 ); // 使用默认摄像头
// 检查摄像头是否成功打开
if ( !cap.isOpened() )
{
std::cerr << "Failed to open the camera." << std::endl;
return -1;
}
// 根据操作系统选择视频编码器的 FourCC 代码
int fourcc;
#if defined( _WIN32 ) || defined( _WIN64 )
// Windows 平台
fourcc = cv::VideoWriter::fourcc( 'M', 'S', 'W', 'F' ); // 使用 MSWF 编码器
#elif defined( __APPLE__ )
// macOS 平台
fourcc = cv::VideoWriter::fourcc( 'a', 'v', 'c', '1' ); // 使用 avc1 (H.264) 编码器
#else
// Linux 或其他 Unix-like 系统
fourcc = cv::VideoWriter::fourcc( 'X', '2', '6', '4' ); // 使用 X264 编码器
#endif
// 创建 VideoWriter 对象
cv::VideoWriter writer;
// 打开视频文件用于写入
bool success = writer.open( "output.mp4", // 输出视频文件名
fourcc, // 视频编码器的 FourCC 代码
25, // 帧率(每秒帧数)
cv::Size( cap.get( cv::CAP_PROP_FRAME_WIDTH ), cap.get( cv::CAP_PROP_FRAME_HEIGHT ) ), // 帧大小
true // 是否为彩色视频
);
if ( !success )
{
std::cerr << "Failed to initialize the video writer." << std::endl;
return -1;
}
// 捕获并写入视频帧
cv::Mat frame;
while ( true )
{
// 从摄像头读取一帧
if ( !cap.read( frame ) )
{
std::cout << "No frame grabbed." << std::endl;
break;
}
// 写入帧到视频文件
writer.write( frame );
// 显示当前帧
cv::imshow( "Live Camera", frame );
// 按 'q' 键退出循环
if ( cv::waitKey( 1 ) == 'q' )
{
break;
}
}
// 释放资源
cap.release();
writer.release();
cv::destroyAllWindows();
return 0;
}