inGW(Minamalist GNU For Windows)是精簡的C/C++編譯器,它將經典的開源C語言編譯器GCC移植到Windows下,且包含Win32API。因此可將C語言編譯、生成Windows下的可執行程序,可以直接在Windows下運行。
標準的MinGW需要連接網絡在線安裝。
minGW的安裝,對于我等編程愛好者而言,也不是件容易的事。這不,利用VScode進行調試時,提示找不到gdb.exe(調試器)。網上查了查,才發現,按照標準流程下載、安裝minGW是不帶gdb.exe的! 坑真多啊!通過minGWInstaller圖形化界面安裝了半天,提示安裝成功了,但在c:\minGW\bin還是沒發現gdb.exe的蹤影,氣得我把minGW目錄刪掉了。 我冷靜下來,再次從官網下載安裝,卻遇到下載安裝后只安裝到一半,文件下載進度完成100%,但continue鍵是灰的,提示安裝出現錯誤,只能點擊quit,退出安裝。到C:\minGW\bin目錄下一看,僅僅只看到一個文件: mingw-get.exe, 真的是一口老血差點吐出來!
再次借助網上教程,向大咖學習:
我按照這個步驟,安裝過程:
圖1 手動安裝 gcc : mingw-get install gcc
圖2 手動安裝 gcc (續)
轉到C:\minGW\bin目錄下,發現安裝了很多文件:
圖3 minGW\bin目錄下安裝的文件
運行gcc.exe成功:
圖4 gcc安裝成功
使用以下命令,繼續安裝g++和gdb
mingw-get install g++
mingw-get install gdb
安裝過程開始后,下載文件,解壓,安裝,但都出現了部分文件不能安裝的錯誤,估計跟我第一次直接刪除安裝目錄有關:
圖 5 安裝g++和gdb時部分文件安裝不成功
查看目錄:
圖6 gdb仍然未能安裝成功
如果沒有特殊要求,在Windows系統下可以直接使用OpenCV的預編譯版本。在github的opencv項目release中選擇相應release版本即可。然而,由于版權原因,預編譯的opencv并沒有包含諸多第三方工具,因此,如果要使用一些第三方工具,或者要在linux系統下使用openCV的話,還需要自己從源碼進行編譯。
OpenCV可以從官網下載,本文使用openCV 4.50版本。下載完成后點擊安裝,該安裝包實際上是指打包的壓縮文件,選擇路徑解壓即可,本文將opencv解壓安裝到D:\lib路徑下,解壓后的opencv所在目錄為D:\lib\opencv。在opencv目錄下,source為源文件的文件夾,build為編譯文件的文件夾,包括了VC14和VC15的預編譯文件。如果要直接使用編譯好的opencv,引用build目錄下的文件即可。本文在opencv目錄下新建一個rebuild目錄,用來保存自行編譯后的文件。
要安裝第三方工具,需要從github上下載相應的opencv_contrib版本,這里從opencv-contrib倉庫的release版本中下載opencv_contrib-4.5.0版本.將解壓后的opencv_contrib-4.5.0文件夾直接放到opencv的source目錄下,以備后續編譯使用。
在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...。
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-toolchain
pacman -S mingw64/mingw-w64-x86_64-make
#上述命令包含了以下3個包,因此下面3個不需要再另外安裝
pacman -S mingw64/mingw-w64-x86_64-gcc
pacman -S mingw64/mingw-w64-x86_64-g++
pacman -S mingw64/mingw-w64-x86_64-gdb
#安裝32位工具
pacman -S mingw32/mingw-w64-i686-toolchain
pacman -S mingw32/mingw-w64-i686-make
pacman -S mingw32/mingw-w64-i686-gcc
pacman -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:\msys64
C:\msys64\mingw64\bin
C:\msys64\mingw64\x86_64-w64-mingw32\bin
CMake 是一個開源的跨平臺工具系列,旨在構建、測試和打包軟件。在CMaje官網下載對應的編譯工具進行安裝,并將安裝路徑寫入環境變量。在命令行輸入cmake --version可以看到cmake版本信息。安裝完成后,也可以通過CMake自帶的圖形界面Cmake GUI進行文件編譯。相比命令行而言,操作更簡單。
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 -U
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
#安裝numpy
pip 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,需要使用完整的路徑加程序名稱。
如果要編譯Java環境相關內容,還需要安裝和配置JDK和Apache-ant,下載JDK的windows版本并使用默認設置安裝,下載ant的可執行文件binary版本,并解壓縮,本文解壓縮到D:\lib\apache-ant-1.10.9目錄下,并將該目錄和bin子目錄添加到環境變量中。在命令行中輸入java和ant可以看到java命令行幫助和ant編譯出錯(因為沒有xml文件)信息,即說明安裝完成。如果不需要安裝Java相關內容,則不需要安裝上述工具。
打開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工具等情況造成的。在這里需要調整部分參數配置,或者添加、修改參數。
需要調整的配置包括:
配置完成后再點擊Configure按鈕,然后點擊Generate按鈕。
注意:從命令行進入D:\lib\opencv\rebuild目錄,輸入mingw32-make install -j16進行編譯。注意j后面的數字表示編譯線程數,一般為4且不能超過計算機支持的最大線程數。在多線程編譯的情況下,有時錯誤信息會被覆蓋掉,從而無法及時找到編譯出錯的信息,這種時候可以通過mingw32-make install -j1將編譯線程數改為1,以便在編譯出錯時及時停止編譯,以處理出錯信息。
在Visual Studio中使用OpenCV,可以直接使用預編譯版本下的VC14、VC15版本,也可以參照上述步驟重新編譯。部分Visual Studio與Visual C++版本對應關系如下表,在實踐中,VC15的編譯版本也可以在Visual Studio 2019中使用:
Visual Studio 版本Visual C++ 版本VS 6.0VC 6.0VS 2013VC 12VS 2015VC 14VS 2017VC 15VS 2019VC 16
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char* argv[]) {
const char* imagename="D:\\Pictures\\Camera Roll\\digitalmeter1.jpg";//此處為你自己的圖片路徑
//從文件中讀入圖像
Mat img=imread(imagename, 1);
//如果讀入圖像失敗
if (img.empty()) {
fprintf(stderr, "Can not load image %s\n", imagename);
return -1;
}
//顯示圖像
imshow("image", img);
//此函數等待按鍵,按鍵盤任意鍵就返回
waitKey();
return 0;
}
編譯并運行項目,如果沒有錯誤,則可以顯示圖像內容。
要在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進行編譯時,編譯選項略有不同。兩種不同編譯工具下的文件內容分別如下:
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"
},
]
}
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
}
]
},
]
}