
第 26 篇 | LINSHIYI
原本这应该是OpenCV配置攻略的第三篇,主要介绍Ubuntu系统下配置各版本OpenCV的步骤。由于这篇文非常长,所以我打算把它拆成7-8篇分别来发,每篇会有一个主题,字数在2000-5000之间。下图是我为这篇长文做的目录,圆圈表示每篇文章的主题,流程图是OpenCV的具体安装步骤。本文是第一篇:以OpenCV3.4.10为例,介绍安装前的“准备工作”,包括安装需要的包、下载源代码并解压缩和创建构建目录三部分。本文所述的方法适用于Ubuntu18.04和Ubuntu16.04,并以OpenCV3.4.10、4.5.3和2.4.10为例,编译步骤中不包括CUDA的配置,望读者提前知悉。OpenCV系列文的前两篇在这里,可以当作背景知识来阅读:
OpenCV配置攻略(一):OpenCV, VC++和VS
OpenCV配置攻略(二): 安装包里都有什么(上) 推荐2.4节(3)-(4)中CMake和make的部分
OpenCV配置攻略(二): 安装包里都有什么(下) 推荐3.3节(3)-(6)中静态库和动态库的部分

安装需要的包
第一步:安装编译所需的包和算法所需的包
命令执行位置:无要求
命令行:
(必须)$ sudo apt-get install build-essential
(必须)$ sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
(可选)$ sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
注意:
1. 可能出现"无法定位libjasper-dev包"的问题
复制
第一步先来安装一些包,官方教程中列出了安装OpenCV之前需要安装的包以及相应的命令语句(https://docs.opencv.org/3.4.10/d7/d9f/tutorial_linux_install.html):下面介绍一下这些命令的含义,由于三条命令都是sudo apt-get install <package name>的格式,所以1.1和1.2会先介绍sudo和apt-get install,1.3-1.5再介绍各个包的具体内容。在Linux/Unix系统中,名为root的超级用户(SuperUser)拥有最高权限,它可以对计算机中的任何文件进行任何操作。我们在计算机中新建的用户通常是普通用户(Regular User),普通用户只对自己目录下的文件、进程等内容拥有操作权限,如果想操作其他用户目录下的内容,需要得到其他用户的许可。当普通用户想要临时使用超级用户权限进行操作时,最简单的方式就是在命令语句前加入sudo(https://help.ubuntu.com/community/RootSudo):This means that in the terminal you should use sudo for commands that require root privileges; simply prepend sudo to all the commands you need to run as root.
为什么普通用户只是临时使用root权限,而不是永久使用root权限或者直接使用root用户进行长期登陆呢?主要原因有3点。第一点是为了防止用户的误操作。由于root的权限非常高,使用root权限输入的命令都可以执行。如果用户不小心输错了命令,或者误删了某些系统文件,可能会对系统造成破坏;
第二点有关于计算机安全。当用户使用root身份登录计算机时,如果受到恶意攻击,对方可以直接获得root权限,继而获取对整台计算机的控制权;最后一点是防止权限滥用。在企业中,一台服务器通常会有多个用户,不同用户可以在自己的目录下进行环境配置、上传/下载文件、运行程序等操作。如果给某一用户分配了root权限,那么该用户可以随意访问其他用户的目录,随意读取/修改/删除文件,甚至删除其他用户,这不论对用户还是对服务器而言都是非常不安全的。所以说,一般我们都会以普通用户的身份登录系统,当遇到权限不够的问题时,再临时使用root权限进行操作。有关超级用户的更多介绍见Ubuntu官网:https://help.ubuntu.com/community/RootSudoapt-get命令可以从系统认证的软件源(例如清华软件源、阿里云软件源等)中下载软件包和有关包的信息。apt-get后可以添加不同命令来实现不同的操作,例如升级包(apt-get upgrade)、删除指定名称的包(apt-get remove <package name>)等,这里的apt-get install <package name>就是安装指定名称软件包的命令。1.3 编译器包:build-essential
build-essential是一个必须安装的包,它包含了一系列编译所必须的软件包,比如C/C++编译器gcc/g++、自动化编译工具GNU make等。用户安装了build-essential这一个包,相当于将这一系列包都安装在了计算机中(https://help.ubuntu.com/community/InstallingCompilers):
build-essential contains a list of packages which are essential for building Ubuntu packages including gcc compiler, make and other required tools.
由于我已经安装了build-essential包,所以再次输入安装语句时,程序只会检查这个包和其依赖包的版本是否为最新版(上图所示内容)。如果用户是首次输入这条语句的话,程序会输出具体的安装过程。安装完成后,我们可以在命令行中输入apt-cache depends build-essential来查看build-essential的依赖关系,也就是build-essential所包含的一系列包:apt-cache 可以查询和显示已经安装和可安装软件包的信息,我们在这一节使用了命令depends来查看软件包的依赖关系,常用的参数还有show,使用命令apt-cache show <package name>可以查看指定名称软件包的相关介绍。1.4 必须包
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev命令一共会安装7个软件包,这些包都是必须安装的包。git是Git的软件包,Git是一个分布式版本控制系统,在管理远程仓库和本地仓库文件的时候会经常用到,常用的git clone命令可以将GitHub上的项目克隆到本地计算机中,git status可以显示本地仓库的文件状态等等,官网链接https://git-scm.com/。libgtk2.0-dev是GTK+的开发文件(Development File),它包含了开发GTK+需要的头文件和静态库文件。GTK+是一个创建图形用户界面的工具包,官网https://www.gtk.org/。pkg-config是pkg-config的软件包,pkg-config是一个管理编译和链接库的工具,我们在第8步“设置头文件和共享库选项”的时候会用到它,相关介绍见https://www.freedesktop.org/wiki/Software/pkg-config/。libavcodec-dev,libavformat-dev和libswscale-dev三个包都是FFmpeg算法所需要的包,FFmpeg是一个可以处理视频的工具,官网链接https://ffmpeg.org/。1.5 可选包
可选包是用户根据自己的需要来下载的包,下图只是为了示范才安装了所有的包,用户在自己安装时没有必要下载全部的包。官方教程给出的安装命令是sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev其中,python-dev和python-numpy属于Python模块,python-dev包含了构建Python模块所需的头文件、静态库和开发工具,Numpy是Python的一个数值计算扩展工具,由于python-dev并不包含Numpy模块,所以我们需要单独安装python-numpy包。libtbb2和libtbb-dev都是有关TBB模块的包,TBB(Thread Building Blocks, 线程构建模块)是一个可以实现并行开发的工具,libtbb2包括了TBB模块的运行文件(Runtime Files),libtbb-dev包括了开发文件(Development Files)。libjpeg-dev、libpng-dev、libtiff-dev和libjasper-dev都是与图像有关的库,它们分别是JPEG、PNG、TIFF(Tag Image File Format)和JasPer JPEG-2000库的开发文件,JasPer是一个可以处理多种格式图像的软件。libdc1394-22-dev是针对IEEE 1394数码相机的高级编程接口开发工具。我们在安装这些包的时候,可能会遇到“无法定位软件包libjasper-dev”的问题:这是因为我们使用的软件源(所提供的软件包仓库)中没有libjasper-dev这个包。解决这个问题的办法很简单,我们只需手动添加一个包含libjasper-dev的软件包仓库即可。一共三步:Ubuntu系统中的软件源配置文件为/etc/apt/sources.list,它记录了我们目前正在使用的软件包仓库:
我的计算机中的/etc/apt/sources.list我们需要在这个文件中添加一个包含libjasper-dev的软件包仓库条目。在计算机任意位置输入命令行sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"即可:
add-apt-repository是一个添加软件包仓库条目的脚本命令。引号中的内容是该命令的参数<sourceline>,即具体的软件包仓库地址(定义来自命令行 $ man add-apt-repository)
Adds a repository into the /etc/apt/sources.list or /etc/apt/sources.list.d or removes an existing one.
运行完命令之后查看/etc/apt/sources.list文件,可以发现新的软件包仓库已经被追加在了文件末尾:

关于这一步,还有一种更简单的方法:把仓库链接deb http://security.ubuntu.com/ubuntu xenial-security main直接复制粘贴到sources.list中,保存即可。虽然我没有用过这种方法,但感觉非常可行
第二步我们需要使用命令sudo apt update来更新系统可用的软件包列表:最后执行sudo apt-get libjasper-dev命令就可以成功安装libjasper-dev包了。从输出的信息可以发现,安装libjasper-dev的时候程序会自动安装一个依赖包libjasper1。
如果单独执行sudo apt-get libjasper-dev失败,可能是因为程序没有自动安装libjasper1,我们可以尝试使用sudo apt-get libjasper1 libjasper-dev命令来手动安装libjasper-dev和它的依赖包libjasper1。最后多说一点有关软件源的内容。上文中我使用的软件源是清华软件源,因为Ubuntu系统默认的软件源下载速度比较慢,有时还会出现下载失败的问题,所以很多用户都会将系统默认软件源修改为清华、阿里云、网易、中科大等国内的软件源。在这里放上清华软件源的链接以供参考https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/

第二步:下载OpenCV核心算法和额外算法源码,并解压至自己的目录下
命令执行位置:压缩包所在目录下
命令行:
$ sudo unzip <package name>
或
$ sudo tar -xvf <package name>
注意:
1. opencv_contrib文件夹不必放在opencv文件夹下,两个文件夹可以并列放置
2. 建议将所有下载的包都放在统一的目录下,方便查找
复制
第二步需要从OpenCV官网或GitHub中下载核心算法的源码包并解压至自己的目录下。如果需要用到额外算法,可以在GitHub中下载相同版本的额外算法源码包。先来说核心算法源代码的下载。第一种方法是官网下载,网址https://opencv.org/releases/,选择好版本后点击“Sources”即可下载源码包,我在这里下载的是OpenCV3.4.10版本:第二种方法是在GitHub中进行下载,网址为https://github.com/opencv/opencv/releases,点击“Source code”的链接可以下载后缀为.zip或.tar.gz的压缩包,我下载的是前者:GitHub下载OpenCV3.4.10核心算法源码包这里需要注意一件事,在GitHub的OpenCV主页中(https://github.com/opencv/opencv),可以点击“Code->Download ZIP”或者在本地命令行中输入git clone https://github.com/opencv/opencv.git下载核心算法源代码包,但是使用这种方法下载的总是最新版的OpenCV,如果想用旧版本的包,还是需要使用之前的两种方式。刚刚下载的核心算法源码包中包括了OpenCV常用的、成熟的算法,从OpenCV3.0.0开始,一些比较新的、还在测试中的算法会被放在名为opencv_contrib的包中单独发布,这些算法被简称为“额外算法”。如果想要使用这些额外算法,还需要下载opencv_contrib源代码包,下载网址https://github.com/opencv/opencv_contrib/releasesGitHub上下载OpenCV3.4.10额外算法源码包我选择的还是.zip后缀的压缩包,在下载额外算法源码包的时候要注意,opencv_contrib和OpenCV的版本要保持一致,比如我下载的核心算法源码包版本是3.4.10,那么额外算法源码包的版本也要是3.4.10,否则在后续编译时会报错。对于后缀为.zip的压缩包来说,使用sudo unzip <package name>就可以解压了。如果下载的是后缀为.tar.gz的压缩包,使用命令sudo tar -xvf <package name>可以解压。关于将下载、解压后的文件放在哪个目录下并没有特殊要求,我一般习惯把下载下来的文件统一放在/home/用户名/downloads/下,方便管理和查找。
最后还有一点需要说明,一些教程中提到,opencv_contrib文件夹需要放在opencv文件夹下,这个操作并不是必须的,两个文件夹可以并列放置。只要保证CMake编译时额外算法模块的路径正确设置就可以了,这一点在第4步“CMake编译”时会有具体解释。
第三步:创建构建目录
命令执行位置:核心算法源代码目录下
命令行:
$ sudo mkdir <folder name>
注意:
1. 可创建一个或者多个构建目录
2. 目录名称自定,一般以编译模式名称或build作为文件名
复制
第三步我们需要创建一个或多个构建目录来存放下一步CMake编译所产生的过程文件(如Makefile、下载日志、头文件等)。创建--构建--目录可以翻译成新建--存放构建OpenCV项目文件的--文件夹。这一步的命令很简单,进入OpenCV核心算法文件夹下,输入命令sudo mkdir <folder name>即可新建一个指定名称的文件夹。我在这里新建了debug和release两个构建目录,分别存放使用Debug模式和Release模式编译生成的OpenCV过程文件。目录的名称可以根据自己的喜好来取,一般会以编译模式的名称或者build来命名。简单解释一下什么是编译模式。在编译一个项目的时候,开发者可以选择调试模式(Debug)、发布模式(Release)、输出调试信息的发布模式(RelWithDebInfo)等编译模式,不同模式下程序的运行速度、后台的输出信息、生成的可执行程序大小、需要链接的库文件都是不同的。比如说,Debug模式下程序会输出很多的调试符号,但是程序的执行速度较慢,而Release模式下程序会开启优化器来提升执行速度,并生成体积更小的可执行程序,但不会输出调试符号。对于开发者而言,一般会使用两个模式来编译程序:先在Debug模式下进行代码的试运行,并通过输出的调试符号等内容来进行代码优化和bug修改,之后在Release模式下生成适用于部署和发布的、运行速度更快的、体积更小的可执行程序。当我们在Debug模式下编译程序时,需要链接debug版本的库文件,在Release模式下编译时需要链接release版本的库文件。所以我在这里新建了两个构建目录,分别用来编译和生成Debug和Release两种版本的库文件。关于如何设置编译模式,会在下一步CMake编译中进行介绍。
这一篇比较简单,都是一些编译前的准备工作。下一步CMake编译会发两篇文,主要介绍CMake命令行中参数的具体含义、下载文件/压缩包失败的原因及解决方法、CMake的下载逻辑等内容。
我在上一篇文中说,希望在9月份完结这个系列,目前看来应该是做不到了
既然一个flag倒了那就再立一个:在2021年结束之前完结这一整个系列,顺便理清小程序系列文的思路,要是能再发上一篇,就更好了
建立公众号即将满一年,写作热情有些下降,果然稳定的生活使人懒散。不过学如逆水行舟,不进则退,坚持总是最难也是最简单的事。在这里悄悄鼓励自己朝着下个一年前进
~
END
~