在CentOS系统上安装OpenCV-3

前几天在一台CentOS系统上安装带解码功能的OpenCV,过程略曲折,特此记录安装过程中遇到的一些问题和解决方法,以备后续查阅。

一. 安装必要的依赖库

因为需要使用OpenCV的解码功能,需要安装FFMPEG,FFMPEG安装过程见我之前的一篇博文:

安装带X264的ffmpeg

但是跟之前有些不一样的地方,就是需要打开libdc1394,因此在FFMPEG配置中需要加入 --enable-libdc1394。

但是在安装FFMPEG之前,需要提前安装libdc1394,我使用的源码安装,源码下载地址:

libdc1394源码下载地址

下载完成并解压后,进入libdc1394目录,./configure、make、make install即可。

libdc1394是一个为应用程序开发人员提供高级编程接口的库,它可以控制和捕获来自基于IEEE 1394摄像头的流,这些摄像头符合基于1394的数码相机规范(也称为IIDC或DCAM规范)。libdc1394还支持一些符合IIDC的USB摄像头。

libdc1394提供的功能包括:相机控制、视频采集、支持多摄像头/多适配器、支持多平台(Linux / OSX / Windows)、兼容IIDC 1.31、颜色空间转换函数、多重去贝叶斯算法等。

安装好libdc后,即可正常安装FFMPEG了。

二. 安装OpenCV

最开始希望安装OpenCV-2.4.9,也是我们在工程中常用的一个版本,但是该版本在视频编码格式上与FFMPEG-4.0并不兼容(FFMPEG-4.0先入为主),因此重新下载了OpenCV-3.4.3的源码来安装,下载地址:

OpenCV源码地址

下载完成并解压缩后,即可配置编译选项了。首先,在opencv-3.4.3目录下建立一个新的目录用于存放编译产生的文件:

1. mkdir build

由于我们要使用FFMPEG进行解码,因此需要打开FFMPEG,设置cmake -D WITH_FFMPEG=ON。另外,如果系统编译器版本较低,可能不支持C++11,会出现配置失败的问题,因此,需要在配置时使能C++11:cmake -D ENABLE_CXX11=1。这样,最终的配置命令行如下:

2. cmake -D ENABLE_CXX11=1 -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_FFMPEG=ON  ..

当然,以上是比较简单的设置,根据不同的需要,可以加入不同的参数。

以上命令行执行完成后,在执行结果中发现FFMPEG库后面都是OFF(或NO)的状态,也就是说opencv配置ffmpeg库未生效,这是怎么回事呢?经过分析并在网上查找解决方案,发现虽然系统中已经安装了FFMPEG,在OpenCV配置中也打开了FFMPEG选项,但是OpenCV并没有找到FFMPEG库的位置。查看OpenCV CMakeList.txt,可以看到对FFMPEG系列库状态的判断如下:

我们知道,在编译中如果不明确指定依赖库的头文件和库路径,就需要使用pkg-config来获取依赖库的信息。一般来讲,系统会默认在/usr/lib/pkgconfig,或者/usr/share/pkgconfig,或者环境变量PKG_CONFIG_PATH指定的目录下查找*.pc文件来确定依赖库的信息,但我们在安装FFMPEG时,是默认安装到了/usr/local/lib目录下,对应的pkgconfig也在这个目录下,但/usr/local/lib/pkgconfig并不在系统查找的范围之内,因此我们需要把该路径放在PKG_CONFIG_PATH中。具体操作方法:

vim /etc/profile

在文件末尾添加如下语句:

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH

保存并退出文件后,执行如下语句使之生效:

source /etc/profile

以上操作完成后,再次运行OpenCV的配置命令(见编号为2的命令行),配置通过。

之后依次运行make、make install完成编译和安装。

3. make
4. make install

三. 测试

OpenCV安装完成后,我们来测试一下是否能够正常使用,主要是解码功能。写了一个简单的测试程序,测试从RTSP码流解码的功能:

#include <stdio.h>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int argc, char **argv)
{
        Mat frame;
		int64_t frame_num = 0;

        VideoCapture capture;               

        capture.open("rtsp://admin:[email protected]:554/h264/ch1/main/av_stream");

        if(!capture.isOpened())
        {
                printf("Open VideoCapture failed\n");
                return -1;
        }

        printf("Open VideoCapture success! \n");
 
        while(1)
        {
                capture.read(frame);

                printf("frame col = %d, row = %d, frame number = %ld  \n", frame.cols,
                         frame.rows, frame_num++);
        }

        return 0;
}

编译运行,解码24小时未出现异常。

发布了57 篇原创文章 · 获赞 58 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/DeliaPu/article/details/89551462