OpenCV编译安装时与FFmpeg相关的坑

这学期的课需要部署OpenCV环境,于是我尝试在我的服务器上部署OpenCV环境,我愿意用坑爹来形容安装过程。在本文中我会记录两个与FFmpeg依赖相关的坑,以供后来参考。

编译脚本找不到FFmpeg

出于两个原因,我选择使用编译安装的方式安装FFmpeg:

  1. 我用的是RHEL系的系统,官方源里面并没有FFmpeg,第三方源又死活导入不了。
  2. 我不喜欢把所有东西都往/usr/bin和/usr/lib里塞,这样会乱作一团,我更喜欢将每个软件分开安装到各自的目录下

FFmpeg是成功安装好了(安装目录/usr/local/ffmpeg),可是运行OpenCV的cmake脚本的时候死活检测不到FFmpeg这项依赖。尝试改变安装目录无果,我在查阅了一定资料后发现OpenCV是根据pkgconfig来查找ffmpeg的,也就是说需要把ffmpeg的pkgconfig文件导入到默认的pkgconfig搜寻目录下,由于我不喜欢在系统里放很多冗余的文件,所以我采用的是软链接的方式:

首先获取当前系统的默认PKG_CONFIG_PATH

1
echo $PKG_CONFIG_PATH

我的系统下为:/usr/local/lib/pkgconfig,此外,ffmpeg的安装路径为/usr/local/ffmpeg,于是用如下指令创建软链接:

1
sudo ln -s /usr/local/ffmpeg/lib/pkgconfig/* /usr/local/lib/pkgconfig

检测成功。

编译opencv_dnn的时候显示失败

查看了终端输出之后,我发现是因为gcc编译失败导致的,根据编译器报错信息,发现是一处宏定义用了未定义的符号,而实际上这些未定义符号是老版本的FFmpeg定义的宏,这个宏定义是试图将老版本的宏定义转化为新版本的宏定义。但是我明明安装的是新版本,这里本该被编译条件舍弃掉,不知道由于什么原因并没有舍弃掉,于是产生了未定义符号的错误。找到了原因之后,出于懒狗本质,我没有细究检测版本的宏到底是在哪里定义的,而是选择直接把宏条件设定为False,手动舍弃这段代码:

1
2
3
4
5
6
7
//这段代码位于:[源码根目录]/modules/videoio/src/ffmpeg_codecs.hpp
//找到这一行
#if (LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(54, 51, 100))
//修改成:
#define FUCK_YOU 0
#define YOU_FUCK 1
#if (FUCK_YOU == YOU_FUCK)

改好之后记得先make clean再重新从头make。

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器