引言
OpenCV 下写视频,只需要使用 cv::VideoWriter
类,代码非常简单。很可惜的是,无论是使用安装包预编译好的静态库和动态库,还是使用 CMake 在本地重新配置生成新的静态库和动态库,都无法写出用 h.264 格式编码的视频。我们运行这个简单的程序:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
int main()
{
const char* videoIn = "old.avi";
const char* videoOut = "new.avi";
cv::VideoCapture vin(videoIn);
cv::VideoWriter vout(videoOut, CV_FOURCC('X','2','6','4'), vin.get(CV_CAP_PROP_FPS),
cv::Size(vin.get(CV_CAP_PROP_FRAME_WIDTH), vin.get(CV_CAP_PROP_FRAME_HEIGHT)));
for (int i = 0; i < 1000; i++)
{
cv::Mat frame;
vin.read(frame);
vout.write(frame);
}
vout.release();
return 0;
}
得到的结果是:
Could not find encoder for codec id 28: Encoder not found请按任意键继续. . .
为了使 OpenCV 支持写 h.264 格式的视频,需要编译支持 x264 的 ffmpeg,其中 x264 是能够进行 h.264 格式视频编码的开源库,ffmpeg 是视频编解码的通用框架。本文将 windows 操作系统下 32 位程序的操作方法进行说明,64 位下的操作还未尝试。使用的 OpenCV 版本是 2.4.5,更新版本的 OpenCV 的操作方法类似。
OpenCV 和 ffmpeg
在进行操作之前,先来简述一下 OpenCV 是如何支持视频的读写的。OpenCV2.0 版本之后采用了新式的接口 cv::VideoCapture
和 cv::VideoWriter
分别进行视频读写操作,这两个类实际上是对 OpenCV1.0 版本 C 接口的 CvCapture
和 CvVideoWriter
进行的封装,而 CvCapture
和 CvVideoWriter
底层是使用 ffmpeg 提供的接口进行视频读写的操作的。所以,从本质上说,OpenCV 提供的是 ffmpeg 接口高层的抽象的易用的的封装,隐藏了 ffmpeg 繁杂的调用细节,让 OpenCV 的使用者专注于视觉方面算法的工作。
一般情况下,我们使用的是 OpenCV 的动态库,解压 opencv2.4.5 的官方安装文件到 D:/OpenCV2.4.5,在 D:/OpenCV2.4.5/build/x86/vc10/bin 路径下,给出了适用于 visual studio 2010 的 32 位的 OpenCV 的动态库。这些库有 opencv_core245.dll,opencv_imgproc245.dll 等。这些库都放在一起,我们还通常把这些动态库的路径写入系统环境变量 Path 中。这些动态库中,有一个 opencv_ffmpeg245.dll,这个动态库封装了视频读写中需要的 ffmpeg 的功能。注意到这个动态库是没有对应的 lib 文件的,我们在写 OpenCV 程序的时候从来不需要在 Project->Properties->Configuration Properties->Linker->Input->Additional Dependencies 中添加 opencv_ffmpeg245.lib。opencv_ffmpeg245.dll 的加载是动态加载。如果我们的程序需要进行视频读写,那么我们的程序在链接的时候需要使用 opencv_highgui245.lib。程序执行的时候,会加载相应的 opencv_highgui245.dll,一旦发生视频读写操作,opencv_highgui245.dll 中的内部会打开这个 dll 所在路径下的 opencv_ffmpeg245.dll,找到所需函数的入口地址,调用相关函数,完成视频读写操作。如果opencv_highgui245.dll 所在路径下不存在 opencv_ffmpeg245.dll,将无法读写视频。
修改 opencv_ffmepg.dll 的步骤
通过上述简介我们知道,为了让 OpenCV 支持写 h.264 格式的视频,最关键的步骤就是重新生成 opencv_ffmpeg245.dll。进入 D:/OpenCV2.4.5/3rdparty/ffmpeg(新版本如 2.4.10 的路径是 D:/OpenCV2.4.10/sources/3rdparty/ffmpeg)文件夹,里面有个 readme.txt 说明了重新生成 opencv_ffmpeg.dll 的操作方法。过程简述如下:
第一,安装 MinGW;
第二,使用 msys 终端编译 ffmpeg,得到 *.a 静态库;
第三,修改 D:/OpenCV2.4.5/3rdparty/ffmpeg/make.bat 文件,使用 msys 终端编译出 opencv_ffmpeg.dll。
默认情况下,ffmpeg 是不支持编码 h.264 格式视频的,如果我们要让 ffmpeg 支持,简要步骤改成:
第一,安装 MinGW;
第二,使用 msys 终端编译 x264,得到 *.a 静态库;
第三,使用 msys 终端编译支持 x264 的 ffmpeg,得到 *.a 静态库;
第四,修改 D:/OpenCV2.4.5/3rdparty/ffmpeg/make.bat 文件,使用 msys 终端编译出opencv_ffmpeg.dll。
下面将详细说明这四个操作步骤。
安装 MinGW
在 http://sourceforge.net/projects/mingw/files/ 下载 mingw-get-setup.exe。
运行这个 exe 安装 MinGW,安装基本的库、可执行文件,最主要是 C 和 C++ 的编译器。安装过程很简单,可参考 http://tieba.baidu.com/p/2826016538。记住要把 MinGW 路径下的 bin 文件夹的全路径加入系统环境变量 Path 中。
我的安装路径是 D:/MinGW,所以要在 Path 中添加 D:\MinGW\bin。要使用 M