使用 MinGW 在 Windows 上安装 OpenCV C++
前言1. 安装配置Mingw-w642. 编译opencv2.1 利用cmake-gui编译2.2命令行编译 3. 编写程序,生成可执行文件3.1 g++ 生成 opencv程序3.2 cmake make 生成hellow3.3 cmake make生成opencv程序3.4 cmake opencv 自动查找 4 遇到的问题前言
OpenCV 在 python 中运行非常容易,因为 conda 确实处理了安装二进制文件并将 opencv python 绑定放在 python 路径中。
但是,在 C++ 中运行相同的内容是另一回事。由g++编译器编译的程序的上下文中引入正确的接口(hpp/头文件)和二进制文件(so/dll)。我将向您展示我是如何设置系统的。为了引入“g++”(GNU C++ 编译器),我们将使用 MinGW64。请记住,我们必须使用 64 位变体,因为 Mingw32 在 Windows 中不正确支持 posix 线程。ming64 二进制文件是使用 posix 实现构建的,该实现提供本机 posix,但与在 Windows 本机 API (win32) 上构建的内容相比,在 Windows 上编译时会更慢
先决条件:
Windows (10/8/7) 系统Mingw-w64 ,你可以从这里下载, 直接下载链接OpenCv 3+ ,官方github仓库Cmake ,从这里下载
编辑器和终端,不管你用什么。如果你愿意,你可以使用记事本😥。
1. 安装配置Mingw-w64
(1) 使用以下设置安装 MinGW-GW64
确保选择了posix。否则 OpenCV 安装将因无法找到互斥体错误而失败。这是 pthreads 库和规范的一部分。根据您的工作系统,架构可以是 x86(32/64 位机器)或 x86_64(64 位机器)。
(2) 单击下一步配置安装路径并让二进制文件安装。
(3)安装后确保在您的路径中包含MinGW bin文件夹。它应该在basePath/x86_64–8.1.0-posix***/mingw64/bin
里面
在此之后,只需通过打开终端并键入命令g++ — version
来测试安装。如果它说找不到命令。无法获取路径,路径设置不正确,重启终端或机器。
2. 编译opencv
2.1 利用cmake-gui编译
完成后安装Cmake。打开Cmake并执行以下操作
(1)选择源代码路径和build二进制文件路径。确保它们是分开的。
(2)完成后点击配置。将出现一个对话框,选择MinGW Makefiles
。这将确保 OpenCV 的新 makefile 与 mingw 兼容。
(3)单击完成。让它产生一些东西。在这个阶段,应该有一些选项列表可以勾选。我不需要特别注意任何这些选项。所以继续点击生成。匹配下面的输出,它应该说“配置完成”和“生成完成”
(4) 编译生成可执行文件
找到build的文件夹,本示例中C:\Program Files\opencv\build_yy
,在此文件夹中打开终端。点击命令“mingw32-make install”并祈祷它成功构建。
此时,在build文件夹中生成了install文件夹,可以将这个文件夹放置在任意路径配置环境变量,C:\Program Files\opencv\build_yy\install\x64\mingw\bin
必须包含在环境变量中。
2.2命令行编译
cd D:\opencv-4.5.3\build_mingw # 将命令行切换到build_mingw文件夹cmake -G "MinGW Makefiles" .. # 使用MinGW作为编译器make install -j16# make生成可执行文件
3. 编写程序,生成可执行文件
#include "opencv2/highgui/highgui.hpp"#include <iostream>using namespace cv;using namespace std;int main(int argc, char argv){string location = "C:\\Users\\yuyang2\\Pictures\\yy.jpg" ;Mat im = cv::imread(location ,1 );if (im.empty()){cout << "Cannot open image!" << endl;return -1;}std::cout << im.size;return 0;}
3.1 g++ 生成 opencv程序
在git-bash中打开终端:
yuyang2@CN0214005415W MINGW64 /c/yuyang2/桌面/test$ g++ -I"C:\Program Files\opencv\build_yy\install\include" -L"C:\Program Files\opencv\build_yy\install\x64\mingw\lib" -L"C:\Program Files\opencv\build_yy\install\x64\mingw\bin" opencvtry.cpp -lopencv_core453 -lopencv_highgui453 -lopencv_imgproc453 -lopencv_imgcodecs453 -o app
执行结果:
3.2 cmake make 生成hellow
预备:
在minggw-64的安装文件bin目录中,将mingw32-make.exe 复制一份重命名为make.exe,保存在当前文件夹。(为了直接使用make,不用mingw32-make,命令简洁)
目录结构:
test.cpp
#include <iostream>using namespace std;int main() {cout << "hello word cmake!!!" << endl;return 0;}
CMakeLists.txt
cmake_minimum_required(VERSION 3.0) project(test) set(SOURCE test.cpp) add_executable(${PROJECT_NAME} ${SOURCE})
执行过程
D:\helllo\build>cmake -G "Unix Makefiles" ../src-- Configuring done-- Generating done-- Build files have been written to: D:/helllo/buildD:\helllo\build>make[ 50%] Building CXX object CMakeFiles/test.dir/test.cpp.obj[100%] Linking CXX executable test.exe[100%] Built target testD:\helllo\build>test.exehello word cmake!!!
3.3 cmake make生成opencv程序
demo链接
提取码:yyyy
目录结构:
CMakeLists.txt
cmake_minimum_required(VERSION 3.0) # 设置cmake的最小版本project(yy VERSION 8.4.0) # 工程名称${PROJECT_NAME} (yy)# 工程版本${PROJECT_VERSION}(8.4.0)#打印调试信息MESSAGE(STATUS "Project Name: ${PROJECT_NAME}") #${PROJECT_NAME} yyMESSAGE(STATUS "Project Verson: ${PROJECT_VERSION}")#${PROJECT_VERSION} 8.4.0MESSAGE(STATUS "Project source dir: ${PROJECT_SOURCE_DIR}") # CmakeLists所在文件夹的绝对路径 MESSAGE(STATUS "Project build dir ${PROJECT_BINARY_DIR}") # build文件夹的绝对路径,包含build路径option(PRINT_VERSION "whether print version or not" ON) # 控制PRINT_VERSION是否在config.h中宏定义option(THIRD_TEST "whether use third patry function or not" ON)configure_file(config.h.in ../include/config.h)# 输入是config.h.in 输出config.h(默认在build文件夹)#获取代码,在项目中,将所有代码都放在src文件夹中AUX_SOURCE_DIRECTORY(src DIR_SRCS) # 查找在src路径下的所有源文件,放入DIR_SRCS变量中MESSAGE(STATUS "Src fie: ${DIR_SRCS}") # 打印 DIR_SRCS 中的所有源文件# 将头文件包含,如果头文件和CmakeList在同级目录则可以省略INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include) #设置可执行目标文件的输出目录, 并添加可执行文件SET(EXECUTABLE_OUTPUT_PATH ../bin) ADD_EXECUTABLE(${PROJECT_NAME} ${DIR_SRCS}) #设置opencv库文件路径file(GLOB OpenCV_LIBS libs/*.a)MESSAGE(STATUS "Opencv Libs: ${OpenCV_LIBS}")#添加opencv链接库TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS})#配置第三方库IF (THIRD_TEST)INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/third_party/third_test) #添加第三方库的头文件ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/third_party/third_test)#添加第三方库的CmakeListTARGET_LINK_LIBRARIES(${PROJECT_NAME} third_lib) #目标要连接third_lib库ENDIF()
main.cpp
#include <iostream>#include "Calculate.h"#include "config.h"#include "opencv2/highgui/highgui.hpp"#ifdef THIRD_TEST#include "third.h"#endifusing namespace std;using namespace cv;void test_opencv(){string location = "C:\\Users\\yuyang2\\Pictures\\yy.jpg" ; //图片路径Mat im = cv::imread(location ,1 );if (im.empty()){cout << "Cannot open image!" << endl;}std::cout <<"call opencv successed! , image size: "<< im.size;}int main() {#ifdef PRINT_VERSIONcout<<"Pro Version: "<<VERSION<<endl; //验证config.h.in 生成的config.h功能#endifCalculate calculate = Calculate();int result = calculate.Sum(1, 1);cout <<"call Calculate func: "<< "1+1=" << result << endl;#ifdef THIRD_TESTcout<<"call third_fun successed!"<<third_fun()<<endl;#endiftest_opencv();return 0;}
Calculate.cpp
#include "Calculate.h"int Calculate::Sum(int a, int b) {return a + b;}
Calculate.h
#pragma onceclass Calculate{public:int Sum(int a, int b);};
config.h.in
#define VERSION "@PROJECT_VERSION@" //等同于"${PROJECT_VERSION}"#cmakedefine PRINT_VERSION //只要在cmakeList中定义了PRINT_VERSION,就会生成到config.h中#cmakedefine THIRD_TEST
config.h(在cmake时由config.h,in生成)
#define VERSION "8.4.0" //等同于"8.4.0"#define PRINT_VERSION //只要在cmakeList中定义了PRINT_VERSION,就会生成到config.h中#define THIRD_TEST
third_party子模块中的内容
third_test(CMakeLists.txt)
cmake_minimum_required(VERSION 3.0)# 设置cmake的最小版本include_directories(${PROJECT_SOURCE_DIR})add_library(third_lib STATIC third.cpp) # 编译一个名为 third_lib的静态库,依赖于third.cpp
third_test(third.cpp)
#include "third.h"std::string third_fun(){return std::string("This is third party function.\n");}
third_test(third.h)
#include <string>std::string third_fun();
执行过程:
D:\test\build>cmake -G "MinGW Makefiles" ..-- The C compiler identification is GNU 8.1.0-- The CXX compiler identification is GNU 8.1.0-- Detecting C compiler ABI info-- Detecting C compiler ABI info - done-- Check for working C compiler: C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/gcc.exe - skipped-- Detecting C compile features-- Detecting C compile features - done-- Detecting CXX compiler ABI info-- Detecting CXX compiler ABI info - done-- Check for working CXX compiler: C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/g++.exe - skipped-- Detecting CXX compile features-- Detecting CXX compile features - done-- Project Name: yy-- Project Verson: 8.4.0-- Project source dir: D:/test-- Project build dir D:/test/build-- Src fie: src/Calculate.cpp;src/main.cpp-- Opencv Libs: D:/test/libs/libopencv_calib3d453.dll.a;D:/test/libs/libopencv_core453.dll.a;D:/test/libs/libopencv_dnn453.dll.a;D:/test/libs/libopencv_features2d453.dll.a;D:/test/libs/libopencv_flann453.dll.a;D:/test/libs/libopencv_gapi453.dll.a;D:/test/libs/libopencv_highgui453.dll.a;D:/test/libs/libopencv_imgcodecs453.dll.a;D:/test/libs/libopencv_imgproc453.dll.a;D:/test/libs/libopencv_ml453.dll.a;D:/test/libs/libopencv_objdetect453.dll.a;D:/test/libs/libopencv_photo453.dll.a;D:/test/libs/libopencv_stitching453.dll.a;D:/test/libs/libopencv_video453.dll.a;D:/test/libs/libopencv_videoio453.dll.a-- Configuring done-- Generating done-- Build files have been written to: D:/test/buildD:\test\build>make -j4Scanning dependencies of target third_lib[ 20%] Building CXX object third_party/third_test/CMakeFiles/third_lib.dir/third.cpp.obj[ 40%] Linking CXX static library libthird_lib.a[ 40%] Built target third_libScanning dependencies of target yy[ 60%] Building CXX object CMakeFiles/yy.dir/src/Calculate.cpp.obj[ 80%] Building CXX object CMakeFiles/yy.dir/src/main.cpp.obj[100%] Linking CXX executable ..\bin\yy.exe[100%] Built target yyD:\test\build>
运行结果:
D:\test\bin>yy.exePro Version: 8.4.0call Calculate func: 1+1=2call third_fun successed!This is third party function.call opencv successed! , image size: 1440 x 1080D:\test\bin>
3.4 cmake opencv 自动查找
1、删掉include文件夹里面的opencv
2、删掉libs里面的opencv链接库
3、修改CMakeLists.txt
cmake_minimum_required(VERSION 3.0) # 设置cmake的最小版本project(yy VERSION 8.4.0) # 工程名称${PROJECT_NAME} (yy)# 工程版本${PROJECT_VERSION}(8.4.0)#打印调试信息MESSAGE(STATUS "Project Name: ${PROJECT_NAME}") #${PROJECT_NAME} yyMESSAGE(STATUS "Project Verson: ${PROJECT_VERSION}")#${PROJECT_VERSION} 8.4.0MESSAGE(STATUS "Project source dir: ${PROJECT_SOURCE_DIR}") # CmakeLists所在文件夹的绝对路径 MESSAGE(STATUS "Project build dir ${PROJECT_BINARY_DIR}") # build文件夹的绝对路径,包含build路径option(PRINT_VERSION "whether print version or not" ON) # 控制PRINT_VERSION是否在config.h中宏定义option(THIRD_TEST "whether use third patry function or not" ON)configure_file(config.h.in ../include/config.h)# 输入是config.h.in 输出config.h(默认在build文件夹)#获取代码,在项目中,将所有代码都放在src文件夹中AUX_SOURCE_DIRECTORY(src DIR_SRCS) # 查找在src路径下的所有源文件,放入DIR_SRCS变量中MESSAGE(STATUS "Src fie: ${DIR_SRCS}") # 打印 DIR_SRCS 中的所有源文件# 将头文件包含,如果头文件和CmakeList在同级目录则可以省略INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include) #设置可执行目标文件的输出目录, 并添加可执行文件SET(EXECUTABLE_OUTPUT_PATH ../bin) ADD_EXECUTABLE(${PROJECT_NAME} ${DIR_SRCS}) #[[#设置opencv库文件路径(任何第三方库可以用这种方式)file(GLOB OpenCV_LIBS libs/*.a)MESSAGE(STATUS "Opencv Libs: ${OpenCV_LIBS}")]]#寻找OpenCV库set(OpenCV_DIR C:/Program\ Files/opencv/build_yy/install) #空格之前需要加 反斜杠FIND_PACKAGE(OpenCV REQUIRED)INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})#link_directories(${PROJECT_SOURCE_DIR}/libs)#添加动态连接库的路径#打印opencv调试信息MESSAGE(STATUS "OpenCV library status:")MESSAGE(STATUS " version: ${OpenCV_VERSION}")MESSAGE(STATUS " libraries: ${OpenCV_LIBS}")MESSAGE(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")#添加opencv链接库TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS})#配置第三方库IF (THIRD_TEST)INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/third_party/third_test) #添加第三方库的头文件ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/third_party/third_test)#添加第三方库的CmakeListTARGET_LINK_LIBRARIES(${PROJECT_NAME} third_lib) #目标要连接third_lib库ENDIF()
执行过程:
D:\test\build>cmake -G "MinGW Makefiles" ..-- Project Name: yy-- Project Verson: 8.4.0-- Project source dir: D:/test-- Project build dir D:/test/build-- Src fie: src/Calculate.cpp;src/main.cpp-- OpenCV ARCH: x64-- OpenCV RUNTIME: mingw-- OpenCV STATIC: OFF-- Found OpenCV: C:/Program Files/opencv/build_yy/install (found version "4.5.3")-- Found OpenCV 4.5.3 in C:/Program Files/opencv/build_yy/install/x64/mingw/lib-- You might need to add C:/Program\ Files/opencv/build_yy/install/x64/mingw/bin to your PATH to be able to run your applications.-- OpenCV library status:--version: 4.5.3--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: C:/Program Files/opencv/build_yy/install/include-- Configuring done-- Generating done-- Build files have been written to: D:/test/buildD:\test\build>makeScanning dependencies of target third_lib[ 20%] Building CXX object third_party/third_test/CMakeFiles/third_lib.dir/third.cpp.obj[ 40%] Linking CXX static library libthird_lib.a[ 40%] Built target third_libScanning dependencies of target yy[ 60%] Building CXX object CMakeFiles/yy.dir/src/Calculate.cpp.obj[ 80%] Building CXX object CMakeFiles/yy.dir/src/main.cpp.obj[100%] Linking CXX executable ..\bin\yy.exe[100%] Built target yy
运行结果:
D:\test\bin>yy.exePro Version: 8.4.0call Calculate func: 1+1=2call third_fun successed!This is third party function.call opencv successed! , image size: 1440 x 1080
4 遇到的问题
无法定位程序输入点 _ZNS……于动态链接库xxxxx上
解决:
把MinGW安装bin路径下的libstdc++-6.dll
这个库文件复制到C:\Windows\System32下就好了。