mingw 配置 opencv与vscode

mingw 配置 opencv

  • mingw的安装配置
    • mingw 的安装以及环境变量的添加
  • cmake安装
  • opencv 编译安装
    • opencv 下载安装
    • opencv 编译
    • g++ 手动编译
    • .exe 文件的运行
    • vscode配置
  • 其他库配置示例
    • eigen
      • eigen 编译
      • eigen 配置
    • raylib
      • 编译安装
      • vscode 配置

前几天想起来要用opencv-cpp了,本来我的编程环境全塞到wsl里面去了,但是wsl没法使用摄像头除非手动添加驱动编译安装,这就算了实在,没这个能力win上为了matlab之类的还是保留了一个mingw编译器,那就用mingw配置opencv得了
该教程并不是要求你严格按照我的步骤来进行配置,而是根据编译链接的原理,一点点讲一下该怎么配置,希望这个教程能对你有足够的帮助

mingw的安装配置

mingw 的安装以及环境变量的添加

tdm-gcc下载 我这里的mingw用的是tdm-gcc封装的64位版本
下载后可随便修改安装位置
之后记得添加环境变量

PathTo/TDM-GCC64/bin

mingw 配置 opencv与vscode_第1张图片
可选部分
根据所学的编译方式,除了gcc,g++,之外还有make工具,但是用在终端里面输入make -v 结果显示未找到make,该问题是是mingw编译器里的make 被命名为mingw32-make.exe 为了方便调用同时不会对编译器造成额外问题,复制mingw32-make.exe 将其另存为make.exe 这样就能在终端里面方便的调用make工具了

cmake安装

cmake 本人不怎么用,直接安装即可,因为win上一般用的是gui,所以无所谓添加环境变量
cmake 下载地址

opencv 编译安装

opencv 下载安装

opencv官网的官网比较操蛋,去opencv.org的source Forge页面下载会识别设备型号自动跳转到这个页面,但是这个玩意是MSVC编译的文件,mingw是无法使用的,只能采用编译安装,而OpenCV的源码挂在github下,下载源码可能需要科学上网之类的,不想各显神通我提供夸克网盘下载 这玩意不限速
链接在这

opencv 编译

解压opencv 文件,新建一个build(你可以随意命名)文件夹用于存放cmake构建文件,在cmake-gui工具中选定source文件夹与build文件夹,点击configure会自动检测你的cpp编译器环境,直接采用默认编译器,等一会后配置结束
可选部分
配置里面有个选项
BUILD_opencv_world,该选项会把所有其他.dll封装为一个libopencv_world460.dll,后续调用时只需要调用这么一个动态链接即可,该动态链接较大,但是不点也行,只是后面调用需要调用多个动态链接,每个链接都比较小,可以个人化定制。
mingw 配置 opencv与vscode_第2张图片
点击generate 即可生成build文件,耐心等一会
之后在你的build文件夹里打开终端,或者任意位置打开终端跳转到build文件里

# 如果你重命名了 mingw32-make
# 那么可以执行
# 否则用 mingw32-make 替代
make -j 8
# 这个 8 指的是你编译配置用的cpu核数量
make install

编译完成后的文件全部在 PathTo/build/install内,opencv的其他文件已经不再需要了
可选部分
为了方便管理,我将install 文件夹剪切出来重命名为opencv460,460为版本号

g++ 手动编译

在配置vscode 等编辑器之前,先用手动编译的方式来了解一下opencv的cpp文件编译器到底干啥了,测试文件如下

#include 
#include 

using namespace cv;
using namespace std;

int main()
{
    VideoCapture cap(0);
    Mat img;

    while (1)
    {
        cap >> img;
        if (img.empty())
            break;
        namedWindow("img", WINDOW_NORMAL);
        imshow("img", img);
        if (27 == waitKey(20))
            break;
    }

    return 0;
}

如果直接

g++ opencv_tst.cpp

结果报错找不到头文件
mingw 配置 opencv与vscode_第3张图片
实际上在g++等编译时如果需要添加标准库以外的库函数时需要额外指定,方法时

g++ opencv_tst.cpp -I PathTo/opencv/include

那么继续手动编译

g++ .\opencv_tst.cpp -I D:\ProEnv\opencv460\include\


结果是已经定义了opencv的头文件,但是没有具体的方法实现,依旧报错
对于非标准的cpp库文件编译链接时又需要一个额外参数

g++ -L PathTo\opencv\lib -l opencv_core -l *****

这里的 -I 是指定库文件夹位置,-l 是链接动态库或者静态库
-l opencv_core实际上是去链接 libopencv_core.a 或者libopencv_core.so文件

类型 linux win
静态链接 .a .lib
动态链接 .so .dll

但是mingw是在win上实现的g++编译器,所以很蛋疼的是目前编译出来的静态链接是.a文件
观察一下当前编译出来的全部文件
可以发现既有动态链接.dll文件(bin文件夹下)又有静态链接.a文件(lib文件夹下)
mingw 配置 opencv与vscode_第4张图片
mingw 配置 opencv与vscode_第5张图片
为了体验一下动态链接和静态链接有什么区别,两种链接方式都去试一试
链接那些文件呢?具体我其实不太清楚,如果有洁癖,一点点试一下,不想麻烦全连接了,或者勾选之前的选项,生成一个大的链接文件,只需要链接一个就可以了
那么链接时只需要链接opencv_modules core这两个链接
注意的是静态链接的名称是libopencv_core.dll.a 所以编译链接时需要

g++ .\opencv_tst.cpp -I D:\ProEnv\opencv460\include\ -L D:\ProEnv\opencv460\lib\ -l opencv_core460.dll -l opencv_video460.dll  -l opencv_highgui460.dll -l opencv_videoio460.dll -o tst1.exe

经过测试 成功编译 为 tst1.exe
为了深入研究一下静态链接和动态链接的区别,再用动态链接编译一下试一试

g++ .\opencv_tst.cpp -I D:\ProEnv\opencv460\include\ -L D:\ProEnv\opencv460\bin\ -l opencv_core460 -l opencv_video460  -l opencv_highgui460 -l opencv_videoio460 -o tst2.exe

成功将其编译为tst2.exe
对比一下编译后的文件
mingw 配置 opencv与vscode_第6张图片
明显两个文件大小相同,源文件也相同,几乎可以判定是同一个文件,运行这两个程序
结果都一样找不到.dll文件
mingw 配置 opencv与vscode_第7张图片

mingw 配置 opencv与vscode_第8张图片
理论上来说 链接静态库后库函数会被打包到.exe里,tst1.exe理论上可以独立运行,而动态库的则不会被打包进去,tst2.exe必须依赖.dll文件,对比一下静态文件和动态文件的体积,可以看到静态文件明显小于动态文件很多,个人理解是opencv偷了懒,将静态文件变成了对动态文件的查找

.exe 文件的运行

那么在自己电脑上如何去运行这些.exe文件呢,当前只需要让.exe找到.dll文件即可
两种方法

  1. 将 .dll文件与.exe文件放在同一目录下
  2. 让电脑能查询到.dll文件,即添加环境变量
    mingw 配置 opencv与vscode_第9张图片
    把程序给其他人用的时候推荐方法1,自己在电脑上玩的时候推荐方法2
    之后即可正常运行
    mingw 配置 opencv与vscode_第10张图片

vscode配置

对于tool级别的代码,最理想的情况就是一键F5 编译运行
更具刚才的手动编译的教程,可以对vscode 的配置进行修改以达到当前目的

  • 先是c_cpp_properties.json
    1. 需要添加对 opencv的支持
    1. includePath 中添加 “D:/ProEnv/opencv460/include”,
  • 对task.json的修改
    1. 在args中添加参数
    1. “-fdiagnostics-color=always”,
      “-g”,
      f i l e " , " − I " , " D : / P r o E n v / o p e n c v 460 / i n c l u d e " , " − L " , " D : / P r o E n v / o p e n c v 460 / b i n " , " − l " , " o p e n c v c a l i b 3 d 460 " , " − l " , " o p e n c v c o r e 460 " , " − l " , " o p e n c v d n n 460 " , " − l " , " o p e n c v f e a t u r e s 2 d 460 " , " − l " , " o p e n c v f l a n n 460 " , " − l " , " o p e n c v g a p i 460 " , " − l " , " o p e n c v h i g h g u i 460 " , " − l " , " o p e n c v i m g c o d e c s 460 " , " − l " , " o p e n c v i m g p r o c 460 " , " − l " , " o p e n c v m l 460 " , " − l " , " o p e n c v o b j d e t e c t 460 " , " − l " , " o p e n c v s t i t c h i n g 460 " , " − l " , " o p e n c v p h o t o 460 " , " − l " , " o p e n c v v i d e o 460 " , " − l " , " o p e n c v v i d e o i o 460 " , " − o " , " {file}", "-I", "D:/ProEnv/opencv460/include", "-L", "D:/ProEnv/opencv460/bin", "-l", "opencv_calib3d460", "-l", "opencv_core460", "-l", "opencv_dnn460", "-l", "opencv_features2d460", "-l", "opencv_flann460", "-l", "opencv_gapi460", "-l", "opencv_highgui460", "-l", "opencv_imgcodecs460", "-l", "opencv_imgproc460", "-l", "opencv_ml460", "-l", "opencv_objdetect460", "-l", "opencv_stitching460", "-l", "opencv_photo460", "-l", "opencv_video460", "-l", "opencv_videoio460", "-o", " file","I","D:/ProEnv/opencv460/include","L","D:/ProEnv/opencv460/bin","l","opencvcalib3d460","l","opencvcore460","l","opencvdnn460","l","opencvfeatures2d460","l","opencvflann460","l","opencvgapi460","l","opencvhighgui460","l","opencvimgcodecs460","l","opencvimgproc460","l","opencvml460","l","opencvobjdetect460","l","opencvstitching460","l","opencvphoto460","l","opencvvideo460","l","opencvvideoio460","o","{fileBasenameNoExtension}.exe”

其他库配置示例

根据前面的 opencv配置原理再来配置一下其他的库,这里选图形库raylib和数值计算库eigen

eigen

eigen 是一个通用数值计算库,体积小,全平台通用

eigen 编译

1. 下载安装
2. cmake build
3. 在build 文件下 make install 会编译安装到C:/program file(x86)/Eigen3
4. 注意如果权限不足需要先创建C:/program file(x86)/Eigen3

eigen 配置

根据前面的教程,如果为了方便eigen版本管理,可以直接把C:/program file(x86)/Eigen3/eigen里面的所有文件剪切出来放到一个特定的地方,在c_cpp_properties.json 添加头文件路径。eigen有个特点,他只有头文件,没有任何静态或者动态链接,编译时只需要g++ tst.cpp -I PathTo/Eigen/include 即可。
但是有没有更简便的方法? 不修改c_cpp_properties.json, 也不要-I PathTo/Eigen/include ?
当然可以,tmdgcc的编译器内置头文件、库文件也有默认位置,只需要将eigen的头文件丢到PathTo/TDM-GCC64/include 中即可
注意我们通常引用的头文件如下

#include 
#include 
using Eigen::MatrixXd;
using Eigen::VectorXd;

int main()
{
    MatrixXd m = MatrixXd::Random(3,3);
    m = (m + MatrixXd::Constant(3,3,1.2)) * 50;
    std::cout << "m =" << std::endl << m << std::endl;
    VectorXd v(3);
    v << 1, 2, 3;
    std::cout << "m * v =" << std::endl << m * v << std::endl;
}

所有应该是把C:/program file(x86)/Eigen3/include/eigen3下的两个目录Eigenunsupported copy到D:\ProEnv\TDM-GCC64\include
后续即可直接g++ 编译该程序
mingw 配置 opencv与vscode_第11张图片

raylib

raylib 是通用的c++ 图像库全平台通用,你可以去raylib官网 看看教程,下载是免费的

编译安装

  1. 下载后是个 .exe文件 直接执行,他会把raylib解压到C:/raylib 下
  2. 到 C:/raylib/raylib/src 目录下打开终端,执行make 即可,或者mingw32-make
  3. 真正有用的东西只有raylib.hlibraylib.a 这两个文件
  4. 编译时需要链接 -l raylib -l opengl32 -l gdi32 -l winmm
  5. 如果想对raylib进行有效管理,可以建立文件夹raylib,文件树如下
    mingw 配置 opencv与vscode_第12张图片
    对于raylib我没有建立专门文件夹,而是把libraylib.a 丢到 PathTo\TDM-GCC64\lib
    raylib.h 丢到 PathTo\TDM-GCC\include
    这两处是TDM-GCC64下可以直接查询的文件夹,所以不需要-I-L 指令

vscode 配置

根据之前的教程,同样可以修改c_cpp_properties 和task.json文件
但是如果该文件夹下有时候想用opencv,有时候想用raylib难道还要重新打开文件夹吗,其实可以在task.json中和launch.json中配置多个任务,这样在调试中就有多个选项,依旧可以一键运行这里附上我的配置

c_cpp_properties.json

{
  "configurations": [
      {
          "name": "Win32",
          "includePath": [
              "${workspaceFolder}/**",
              "D:/ProEnv/TDM-GCC64/lib/gcc/x86_64-w64-mingw32/10.3.0/include/c++",
              "D:/ProEnv/TDM-GCC64/lib/gcc/x86_64-w64-mingw32/10.3.0/include/c++/tr1",
              "D:/ProEnv/TDM-GCC64/lib/gcc/x86_64-w64-mingw32/10.3.0/include/c++/x86_64-w64-mingw32",
			  "D:/ProEnv/opencv460/include",
			  "D:/ProEnv/opencv460/include/opencv2"
          ],
          "defines": [
              "_DEBUG",
              "UNICODE",
              "_UNICODE"
          ],
          "windowsSdkVersion": "10.0.17763.0",
          "compilerPath": "D:/ProEnv/TDM-GCC64/bin/g++.exe",
          "cStandard": "c11",
          "cppStandard": "c++11",
          "intelliSenseMode": "gcc-x64"
      }
  ],
  "version": 4
}

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "opencv gdb",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "miDebuggerPath": "D:/ProEnv/TDM-GCC64/bin/gdb.exe",
            "preLaunchTask": "opencv g++",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        },
        {
            "name": "raylib gdb",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "D:/ProEnv/TDM-GCC64/bin",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "D:\\ProEnv\\TDM-GCC64\\bin\\gdb.exe",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "raylib g++"
        },
		{
            "name": "ege gdb",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "D:/ProEnv/TDM-GCC64/bin",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "D:\\ProEnv\\TDM-GCC64\\bin\\gdb.exe",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "ege g++"
        }
    ]
}

setting.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch", 
            "type": "cppdbg", 
            "request": "launch", 
            "program": "${fileDirname}/${fileBasenameNoExtension}.exe", 
            "args": [],
            "stopAtEntry": true,
			"editor.minimap.enabled": true,
    		"C_Cpp.autocomplete": "Default",
    		"[cpp]": {
        		"editor.quickSuggestions": true
    		},
    		"[c]": {
     		   "editor.quickSuggestions": true
    		},
            "cwd": "${workspaceFolder}", 
            "environment": [], 
            "externalConsole": true, 
            "internalConsoleOptions": true, 
            "MIMode": "gdb", 
            "miDebuggerPath": "gdb.exe", 
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": false
                }
            ],
            "preLaunchTask": "Compile" 
        }
	],
	"cmake.configureOnOpen": false
}

task.json

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "opencv g++",
            "type": "cppbuild",
            "command": "g++",
            "args": [
				"-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-I",
                "D:/ProEnv/opencv460/include",
                "-L",
                "D:/ProEnv/opencv460/bin",
                "-l",
                "opencv_calib3d460",
                "-l",
                "opencv_core460",
                "-l",
                "opencv_dnn460",
                "-l",
                "opencv_features2d460",
                "-l",
                "opencv_flann460",
                "-l",
                "opencv_gapi460",
                "-l",
                "opencv_highgui460",
                "-l",
                "opencv_imgcodecs460",
                "-l",
                "opencv_imgproc460",
                "-l",
                "opencv_ml460",
                "-l",
                "opencv_objdetect460",
                "-l",
                "opencv_stitching460",
                "-l",
                "opencv_photo460",
                "-l",
                "opencv_video460",
                "-l",
                "opencv_videoio460",
                "-o",
                "${fileBasenameNoExtension}.exe"
            ],
            "problemMatcher": [],
            "group": {
                "kind": "test",
                "isDefault": true
            }
        },
        {
            "type": "cppbuild",
            "label": "raylib g++",
            "command": "D:/ProEnv/TDM-GCC64/bin/g++.exe",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
				"-l",
				"raylib",
				"-l",
				"opengl32",
				"-l",
				"gdi32", 
				"-l",
				"winmm",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "D:/ProEnv/TDM-GCC64/bin"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": "build",
            "detail": "调试器生成的任务。"
        },
		{
            "type": "cppbuild",
            "label": "ege g++",
            "command": "D:/ProEnv/TDM-GCC64/bin/g++.exe",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
				"-l",
				"graphics", 
				"-l",
				"uuid", 
				"-l",
				"msimg32", 
				"-l",
				"gdi32", 
				"-l",
				"imm32", 
				"-l",
				"ole32", 
				"-l",
				"oleaut32", 
				"-l",
				"winmm", 
				"-l",
				"gdiplus",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "D:/ProEnv/TDM-GCC64/bin"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": "build",
            "detail": "调试器生成的任务。"
        }
    ]
}

需要关注的是launch.json 中的 PreTask 的值一定与你的task.json的 label 的值对应
每个task.json中的args为编译时的参数
launch.json中的type必须为’cppdbg’ 这是vscode cpp 插件决定的
复制粘贴后有3个不同调试任务
mingw 配置 opencv与vscode_第13张图片
里面的ege 是我自己安装了ege图形库,有兴趣可以自己安装验证一下

你可能感兴趣的:(opencv,vscode,计算机视觉)