1. Windows系統下OpenCV及第三方庫文件的使用與下載
如果沒有特殊要求,在Windows系統下可以直接使用OpenCV的預編譯版本。在github的opencv項目release中選擇相應release版本即可。然而,由於版權原因,預編譯的opencv並沒有包含諸多第三方工具,因此,如果要使用一些第三方工具,或者要在linux系統下使用openCV的話,還需要自己從源碼進行編譯。
1.1 OpenCV下載與安裝
OpenCV可以從官網下載,本文使用openCV 4.50版本。下載完成後點擊安裝,該安裝包實際上是指打包的壓縮文件,選擇路徑解壓即可,本文將opencv解壓安裝到D:\lib路徑下,解壓後的opencv所在目錄為D:\lib\opencv。在opencv目錄下,source為源文件的文件夾,build為編譯文件的文件夾,包括了VC14和VC15的預編譯文件。如果要直接使用編譯好的opencv,引用build目錄下的文件即可。本文在opencv目錄下新建一個rebuild目錄,用來保存自行編譯後的文件。
1.2 OpenCV_Contrib庫下載與安裝
要安裝第三方工具,需要從github上下載相應的opencv_contrib版本,這裡從opencv-contrib倉庫的release版本中下載opencv_contrib-4.5.0版本.將解壓後的opencv_contrib-4.5.0文件夾直接放到opencv的source目錄下,以備後續編譯使用。
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目錄,針對不同模塊新建包括ffmpeg、ippicv、xfeatures2d等目錄,將上一步中3rdparty庫對應分支的文件複製到對應的文件夾下即可。需要注意的是,OpenCV在緩存文件時並不是按照原始的文件名緩存在,而是在前面加上了md5校驗字符串,因此在複製文件時要將文件重命名。例如在ffmpeg.cmake文件中有以下內容:
...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-W64的msys32發行版
MinGW-w64 是一個Windows系統下支持GCC編譯器的工具,它支持64位和32位作業系統。使用MinGW-W64,可以替代微軟的VC編譯器來編譯c和c++項目。MSYS2是一個集成了pacman和MinGW-w64的Cygwin升級版的工具,用於在Windows系統下提供接近原生的Linux工具鏈。通過msys2集成的pacman包管理工具,可以方便的安裝和管理包,如果你熟悉Arch Linux,使用Pacman工具會感到格外方便。
由於網絡環境的原因,MinGW-w64在國內使用很不方便,經常出現無法更新軟體的情況,因此這裡使用包含了MinGW-w64的msys2發行版。
從清華大學開源網站msys2下載地址下載msys2後採用默認設置安裝,安裝在C:\msys64目錄下。安裝完成後,打開C:\msys64\etc\pacman.d目錄並修改以下三個文件,以將msys2的軟體源配置為清華鏡像,加快下載速度。
#編輯 /etc/pacman.d/mirrorlist.mingw32 ,在文件開頭添加:Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/i686#編輯 /etc/pacman.d/mirrorlist.mingw64 ,在文件開頭添加:Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/x86_64#編輯 /etc/pacman.d/mirrorlist.msys ,在文件開頭添加: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 --version、g++ --version或者gdb --version可以看到相應版本。
#安裝64位工具和make工具pacman -S mingw64/mingw-w64-x86_64-toolchainpacman -S mingw64/mingw-w64-x86_64-make#上述命令包含了以下3個包,因此下面3個不需要再另外安裝pacman -S mingw64/mingw-w64-x86_64-gccpacman -S mingw64/mingw-w64-x86_64-g++pacman -S mingw64/mingw-w64-x86_64-gdb#安裝32位工具pacman -S mingw32/mingw-w64-i686-toolchainpacman -S mingw32/mingw-w64-i686-makepacman -S mingw32/mingw-w64-i686-gccpacman -S mingw32/mingw-w64-i686-g++pacman -S mingw32/mingw-w64-i686-gdb#pacman常用的操作指令pacman -Sy#更新軟體包數據pacman -R package-name #刪除軟體包pacman -S package-name #安裝軟體包pacman -Syu#更新所有pacman -Ss xx #查詢軟體xx的信息
要在系統命令行中使用gcc等命令,還需要將minGW-W64添加到windows的環境變量中。在windows控制面板-->系統-->高級系統設置-->環境變量下,雙擊path參數並新建環境變量,將以下路徑添加到環境變量中(如果要使用32位的msys2,路徑也要相應地修改為32位的目錄)。環境變量配置完成後,在windows命令行或者powershell中輸入,輸入gcc --version、g++ --version或者gdb --version可以看到相應版本。
注意:如果配置環境變量時命令行已經在運行,需要關掉命令行並重新打開,才能使配置生效。
C:\msys64C:\msys64\mingw64\binC:\msys64\mingw64\x86_64-w64-mingw32\bin
2.2 安裝CMAKE工具
CMake 是一個開源的跨平臺工具系列,旨在構建、測試和打包軟體。在CMaje官網下載對應的編譯工具進行安裝,並將安裝路徑寫入環境變量。在命令行輸入cmake --version可以看到cmake版本信息。安裝完成後,也可以通過CMake自帶的圖形界面Cmake GUI進行文件編譯。相比命令行而言,操作更簡單。
2.3 安裝python2.7
OpenCV編譯需要python的numpy工具包,如果要編譯OpenCV的python接口,同樣需要安裝python,雖然目前python已經停止對python2的支持,但和大多數歷史遺留項目一樣,opencv仍然需要安裝python2版本。在python官網下載python2的最新發行版python2.7.18並進行安裝,安裝時選中最後一條「將python寫入環境變量」,否則在安裝完成後需要手動將python以及python的script目錄添加的環境變量中。安裝完成後在命令行輸入python -V可以看到python的版本信息。
修改pip鏡像為清華開源站,在命令行輸入以下兩行,更換python安裝庫位置,以提高包下載速度,更換完成後通過pip命令安裝numpy包。在編譯OpenCV的過程中,可能還需要python的debug文件,在python官網下載對應的debug info文件並解壓複製到python安裝目錄的DLLs目錄下。如果不需要編譯python相關內容,可以跳過該步驟。
pip install pip -Upip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple#安裝numpypip install numpy
如果安裝了msys2,那麼在安裝python2.7之前,輸入python -V,是會顯示python3的版本信息的,這是因為minGW64的bin目錄中已經有了python3的文件,但是這個python沒有安裝pip,是不完整的,如果要為minGW64安裝pip,需要在該目錄下運行
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py #下載pip安裝腳本.\pip3.8.exe install pip #安裝pip
注意,由於系統路徑中python已經指定為2.7版本,要使用該python3,需要使用完整的路徑加程序名稱。
2.4 安裝JDK和Ant
如果要編譯Java環境相關內容,還需要安裝和配置JDK和Apache-ant,下載JDK的windows版本並使用默認設置安裝,下載ant的可執行文件binary版本,並解壓縮,本文解壓縮到D:\lib\apache-ant-1.10.9目錄下,並將該目錄和bin子目錄添加到環境變量中。在命令行中輸入java和ant可以看到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_TESTS和BUILD_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中使用:
將編譯文件的bin目錄D:\lib\opencv\build\x64\vc15\bin添加到環境變量中。新建Visual Studio空項目。在Resource Files上右鍵單擊Add添加New Item,創建一個main.cpp文件。
#include <iostream>#include <opencv2/opencv.hpp>usingnamespacestd;usingnamespacecv;intmain(intargc, char*argv[]) {constchar*imagename="D:\\Pictures\\Camera Roll\\digitalmeter1.jpg";//此處為你自己的圖片路徑//從文件中讀入圖像Matimg=imread(imagename, 1);//如果讀入圖像失敗if (img.empty()) {fprintf(stderr, "Can not load image %s\n", imagename);return-1; }//顯示圖像imshow("image", img);//此函數等待按鍵,按鍵盤任意鍵就返回waitKey();return0;}
在項目資源上右鍵->屬性,在VC++目錄(VC++ Directory)的包含目錄(include Directories)中添加D:\lib\opencv\build\include和D:\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文件),然後在其中新建tasksjson、lauch.json和c_cpp_properties.json三個文件。選擇Windows系統的VC編譯工具cl.exe和mingw64進行編譯時,編譯選項略有不同。兩種不同編譯工具下的文件內容分別如下:
5.1 VC編譯器
c_cpp_properties.json
{"configurations": [ {"name": "win","includePath": ["${workspaceFolder}/**","C:\\lib\\opencv\\build\\include","C:\\lib\\opencv\\build\\include\\opencv2" ],"defines": ["_DEBUG"],"compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC\\Tools\\MSVC\\14.16.27023\bin\\Hostx64\\x64\\cl.exe","cStandard": "c11","cppStandard": "c++17","intelliSenseMode": "msvc-x64" } ],"version": 4}
tasksjson
{// See https://go.microsoft.com/fwlink/?LinkId=733558// for the documentation about the tasks.json format"version": "2.0.0","tasks": [ {"type": "shell","label": "cl.exe build active file","command": "cl.exe","args": ["/Zi","/EHsc","/utf-8","/Fe:","${fileDirname}\\${fileBasenameNoExtension}.exe","${file}","/DYNAMICBASE","C:\\lib\\opencv\\build\\x64\\vc15\\lib\\opencv_world450.lib" ],"problemMatcher": ["$msCompile"],"group": {"kind": "build","isDefault": true } } ]}
lauch.json
{"version": "0.2.0","configurations": [ {"name": "cl.exe build and debug active file","type": "cppvsdbg","request": "launch","program": "${fileDirname}\\${fileBasenameNoExtension}.exe","args": [],"stopAtEntry": false,"cwd": "${workspaceFolder}","environment": [],"externalConsole": false,"preLaunchTask": "cl.exe build active file" }, ]}
5.2 mingw64編譯器
c_cpp_properties.json
{"configurations": [ {"name": "win","includePath": ["${workspaceFolder}/**","D:\\lib\\opencv\\rebuild\\install\\include","D:\\lib\\opencv\\rebuild\\install\\include\\opencv2" ],"defines": ["_DEBUG", "UNICODE", "_UNICODE"],"compilerPath": "C:\\msys64\\mingw64\\bin\\gcc.exe","cStandard": "c11","cppStandard": "c++17","intelliSenseMode": "clang-x64" } ],"version": 4}
tasksjson
{// See https://go.microsoft.com/fwlink/?LinkId=733558// for the documentation about the tasks.json format"version": "2.0.0","tasks": [ {"type": "shell","label": "g++.exe build active file","command": "C:\\msys64\\mingw64\\bin\\g++.exe","args": ["-g", "-std=c++11", "${file}", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe","-I", "D:\\lib\\opencv\\rebuild\\install\\include","-I", "D:\\lib\\opencv\\rebuild\\install\\include\\opencv2","-L", "D:\\lib\\opencv\\rebuild\\install\\x64\\mingw\\lib","-l", "libopencv_core450","-l", "libopencv_imgproc450","-l", "libopencv_imgcodecs450","-l", "libopencv_video450","-l", "libopencv_ml450","-l", "libopencv_highgui450","-l", "libopencv_objdetect450","-l", "libopencv_flann450","-l", "libopencv_video450","-l", "libopencv_photo450","-l", "libopencv_videoio450" ],"options": {"cwd": "C:\\msys64\\mingw64\\bin" },"problemMatcher": ["$gcc" ],"group": {"kind": "build","isDefault": true } } ]}
lauch.json
{"version": "0.2.0","configurations": [ {"name": "(gdb) Launch","type": "cppdbg","request": "launch","program": "${fileDirname}\\${fileBasenameNoExtension}.exe","args": [],"stopAtEntry": true,"cwd": "${workspaceFolder}","environment": [],"externalConsole": true,"MIMode": "gdb","miDebuggerPath": "C:\\msys64\\mingw64\\bin\\gdb.exe","preLaunchTask": "g++.exe build active file","setupCommands": [ {"description": "Enable pretty-printing for gdb","text": "-enable-pretty-printing","ignoreFailures": true } ] }, ]}
參考文獻
[1] 再談OpenCV Contrib編譯與安裝[2] 將 VSCode 打造成 OpenCV 的 IDE(C++,window10 1803)[3] VSCODE 配置cl.exe編譯器[4] CL編譯器和LINK編譯器的使用方法[5] Configure VS Code for Microsoft C++[6] CMake+VS+opencv/opencv_contrib 環境配置[7] VisualStudio2019安裝配置OpenCV的C++環境