Windows平臺使用CMake+MinGW64編譯OpenCV

Tamap發表於2024-05-10

Windows平臺使用CMake+MinGW64編譯OpenCV

(注:2年前寫的筆記, 可能有些地方過時了)

目錄
  • Windows平臺使用CMake+MinGW64編譯OpenCV
  • 1.安裝及配置環境
    • 1.1 MinGW-w64
    • 1.2 CMake
    • 1.3 OpenCV原始碼
  • 2.CMake配置及生成
    • 2.1 新建目錄
    • 2.2 CMake-GUI
    • 2.3 編譯配置
    • 2.4 生成
    • 2.5 Make編譯和安裝
  • 3.配置CMake編譯環境
    • 3.1 CMAKE_PREFIX_PATH配置
    • 3.2 在CMake中引用
    • 3.3 dll動態連結引用
        • 方法一: 加入PATH環境變數
        • 方法二: 直接複製.dll到當前可執行檔案所在資料夾
  • 4.測試例程
    • 4.1 程式碼
    • 4.2 CMake配置和編譯
      • 4.2.1 配置
        • 編譯報錯:找不到OpenCV
      • 4.2.2 編譯
      • 4.2.3 執行
        • 執行報錯:找不到dll

1.安裝及配置環境

1.1 MinGW-w64

編譯器使用MinGW-w64:MinGW-w64 - for 32 and 64 bit Windows

注意:安裝MinGW-w64時,選擇posix介面的Threads,否則編譯OpenCV時會一直報錯(典型現象是前期會報找不到mutex的錯誤)

MinGW安裝

具體安裝細節可以參考文章:MinGW-w64安裝教程——著名C/C++編譯器GCC的Windows版本

將含有gcc.exe的bin資料夾配置環境變數PATH,如

D:\xxx\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin

測試,開啟CMD,輸入

gcc --version

另外,如果裝有QT可以選擇使用QT自帶的編譯器,也是可以進行編譯的

1.2 CMake

下載:Download | CMake

安裝中會詢問是否將CMake新增到PATH環境變數,為了方便可以選擇Add CMake to the system PATH for all users

測試,開啟CMD,輸入

cmake --version

1.3 OpenCV原始碼

從GitHub下載OpenCV原始碼,進入網頁https://github.com/opencv/opencv,點選Code▼-Download ZIP下載zip壓縮包

如果有安裝git,可以cd到合適的新目錄下,然後直接使用git clone https://github.com/opencv/opencv.git命令下載原始碼

由於github下載較慢,這裡fork了一份原始碼(2021-11-8)到gitee以供下載:https://gitee.com/chntamap/opencv

完成後資料夾內容如下:

opencv原始碼

2.CMake配置及生成

2.1 新建目錄

在opencv資料夾外新建目錄build和install,分別用於放生成檔案及編譯完成的檔案

總目錄

2.2 CMake-GUI

開啟CMake(cmake-gui):

Where is the source code:選擇opencv原始碼資料夾

Where to build thr binaries:選擇build資料夾

CMake配置1

點選Configure進行配置,彈出的視窗中下拉選擇MinGW Makefiles,單選框直接選擇Use default native compilers,如果前面配置OK的話,CMake應該可以自動檢測到編譯器所在位置的

CMake預設編譯器

如果CMake在Configure過程中報找不到編譯器的錯誤,可以選擇第二個單選框Specify native compilers手動選擇編譯器路徑

CMake手動選擇編譯器

2.3 編譯配置

編譯配置參考了網上幾篇文章,普遍配置為:

ENABLE_PRECOMPILED_HEADERS:不勾選
WITH_IPP:不勾選
WITH_OPENGL:勾選

其中,ENABLE_PRECOMPILED_HEADERSWITH_IPP在這邊的配置中預設沒有勾選因此無需操作

其他文章普遍勾選了ENABLE_CXX11,但這邊找不到相關配置,因此忽略這一項

如果有安裝QT,可以選擇勾選WITH_QT,目前環境沒有安裝QT,選擇不勾選

另外,CMAKE_INSTALL_PREFIX可以配置install路徑, 這裡將其配置為了剛剛新建的install資料夾,這個資料夾將放置最終的編譯結果

注:更建議使用opencv加版本號的形式替代install資料夾, 如opencv-4.5.4資料夾, 這樣可以相容不同版本的庫, 這裡為了方便, 直接使用install資料夾

其他的配置根據需要或碰到的問題,再進一步具體調整即可

2.4 生成

點選Generate,等待生成

這一步會下載相關的檔案,由於網路環境的影響,可能會有部分檔案下載失敗報錯(如opencv_videoio_ffmpeg.dll等)

下載失敗的檔案可在build目錄的日誌檔案CMakeDownloadLog.txt檢視,檔案中寫明瞭下載連結及需要放置的路徑,自行找另外的方法下載

這裡提供了部分自己下載的檔案,取出需要的檔案放置到build/3rdparty對應位置即可

3rdparty_win.zip-藍奏雲

完成後再次點選Generate

2.5 Make編譯和安裝

開啟cmd,使用cd命令進入build目錄輸入:

mingw32-make

如需要加速編譯則輸入

mingw32-make -j 8

其中-j 8引數用於加速編譯,數量8根據CPU核心決定

編譯完成後,輸入命令完成最後的安裝步驟:

mingw32-make install

如果配置了CMAKE_INSTALL_PREFIX, 那麼OpenCV將會安裝在指定的位置, 比如我這裡設定了install資料夾, 記住install資料夾的位置, 後面呼叫該庫時需要用到

此處沒有對環境變數進行配置, 會導致編譯時找不到原始檔, 執行時也找不到動態連結庫
先透過測試例程進行問題說明, 再針對問題配置環境

3.配置CMake編譯環境

編譯好OpenCV庫後, 如果沒有配置環境, 則系統將找不到庫導致編譯報錯和執行報錯;
下面是兩種配置方法, 各有優劣:

  1. 將OpenCV配置到系統環境變數中, 這樣所有用到OpenCV的工程都將引用該庫
    1. 優點: 簡單, 只需配置一次即可
  2. 在配置工程時指定OpenCV的路徑,
    1. 優點: 不同的工程可以靈活指定不同的OpenCV庫

3.1 CMAKE_PREFIX_PATH配置

這裡我們僅介紹配置CMAKE_PREFIX_PATH環境變數的方法, 來使得CMake可以查詢倒OpenCV庫:

  1. 開啟windows環境變數設定介面(此電腦右鍵-屬性-高階系統設定-環境變數)
  2. 找到環境變數CMAKE_PREFIX_PATH, 找不到則新建
  3. 將安裝目錄下的x64\mingw\lib加入到環境變數CMAKE_PREFIX_PATH
    1. 這裡我的安裝路徑是F:\Project\OpenCV_Src\install
    2. 我的環境是x64, 編譯器是mingw
    3. 因此最終要設定到環境變數中的值為:F:\Project\OpenCV_Src\install\x64\mingw\lib;
    4. 注:這裡最後帶個分號可以使系統識別為列表, 方便新增其他CMake庫或其他版本的OpenCV庫

3.2 在CMake中引用

要在工程中呼叫OpenCV, 則需要在CMakeLists.txt中加入以下兩個語句, 分別用於查詢和連結:

find_package(OpenCV REQUIRED)
target_link_libraries(opencv_example PRIVATE ${OpenCV_LIBS})

如果需要指定OpenCV的版本, 則可以加入版本號, 如:

find_package(OpenCV 4.5.4 REQUIRED)

3.3 dll動態連結引用

執行呼叫了opencv的應用程式時, 可能會因為引用了dll動態連結庫, 但系統找不到檔案而報錯

動態連結庫檔案位於install目錄下的x64\mingw\bin資料夾, 例如我的路徑是: F:\Project\OpenCV_Src\install\x64\mingw\bin

因此有兩種方法:

方法一: 加入PATH環境變數

  1. 點選PATH環境變數, 然後點編輯, 再點新建
  2. 將上述bin路徑加入到PATH環境變數中
  3. 注意不要動到其他路徑, 否則系統可能會出問題

方法二: 直接複製.dll到當前可執行檔案所在資料夾

  1. 找到正確的bin資料夾, 也就是上述.dll所在資料夾
  2. 將所需的.dll檔案複製到可執行檔案(.exe)同目錄下
  3. 更建議此方法, 反正要將該程式發給別人的話, 也得打包.dll檔案, 否則別人也會報此錯誤

4.測試例程

4.1 程式碼

在任意位置新建一空資料夾作為測試用的工程, 並編寫main.cppCMakeLists.txt檔案:

main.cpp: 顯示一張純藍色的200*200的圖片

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
    cout << "Built with OpenCV " << CV_VERSION << endl;

    Mat img = Mat(200, 200, CV_8UC3, Scalar(255, 0, 0));
    imshow("Source", img);

    waitKey(0);
    return 0;
}

CMakeLists.txt: 將main.cpp加入工程; 然後查詢並連結opencv庫

# cmake needs this line
cmake_minimum_required(VERSION 3.1)

# Define project name
project(opencv_example_project)

# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
find_package(OpenCV REQUIRED)

# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS "    config: ${OpenCV_DIR}")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")

# Declare the executable target built from your sources
add_executable(opencv_example main.cpp)

# Link your application with OpenCV libraries
target_link_libraries(opencv_example PRIVATE ${OpenCV_LIBS})
# target_link_libraries(opencv_example PRIVATE strmiids)
# target_link_libraries(opencv_example PRIVATE quartz)

4.2 CMake配置和編譯

4.2.1 配置

開啟CMake GUI, 原始檔位置: 選擇當前資料夾, 編譯位置: 選擇當前資料夾下新建的build資料夾

例程CMakeGUI配置1

點選Configure按鈕, 在彈出的對話方塊中選擇MinGW編譯器, 操作與## 2.2 CMake-GUI相同, 可跳回去參考

點Finish, 將提示以下資訊, 表示配置成功:

Found OpenCV: F:/Project/OpenCV_Src/install (found version "4.5.4")
OpenCV library status:
config: F:/Project/OpenCV_Src/install/x64/mingw/lib
version: 4.5.4
libraries: opencv_calib3d;opencv_core;opencv_dnn;opencv_features2d;opencv_flann;opencv_gapi;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_ml;opencv_objdetect;opencv_photo;opencv_stitching;opencv_video;opencv_videoio
include path: F:/Project/OpenCV_Src/install/include
Configuring done

和上述編譯OpenCV原始碼的操作相似, 再點選Generate即可生成Makefile工程到build資料夾, 提示:

Generating done

編譯報錯:找不到OpenCV

報錯資訊如下:

CMake Error at CMakeLists.txt:10 (find_package):
By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "OpenCV", but
CMake did not find one.

Could not find a package configuration file provided by "OpenCV" with any
of the following names:

OpenCVConfig.cmake
opencv-config.cmake

Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set
"OpenCV_DIR" to a directory containing one of the above files. If "OpenCV"
provides a separate development package or SDK, be sure it has been
installed.

意思是找不到opencv, 需要我們在環境變數或配置中提供OpenCV庫所在的位置, 參考## 3.1 CMAKE_PREFIX_PATH配置 進行環境配置, 並重啟CMakeGUI以重新整理程式的環境變數

4.2.2 編譯

開啟命令列工具, 並cd到build資料夾下, 然後執行make: mingw32-make, 輸出如下:

F:\Project\OpenCV_Src\project\test\build>mingw32-make
[ 50%] Building CXX object CMakeFiles/opencv_example.dir/main.cpp.obj
[100%] Linking CXX executable opencv_example.exe
[100%] Built target opencv_example

表示編譯成功

4.2.3 執行

隨後在build資料夾中, 雙擊執行程式: opencv_example.exe

如果操作無誤, 則可以看到顯示如下:

執行成功

執行報錯:找不到dll

如果彈出如下錯誤:

執行報錯1

說明系統找不到.dll動態連結庫檔案, 參考: dll動態連結引用

執行exe, 看看是否還會報錯, 將新報錯的檔案補上, 直到程式正常執行(或者簡單粗暴一點, 將所有dll複製過去就完事), 針對例程程式的需要, 此處我複製了四個檔案:

  • libopencv_imgproc454.dll
  • libopencv_core454.dll
  • libopencv_highgui454.dll
  • libopencv_imgcodecs454.dll

相關文章