简单介绍一下OpenCV

OpenCV 是(Open Source Computer Vision Library)的简称,在计算机视觉领域中是一个非常重要的开源库,该库使用的是BSD开源协议,这个开源协议非常的开放,具体开放到什么程度,它允许你使用源代码进行你自己项目的开发,当然你的项目既可以开源也可以不开源,所以说非常的开放,你也可以用BSD协议的开源代码更改后用作商业用途,但是也有一定的限制,也不能说是限制,可能算是一种协议精神吧,如果二次开发的产品包含源BSD协议的代码,则需要在我们的产品源代码中带有原来的BSD协议,如果开发的是非源代码项目(软件、库),则需要在我们的文档中声明有部分代码使用BSD协议。还有就是不能用开源作者和其产品对我们自己的产品做宣传。开源这个词引来的话题也非常的多,感兴趣的同学可以看一下这本书《The success of open source》。好了BSD协议就简单说这些,可能大家已经迫不及待的跳到下面的步骤了,不过没关系,网络资源各取所需,对故事感兴趣的人自然就会读一读故事。当然,这里没有太多的故事。 好了我们简单知道OpenCV是用来做计算机视觉相关内容的一个开放性很大的开源库就OK了,网上很多关于安装OpenCV的教程,我自己也是安装了好多次,所以今天把一些经验写下来,供大家参考。

如何选择版本

刚刚接触到OpenCV的同学都会纠结同一个问题:选那个版本好呢?有人说选2.*, 有人说3.*的好,到底那个版本比较合适,似乎是一个比较难决定,可能这是人的一种本性,遇到陌生的东西是不愿意冒险尝试的,喜欢听总结,挺经验。那么我建议大家怎么选择版本呢?这个问题的核心不在于各个版本之间有什么差别,而在于你需要OpenCV来做什么,如果你只是刚刚学习,对OpenCV还不熟悉,那么就不用纠结,随便下载一个最新或者次新版本,安装上尝试一下就好,如果你的工作环境非常特殊,项目是从前辈那里接手的,也不用纠结,用子前项目的版本。总之,没有哪一个版本好与不好之分,只有版文适合还是不适合你。新手的话我建议大家安装3.2或者3.4版本(当然我也是新手)。

如何安装

我原来写过以篇简单的Blog试图总结安装OpenCV中遇到的问题,然后可以根据这些问题去搜索资料就好,后来发现这样似乎并没有什么人看,因为这样造成了大家二次查找资料没有太多时间去思考,也就厌倦这种文章。所以今天才打算写一篇比较详细的文章,做为总结。

下载软件和工具

在安装软件之前看一下自己的工作平台是windows还是ubuntu(linux),我想大部分的人都是在这两个平台下安装环境的,所以其他平台的我也不介绍了。这两个平台对应的开发工具是不一样的如下图:
开发平台
一般来说在windows开发大家主要用微软的那一套开发工具,visual studio 被称为史上最强大的IDE,一般使用它就对了,但是我们经常会遇到这样的问题,又是版本问题。visual studio大家都知道有很多版本,现在最新的有2017版的,但是很多人电脑上可能是用的2015或者2013版本,要注意的是不同版本的visual studio不能通用一个OpenCV库,什么意思呢?就像上图中表示的那样windows平台的开发工具是visusl studio,但不同版本的studio对应不同版本的VC编译器,而可直接使用的OpenCV库必须是对应的VC编译器编译成的才可以使用。OpenCV官网给出了windows版本的下载包其中就包含已经编译好的库可以供大家直接使用,但是一定要注意,一般官网给定的那个包是需要对应的vs版本的,比如说OpenCV3.2 从官网下载下来的压缩包解压后如下图,build文件夹就是存放着已经编译好的库,sources文件夹是OpenCV源代码。官网给的是VC14编译器版本的,对应的Visual studio是2015,所以如果你想直接使用该库你的电脑上必须有对应的visual studio2015,其他版本的OpenCV也是同样道理的。

问题来了,如果我想用OpenCV3.2 但是当前电脑上是不是visual studio2015怎么办呢? 这个问题很好解决,就是我们需要自己安装这个库,这个问题也同样适用于你想用一些额外功能的时候,如果你想用一些OpenCV额外功能,比如说人脸识别功能,这个模块官网给的编译好的库里面是没有的,需要我们自己去编译OpenCV并安装才可以使用。好了,很多坑就是在这里踩出来的。下面我们开始踩坑。

踩坑

下载源代码和opencv_contrib

自己编译OpenCV和其额外功能首先需要下载两部分源代码,我建议大家到github上下载。
githubOpenCV,打开这个页面发现有两个链接,一个是OpenCV对应的,另一个是opencv_contrib也就是opencv额外的功能模块。点进去opencv,点击releases就可以找到并下载你需要的对应的版本


同样的,下载和opencv版本相同的opencv_contrib源代码,并将两部分源代码解压到你的电脑里。剩下的工作就是编译了。例如我最近安装了OpenCV3.4 对应的两个文件夹就是下图的两个文件夹

下载构建工程的工具:cmake-gui

我建议大家使用cmake-gui这个工具进行安装操作,cmake其实是一个非常好用的工具,可以用它构建不同类型的工程。windows下面的cmake默认是图形化界面,在ubuntu下面的cmake默认是命令行工具,我们需要另外安装cmake-gui工具才可以使用cmake-gui,如果你命令行熟悉的话也可以使用命令行,其功能是一样的,这里我统一使用cmake-gui

ubnutu 下安装cmake-gui

sudo apt-get install cmake-gui

好啦,安装好cmake-gui就可以进行安装了,怎么安装呢?
请看下图

s 表示sources,即opencv源代码文件夹,我们需要把刚才解压的opencv源代码文件夹的路径指定在这里。t表示target,即工程文件放置的位置,这里你可以新建一个文件夹,然后将这个文件夹的路径指定到这里。然后点击configure按钮,第一次点击该按钮cmake会提示你选择生成哪种工程

ubuntu 选择 Unix MakeFiles
windows 选择你电脑对应的visual studio版本

可能还有很多其他的选项,比如codeblocks,或者eclipse,不同的IDE会构建不同类型的工程文件。
下面是选择使用编译器,我们就使用默认的编译器就好。

然后再次点击configure按钮,cmake就开始构建工程文件。这个过程cmake会建立一个工程,并且会下载一些第三方的库比如说ffmpeg, ippcv等。如果我们没有网络连接的话,最终没有这些模块,那么cmake会报错,这是一个很大的坑,并且,即便是有网下载也会很慢,有时候会报timeout 的错误,所以这个时候该怎么办呢?

继续踩坑-下载第三方文件ippcv、ffmpeg

上面的问题其实很好解决,前提是你的网络很好,并且不会被各种防火墙给墙掉。也就是说下载不成功的原因首先是网络不好,毕竟服务器离我们比较远,其次就是电脑上的防火墙软件把你的下载给封掉了。所以我们想办法提前下载好这些文件,然后放到对应的文件夹中即可。

ffmpeg

怎么下载ffmpeg呢? 这个就需要我们查看一下文件了,打开 opecvdir/3rdparty/ffmpeg/ffmpeg.cmake 文件。该文加中的信息会告诉你下在哪个版本的ffmpeg,下载后放到哪个文件夹。如果是ubuntu系统,系统中已经用ffmpeg模块,那么cmake不会重复下载的,但是据我的经验,windows需要下载ffmpeg(32和64位两个文件)和ippcv。ubuntu需要下载ippcv(系统已经安装了ffmpeg)
ffmpeg 第一行会告诉你cmake会下载哪个版本的ffmpeg文件。例如我的ffmpeg.cmake 第一行是这样写的

# Binary branch name: ffmpeg/master_20171009
# Binaries were created for OpenCV: 8ac2c5d620b467d3f22802e96c88ddde6da707af

意思是,ffmpeg对应的opencv分支是ffmpeg/master_20171009。 好了,那么我们到github上面的opencv下找到 3rdparty仓库,然后选择分支
ffmpeg/master_20171009。然后下载opencv_ffmpeg.dllopencv_ffmpeg_64.dll,就可以了,那么下载下来放在哪里呢?我们仍然看ffmpeg.cmake文件,该文件中有这样一行代码

set(FFMPEG_DOWNLOAD_DIR "${OpenCV_BINARY_DIR}/3rdparty/ffmpeg")

意思是设置ffmpeg的下载路径为 opencv二进制文件夹/3rdparty/ffmpeg,所以下载下来的文件夹放在那里就可以了,但是问题来了,opencv二进制文件的文件夹在哪里呢?其实就是opencv源代码文件夹。

ippcv参照ffmpeg方法

与ffmpeg略有不同,不同的地方在于ippcv的ippcv.cmake文件内的内容不一样,这个文件是一个下载函数,但是我们仍然可以从这个文件中看到一些信息

ippcv.cmake document
function(download_ippicv root_var)
  set(${root_var} "" PARENT_SCOPE)

  # Commit SHA in the opencv_3rdparty repo
  set(IPPICV_COMMIT "dfe3162c237af211e98b8960018b564bc209261d")
  # Define actual ICV versions
  if(APPLE)
    set(OPENCV_ICV_PLATFORM "macosx")
    set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_mac")
    if(X86_64)
      set(OPENCV_ICV_NAME "ippicv_2017u3_mac_intel64_general_20170822.tgz")
      set(OPENCV_ICV_HASH "c1ebb5dfa5b7f54b0c44e1917805a463")
    else()
      set(OPENCV_ICV_NAME "ippicv_2017u3_mac_ia32_general_20170822.tgz")
      set(OPENCV_ICV_HASH "49b05a669042753ae75895a445ebd612")
    endif()
  elseif((UNIX AND NOT ANDROID) OR (UNIX AND ANDROID_ABI MATCHES "x86"))
    set(OPENCV_ICV_PLATFORM "linux")
    set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_lnx")
    if(X86_64)
      set(OPENCV_ICV_NAME "ippicv_2017u3_lnx_intel64_general_20170822.tgz")
      set(OPENCV_ICV_HASH "4e0352ce96473837b1d671ce87f17359")
    else()
      set(OPENCV_ICV_NAME "ippicv_2017u3_lnx_ia32_general_20170822.tgz")
      set(OPENCV_ICV_HASH "dcdb0ba4b123f240596db1840cd59a76")
    endif()
  elseif(WIN32 AND NOT ARM)
    set(OPENCV_ICV_PLATFORM "windows")
    set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_win")
    if(X86_64)
      set(OPENCV_ICV_NAME "ippicv_2017u3_win_intel64_general_20170822.zip")
      set(OPENCV_ICV_HASH "0421e642bc7ad741a2236d3ec4190bdd")
    else()
      set(OPENCV_ICV_NAME "ippicv_2017u3_win_ia32_general_20170822.zip")
      set(OPENCV_ICV_HASH "8a7680ae352c192de2e2e34936164bd0")
    endif()
  else()
    return()
  endif()

  set(THE_ROOT "${OpenCV_BINARY_DIR}/3rdparty/ippicv")
  ocv_download(FILENAME ${OPENCV_ICV_NAME}
               HASH ${OPENCV_ICV_HASH}
               URL
                 "${OPENCV_IPPICV_URL}"
                 "$ENV{OPENCV_IPPICV_URL}"
                 "https://raw.githubusercontent.com/opencv/opencv_3rdparty/${IPPICV_COMMIT}/ippicv/"
               DESTINATION_DIR "${THE_ROOT}"
               ID IPPICV
               STATUS res
               UNPACK RELATIVE_URL)

  if(res)
    set(${root_var} "${THE_ROOT}/${OPENCV_ICV_PACKAGE_SUBDIR}" PARENT_SCOPE)
  endif()
endfunction()

该函数首先判断我们的系统是什么类型的,(apple unix(linux) win32(windows)),获得系统类型,然后判断操作系统是32位还是64位,然后下载的对应的文件,我们可以根据自己的系统信息查看需要下载哪个文件。
例如我的电脑是ubuntu16.04, 64位,那么我就需要下载ippicv_2017u3_lnx_intel64_general_20170822.tgz。同样的,该文需要到github中下载,下载方式和ffmpeg下载方式相同。最后放在对应的文件夹中。
ippcv 20170822分支

好了,可算搞定这些东西了,将下载下来的文件放在对应的文件下后就可以进行配置工作了。此时我们再次点击configre按钮,然后调整编译安装的参数。

configure

在编译安装中有很多参数,但是我们只关注我我们需要的即可。
下面我列出一些比较重要的参数

BUILD_DOCS 是否编译函数文档
BUILD_JAVA 是否生成java库
BUILD_PYTHON 是否生成 python库
BUILD_opencv_python
BUILD_opencv_world 是否将各个模块的连接库放在一个文件里 我们选择no
CMAKE_INSTALL_PREFIX 库的最终安装目录,需要我们指定
OPENCV_EXTRA_MODUALS_PATH 即我们上面下载的contrib文件夹下的moudle文件夹对应的路径

其他的参数根据我们的实际情况选定,比如你需要Qt配合OpenCV的使用,那么就在with_Qt 那个参数那画勾,前提是电脑里安装了Qt的库,否则他会报错的。其他参数可以选择默认,然后再次点击configure按钮,你会发现参数部分没有红色的,证明配置成功,接下来我们点击generate就可以了。

到这里OpenCV的工程就构建完毕,接下来编译安装。

Linux 命令行安装

  • 下载opencv 源码
  • 下载opencv-contrib源码
  • 在opencv源码文件夹下新建build文件夹
  • cd到build文件夹
  • 新建 run.sh文件用来执行命令
  • 文本编辑器打开run.sh
  • 输入下面的命令(下面命令是opencv4.2版本的)
  • 注意:如果python是在conda环境中,需要指定到具体的路径
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=install/opencv3.4.3 \
-D OPENCV_EXTRA_MODULES_PATH=/home/facri/Documents/OpenCV/OpenCV3.4.3_Source/opencv_contrib-3.4.3/modules \
-D ENABLE_NEON=ON \
-D ENABLE_VFPV3=ON \
-D WITH_OPENMP=ON \
-D WITH_OPENCL=OFF \
-D BUILD_ZLIB=ON \
-D BUILD_JAVA=OFF \
-D BUILD_TIFF=ON \
-D WITH_FFMPEG=ON \
-D WITH_TBB=ON \
-D BUILD_TBB=ON \
-D BUILD_TESTS=OFF \
-D WITH_EIGEN=ON \
-D WITH_GSTREAMER=ON \
-D WITH_V4L=ON \
-D WITH_LIBV4L=ON \
-D WITH_VTK=OFF \
-D WITH_QT=OFF \
-D OPENCV_ENABLE_NONFREE=ON \
-D INSTALL_C_EXAMPLES=OFF \
-D INSTALL_PYTHON_EXAMPLES=OFF \
-D BUILD_opencv_python3=TRUE \
-D PYTHON3_EXECUTABLE=/home/facri/SoftWare/miniconda3/envs/py37/bin/python3 \
-D PYTHON3_NUMPY_INCLUDE_DIRS=/home/facri/SoftWare/miniconda3/envs/py37/lib/python3.7/site-packages/numpy/core/include \
-D PYTHON3_INCLUDE=/home/facri/SoftWare/miniconda3/envs/py37/include \
-D PYTHON3_LIBRARIES=/home/facri/SoftWare/miniconda3/envs/py37/lib/libpython3.so \
-D PYTHON3_PACKAGES_PATH=lib/python3.7/site-packages \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D BUILD_EXAMPLES=OFF ..

编译安装

ubuntu

我们到我们生成的工程文件夹下,ubuntu打开终端运行

make -j4  

该命令是编译的意思 参数-j4表示的是用4核cpu,也可以不用该参数,编译成功后运行下面的命令

sudo make install

到这里OpenCV库就安装完成了,安装到了我们刚才设置的CMAKE_INSTALL_PREFIX 文件夹下,默认是/usr/local

如果编译安装了Python的库,还需要配置一下才可以在python 中使用,通过上述过程我们的OpenCV安装目录下会有lib/python3.*文件夹,我们只需要把这里的库复制到我们的python

windows

用我们之前选定的visual studio打开生成的工程目录下的 OpenCV.sln文件,对整个工程生成解决方案,或者找到工程目录中的CMake** 文件夹下的ALLBUILD生成解决方案,也就是对应ubuntu中的make操作。然后找到工程文件中的CMake**文件夹下的INSTALL ,生成INSTALL的项目解决方案,这个操作对应ubuntu中的 make install 。到这里windows下面的OpenCV也安装成功了,在编译的过程中如果出错了,那就是上一步的cmake配置没有配置对,回去重新配置。

安装后续工作

真的是一重山一重关,安装一个OpenCV怎么这么复杂,难道就没有项windows下面的.exe 文件安装一下就可以了么? 还真没有,不过对于这点小小的困难我们还是需要克服,这难道不是一种求知精神么?

安装完OpenCV库以后是不能直接使用的,ubuntu和windows都需要配置一下。

linux

linux 环境下配置后续工作无非是配置动态连接库,我们编译安装的工作就是生成了一些模块的动态连接库,这些库需要被系统知道,所以需要后续的操作。

unbutu 下配置动态连接库的文件夹和文夹有

/etc/ld.so.conf.d/
/etc/ld.so.conf

/etc/ld.so.conf.d/ 里面有一些 .conf 文件,这些.conf 文件就是动态连接库文件,ubuntu操作系统会自动加载这些文件获取这些库的属性信息。
我们安装玩opencv后,在/etc/ld.so.conf.d/ 目录下会多出一个opencv.conf的文件,该文件的内容很简单,就是指定opencv lib的地址,我的系统里opencv.conf 内容如下:

表示我的opencv库目录在/usr/local/OpenCV/lib中。

/etc/ld.so.conf 文件其实是指向 /etc/ld.so.conf.d/ 文件夹的。

如果安装完Opencv后/etc/ld.so.conf.d/ 没有opencv.conf 文件,那么我们需要自己建立一个,然后把我们安装的opencv 库目录的地址写进去即可。
然后在终端中运行命令:

ldconfig

该命令表示更新动态连接库

ubuntu内还有一个第三方的库管理工具

pkg-config

配置pkg-config 我们需要把 opencvInstallDir/lib/pkgconfig/opencv.pc 复制到 /usr/lib/pkgconfig/ 目录下。
测试一下我们的pkg-config 是否成功配置了opencv

终端中输入

pkg-config --libs --cflags opencv

如果出现opencv对应的地址和库文件名说明成功配置。

windows visual studio

在windows平台下面配置visual studio 的opencv环境就非常简单了,无非是量项工作:

  1. 配置opencv path环境变量
  2. 配置visual studio 库和include设置

这两项工作网上的blog一大堆,所以我就不费话了,大家可以自己找找。

最后如何使用

windows版的不说了,很好配置,那么如果我们在Linux平台下使用CMake构建工程的时候该如何使用OpenCV呢?

  1. 在工程的CmakeLists.txt里指定OpenCV的环境设置代码如下:
set(OpenCV_DIR /home/User/opencv/build/)
find_package( OpenCV REQUIRED )

如果我们在linux平台下默认安装到了/usr/local目录下,就不需要set(OpenCV_DIR /config_path/opencv/),但往往我们安装的位置可能是随机的,这时候就需要指定目录了,这个目录通常是在安装目录下的lib/cmake/opencv文件夹。或者你也可以利用命令find opencv安装目录 --name OpenCVConfig 找到OpenCVConfig.cmake或者OpenCVConfig-version.cmake的那个目录就是要填在上面的CmakeLists.txt代码中的路径,然后你用cmake 去构建工程就可以使用opencv了。

这篇Blog就写到这里了,如果有疑问的欢迎大家私信留言,如果觉得这篇文章有用,别忘记关注我的Blog

PiggyGaGa

Logo

长江两岸老火锅,共聚山城开发者!We Want You!

更多推荐