1. Windows系统下OpenCV及第三方库文件的使用与下载

如果没有特殊要求,在Windows系统下可以直接使用OpenCV的预编译版本。在githubopencv项目release中选择相应release版本即可。然而,由于版权原因,预编译的opencv并没有包含诸多第三方工具,因此,如果要使用一些第三方工具,或者要在linux系统下使用openCV的话,还需要自己从源码进行编译。

1.1 OpenCV下载与安装

OpenCV可以从官网下载,本文使用openCV 4.50版本。下载完成后点击安装,该安装包实际上是指打包的压缩文件,选择路径解压即可,本文将opencv解压安装到D:\lib路径下,解压后的opencv所在目录为D:\lib\opencv。在opencv目录下,source为源文件的文件夹,build为编译文件的文件夹,包括了VC14VC15的预编译文件。如果要直接使用编译好的opencv,引用build目录下的文件即可。本文在opencv目录下新建一个rebuild目录,用来保存自行编译后的文件。

1.2 OpenCV_Contrib库下载与安装

要安装第三方工具,需要从github上下载相应的opencv_contrib版本,这里从opencv-contrib仓库的release版本中下载opencv_contrib-4.5.0版本.将解压后的opencv_contrib-4.5.0文件夹直接放到opencvsource目录下,以备后续编译使用。

1.3 OpenCV_3rdParty库下载与安装

在OpenCV的编译过程中,还需要一些第三方库支持,这些库文件包含在opencv_3rdparty库中,该库不同的分支(branch)文件对应了编译过程中可能需要的ippicv、ffmpeg以及dnn等第三方库,如果要安装对应的工具,则需要下载对应的库文件。需要注意的是,第三方库文件的下载过程已经写在opencv的编译文件中了,但是由于国内网络环境的原因,直接下载通常很难成功,这也是编译失败的主要原因之一。要使用预先下载的第三方库文件代替直接下载。

github上下载的opencv_3rdparty库,默认的readme分支仅包含简单的说明文档,可以使用git branch命令查看不同分支,并使用git checkout <分支名>切换到不同分支,以便将对应文件复制出来。在opencv/source/3rdparty文件夹下可以看到第三方工具文件夹,在各文件夹下有对应的编译文件,例如ffmpeg文件夹下的编译文件ffmpeg.cmake,在ffmpeg.cmake文件中,可以找到需要下载的文件版本例如ffmpeg/master_20200908。在opencv_3rdparty库中checkout相应的分支即可找到对应文件。

OpenCV编译过程中下载的临时文件位于opencv目录下的.cache目录中,可以在opencv目录下新建.cache目录,针对不同模块新建包括ffmpegippicvxfeatures2d等目录,将上一步中3rdparty库对应分支的文件复制到对应的文件夹下即可。需要注意的是,OpenCV在缓存文件时并不是按照原始的文件名缓存在,而是在前面加上了md5校验字符串,因此在复制文件时要将文件重命名。例如在ffmpeg.cmake文件中有以下内容:

  1. ...
  2. ocv_update(FFMPEG_FILE_HASH_BIN64 "cf5dba83edf8619f57ccff4edb989c62")

那么就需要将原始的opencv_videoio_ffmpeg_64.dll文件重命名为cf5dba83edf8619f57ccff4edb989c62-opencv_videoio_ffmpeg_64.dll。典型的文件夹结构如下图。如果在编译过程中出现下载错误,可以检查对应安装包的编译文件,看看是否与所需要的文件版本内容一致。

另一个选择是将下载的第三方文件放在特定文件夹中,并找到每个CMakelist.txt文件,将其中https://raw.githubusercontent.com....目录修改为存放对应文件的位置如file:///D:/lib/3rdparty...

2.编译环境和工具安装

2.1 安装MinGW-W64msys32发行版

MinGW-w64 是一个Windows系统下支持GCC编译器的工具,它支持64位和32位操作系统。使用MinGW-W64,可以替代微软的VC编译器来编译cc++项目。MSYS2是一个集成了pacmanMinGW-w64Cygwin升级版的工具,用于在Windows系统下提供接近原生的Linux工具链。通过msys2集成的pacman包管理工具,可以方便的安装和管理包,如果你熟悉Arch Linux,使用Pacman工具会感到格外方便。

由于网络环境的原因,MinGW-w64在国内使用很不方便,经常出现无法更新软件的情况,因此这里使用包含了MinGW-w64msys2发行版。

清华大学开源网站msys2下载地址下载msys2后采用默认设置安装,安装在C:\msys64目录下。安装完成后,打开C:\msys64\etc\pacman.d目录并修改以下三个文件,以将msys2的软件源配置为清华镜像,加快下载速度。

  1. #编辑 /etc/pacman.d/mirrorlist.mingw32 ,在文件开头添加:
  2. Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/i686
  3. #编辑 /etc/pacman.d/mirrorlist.mingw64 ,在文件开头添加:
  4. Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/x86_64
  5. #编辑 /etc/pacman.d/mirrorlist.msys ,在文件开头添加:
  6. Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/msys/$arch

打开C:\msys64\mingw64.exe,输入以下命令以安装完整的64位工具链,也可以按照toolchain下面的命令,单独安装gcc,g++gdb三个工具,如果要安装32位工具,则使用mingw32.exe和对应的mingw32与对应的i686相关工具。本文安装64位工具链,安装完成后,在mingw64.exe的命令行下输入gcc --versiong++ --version或者gdb --version可以看到相应版本。

  1. #安装64位工具和make工具
  2. pacman -S mingw64/mingw-w64-x86_64-toolchain
  3. pacman -S mingw64/mingw-w64-x86_64-make
  4. #上述命令包含了以下3个包,因此下面3个不需要再另外安装
  5. pacman -S mingw64/mingw-w64-x86_64-gcc
  6. pacman -S mingw64/mingw-w64-x86_64-g++
  7. pacman -S mingw64/mingw-w64-x86_64-gdb
  8. #安装32位工具
  9. pacman -S mingw32/mingw-w64-i686-toolchain
  10. pacman -S mingw32/mingw-w64-i686-make
  11. pacman -S mingw32/mingw-w64-i686-gcc
  12. pacman -S mingw32/mingw-w64-i686-g++
  13. pacman -S mingw32/mingw-w64-i686-gdb
  14. #pacman常用的操作指令
  15. pacman -Sy #更新软件包数据
  16. pacman -R package-name #删除软件包
  17. pacman -S package-name #安装软件包
  18. pacman -Syu #更新所有
  19. pacman -Ss xx #查询软件xx的信息

要在系统命令行中使用gcc等命令,还需要将minGW-W64添加到windows的环境变量中。在windows控制面板—>系统—>高级系统设置—>环境变量下,双击path参数并新建环境变量,将以下路径添加到环境变量中(如果要使用32位的msys2,路径也要相应地修改为32位的目录)。环境变量配置完成后,在windows命令行或者powershell中输入,输入gcc --versiong++ --version或者gdb --version可以看到相应版本。

注意:如果配置环境变量时命令行已经在运行,需要关掉命令行并重新打开,才能使配置生效。

  1. C:\msys64
  2. C:\msys64\mingw64\bin
  3. C:\msys64\mingw64\x86_64-w64-mingw32\bin

2.2 安装CMAKE工具

CMake 是一个开源的跨平台工具系列,旨在构建、测试和打包软件。在CMaje官网下载对应的编译工具进行安装,并将安装路径写入环境变量。在命令行输入cmake --version可以看到cmake版本信息。安装完成后,也可以通过CMake自带的图形界面Cmake GUI进行文件编译。相比命令行而言,操作更简单。

2.3 安装python2.7

OpenCV编译需要pythonnumpy工具包,如果要编译OpenCVpython接口,同样需要安装python,虽然目前python已经停止对python2的支持,但和大多数历史遗留项目一样,opencv仍然需要安装python2版本。在python官网下载python2的最新发行版python2.7.18并进行安装,安装时选中最后一条“将python写入环境变量”,否则在安装完成后需要手动将python以及pythonscript目录添加的环境变量中。安装完成后在命令行输入python -V可以看到python的版本信息。

修改pip镜像为清华开源站,在命令行输入以下两行,更换python安装库位置,以提高包下载速度,更换完成后通过pip命令安装numpy包。在编译OpenCV的过程中,可能还需要python的debug文件,在python官网下载对应的debug info文件并解压复制到python安装目录的DLLs目录下。如果不需要编译python相关内容,可以跳过该步骤。

  1. pip install pip -U
  2. pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
  3. #安装numpy
  4. pip install numpy

如果安装了msys2,那么在安装python2.7之前,输入python -V,是会显示python3的版本信息的,这是因为minGW64bin目录中已经有了python3的文件,但是这个python没有安装pip,是不完整的,如果要为minGW64安装pip,需要在该目录下运行

  1. curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py #下载pip安装脚本
  2. .\pip3.8.exe install pip #安装pip

注意,由于系统路径中python已经指定为2.7版本,要使用该python3,需要使用完整的路径加程序名称。

2.4 安装JDK和Ant

如果要编译Java环境相关内容,还需要安装和配置JDKApache-ant,下载JDK的windows版本并使用默认设置安装,下载ant的可执行文件binary版本,并解压缩,本文解压缩到D:\lib\apache-ant-1.10.9目录下,并将该目录和bin子目录添加到环境变量中。在命令行中输入javaant可以看到java命令行帮助和ant编译出错(因为没有xml文件)信息,即说明安装完成。如果不需要安装Java相关内容,则不需要安装上述工具。

3. OpenCV编译

打开CMake(cmake-gui),输入路径(where is the source code)选择opencv的源代码路径D:\lib\opencv\sources,输出路径(where to build the binary)选择第一步新建的rebuild目录D:\lib\opencv\rebuild

点击左下角Configure,在编译器选项中选择MinGW Makefiles,下面选择Specify native compilers,以使用MinGW64进行编译,如果电脑安装有Visual Studio也可以选择相应的Visual Studio编译器进行编译。

在下一步的compiles中,c语言选择C:/msys64/mingw64/bin/gcc.exe,c++选择C:/msys64/mingw64/bin/g++.exe。点击确定后,系统会开始尝试进行配置,第一次配置完成后,往往会出现很多红色错误,需要一一解决。在该步骤还可能出现找不到项目文件或编译器的错误,可以检查配置过程输入文件,往往是文件路径错误,或者未安装make工具等情况造成的。在这里需要调整部分参数配置,或者添加、修改参数。

  • Add Entry按钮可以添加编译参数,添加参数时选择参数类型,布尔量通过打勾选择有或无,字符串和路径分别输入对应值。
  • Search框可以输入参数的一部分来过滤和搜索变量,以便于修改

需要调整的配置包括:

  • OPENCV_ENABLE_ALLOCATOR_STATS,取消选择,否则可能出现vs_version.rc.obj错误
  • BUILD_opencv_world选项可以打开,该选项将opencv编译成一个包
  • OPENCV_ENABLE_NONFREE选项打开,以安装contrib文件包内容
  • OPENCV_EXTRA_MODULES_PATH选项输入contrib包的modules目录D:\lib\opencv\sources\opencv_contrib-4.5.0\modules
  • 修改CMAKE_INSTALL_PREFIX参数为D:/lib/opencv/rebuild/mingw64以更改安装目录
  • 取消BUILD_TESTSBUILD_Opencv_python_tests

配置完成后再点击Configure按钮,然后点击Generate按钮。

注意:从命令行进入D:\lib\opencv\rebuild目录,输入mingw32-make install -j16进行编译。注意j后面的数字表示编译线程数,一般为4且不能超过计算机支持的最大线程数。在多线程编译的情况下,有时错误信息会被覆盖掉,从而无法及时找到编译出错的信息,这种时候可以通过mingw32-make install -j1将编译线程数改为1,以便在编译出错时及时停止编译,以处理出错信息。

4. 在Visual Studio中使用OpenCV

Visual Studio中使用OpenCV,可以直接使用预编译版本下的VC14、VC15版本,也可以参照上述步骤重新编译。部分Visual Studio与Visual C++版本对应关系如下表,在实践中,VC15的编译版本也可以在Visual Studio 2019中使用:

Visual Studio 版本 Visual C++ 版本
VS 6.0 VC 6.0
VS 2013 VC 12
VS 2015 VC 14
VS 2017 VC 15
VS 2019 VC 16
  • 将编译文件的bin目录D:\lib\opencv\build\x64\vc15\bin添加到环境变量中。
  • 新建Visual Studio空项目。在Resource Files上右键单击Add添加New Item,创建一个main.cpp文件。
  1. #include <iostream>
  2. #include <opencv2/opencv.hpp>
  3. using namespace std;
  4. using namespace cv;
  5. int main(int argc, char* argv[]) {
  6. const char* imagename = "D:\\Pictures\\Camera Roll\\digitalmeter1.jpg";//此处为你自己的图片路径
  7. //从文件中读入图像
  8. Mat img = imread(imagename, 1);
  9. //如果读入图像失败
  10. if (img.empty()) {
  11. fprintf(stderr, "Can not load image %s\n", imagename);
  12. return -1;
  13. }
  14. //显示图像
  15. imshow("image", img);
  16. //此函数等待按键,按键盘任意键就返回
  17. waitKey();
  18. return 0;
  19. }
  • 在项目资源上右键->属性,在VC++目录(VC++ Directory)包含目录(include Directories)中添加
    D:\lib\opencv\build\includeD:\lib\opencv\build\include\opencv2
  • 库目录(Library Directories)中添加D:\lib\opencv\build\x64\lib
  • 在链接器(Linker)的输入(Input)中,添加D:\lib\opencv\build\x64\lib下的opencv_world450d.lib,对应编译文件的debug模式,如果要编译release版本,则需要选择不带d的opencv_world450.lib文件。

编译并运行项目,如果没有错误,则可以显示图像内容。

5. 在VS Code中使用OpenCV

要在VS Code中使用OpenCV,需要安装VScode的c/c++语言扩展插件,然后在项目文件夹下新建main.cpp文件,文件内容可与前节相同,根目录下新建.vscode文件夹(也可以按照官方文档指引,通过Terminal->Config Default Building Task命令新建该文件夹并在其中生成tasks.json文件),然后在其中新建tasksjsonlauch.jsonc_cpp_properties.json三个文件。选择Windows系统的VC编译工具cl.exemingw64进行编译时,编译选项略有不同。两种不同编译工具下的文件内容分别如下:

5.1 VC编译器

c_cpp_properties.json

  1. {
  2. "configurations": [
  3. {
  4. "name": "win",
  5. "includePath": [
  6. "${workspaceFolder}/**",
  7. "C:\\lib\\opencv\\build\\include",
  8. "C:\\lib\\opencv\\build\\include\\opencv2" ],
  9. "defines": ["_DEBUG"],
  10. "compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC\\Tools\\MSVC\\14.16.27023\bin\\Hostx64\\x64\\cl.exe",
  11. "cStandard": "c11",
  12. "cppStandard": "c++17",
  13. "intelliSenseMode": "msvc-x64"
  14. }
  15. ],
  16. "version": 4
  17. }

tasksjson

  1. {
  2. // See https://go.microsoft.com/fwlink/?LinkId=733558
  3. // for the documentation about the tasks.json format
  4. "version": "2.0.0",
  5. "tasks": [
  6. {
  7. "type": "shell",
  8. "label": "cl.exe build active file",
  9. "command": "cl.exe",
  10. "args": [
  11. "/Zi",
  12. "/EHsc",
  13. "/utf-8",
  14. "/Fe:",
  15. "${fileDirname}\\${fileBasenameNoExtension}.exe",
  16. "${file}",
  17. "/DYNAMICBASE",
  18. "C:\\lib\\opencv\\build\\x64\\vc15\\lib\\opencv_world450.lib"
  19. ],
  20. "problemMatcher": ["$msCompile"],
  21. "group": {
  22. "kind": "build",
  23. "isDefault": true
  24. }
  25. }
  26. ]
  27. }

lauch.json

  1. {
  2. "version": "0.2.0",
  3. "configurations": [
  4. {
  5. "name": "cl.exe build and debug active file",
  6. "type": "cppvsdbg",
  7. "request": "launch",
  8. "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
  9. "args": [],
  10. "stopAtEntry": false,
  11. "cwd": "${workspaceFolder}",
  12. "environment": [],
  13. "externalConsole": false,
  14. "preLaunchTask": "cl.exe build active file"
  15. },
  16. ]
  17. }

5.2 mingw64编译器

c_cpp_properties.json

  1. {
  2. "configurations": [
  3. {
  4. "name": "win",
  5. "includePath": [
  6. "${workspaceFolder}/**",
  7. "D:\\lib\\opencv\\rebuild\\install\\include",
  8. "D:\\lib\\opencv\\rebuild\\install\\include\\opencv2" ],
  9. "defines": ["_DEBUG", "UNICODE", "_UNICODE"],
  10. "compilerPath": "C:\\msys64\\mingw64\\bin\\gcc.exe",
  11. "cStandard": "c11",
  12. "cppStandard": "c++17",
  13. "intelliSenseMode": "clang-x64"
  14. }
  15. ],
  16. "version": 4
  17. }

tasksjson

  1. {
  2. // See https://go.microsoft.com/fwlink/?LinkId=733558
  3. // for the documentation about the tasks.json format
  4. "version": "2.0.0",
  5. "tasks": [
  6. {
  7. "type": "shell",
  8. "label": "g++.exe build active file",
  9. "command": "C:\\msys64\\mingw64\\bin\\g++.exe",
  10. "args": [
  11. "-g",
  12. "-std=c++11",
  13. "${file}",
  14. "-o",
  15. "${fileDirname}\\${fileBasenameNoExtension}.exe",
  16. "-I", "D:\\lib\\opencv\\rebuild\\install\\include",
  17. "-I", "D:\\lib\\opencv\\rebuild\\install\\include\\opencv2",
  18. "-L", "D:\\lib\\opencv\\rebuild\\install\\x64\\mingw\\lib",
  19. "-l", "libopencv_core450",
  20. "-l", "libopencv_imgproc450",
  21. "-l", "libopencv_imgcodecs450",
  22. "-l", "libopencv_video450",
  23. "-l", "libopencv_ml450",
  24. "-l", "libopencv_highgui450",
  25. "-l", "libopencv_objdetect450",
  26. "-l", "libopencv_flann450",
  27. "-l", "libopencv_video450",
  28. "-l", "libopencv_photo450",
  29. "-l", "libopencv_videoio450"
  30. ],
  31. "options": {
  32. "cwd": "C:\\msys64\\mingw64\\bin"
  33. },
  34. "problemMatcher": [
  35. "$gcc"
  36. ],
  37. "group": {
  38. "kind": "build",
  39. "isDefault": true
  40. }
  41. }
  42. ]
  43. }

lauch.json

  1. {
  2. "version": "0.2.0",
  3. "configurations": [
  4. {
  5. "name": "(gdb) Launch",
  6. "type": "cppdbg",
  7. "request": "launch",
  8. "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
  9. "args": [],
  10. "stopAtEntry": true,
  11. "cwd": "${workspaceFolder}",
  12. "environment": [],
  13. "externalConsole": true,
  14. "MIMode": "gdb",
  15. "miDebuggerPath": "C:\\msys64\\mingw64\\bin\\gdb.exe",
  16. "preLaunchTask": "g++.exe build active file",
  17. "setupCommands": [
  18. {
  19. "description": "Enable pretty-printing for gdb",
  20. "text": "-enable-pretty-printing",
  21. "ignoreFailures": true
  22. }
  23. ]
  24. },
  25. ]
  26. }

参考文献