MinGW版本:8.1.0 x86_64-posix-seh
Opencv版本:3.4.1(Source版)
Cmake:3.24.1
参考上一篇文章:VSCode笔记01-VSCode+CMake+MinGW配置: VSCode下进行C/C++的编译、运行和调试
一步一步配置完后,就可以继续本文章接着往下走了。
首先,为什么要下载源码?因为官网没有基于 MinGW 编译的版本,所以我们只能来自己下载源码进行编译,自力更生。
官网下载Opencv源码,我下载的 Opencv3.4.1。
最开始我下载了这个 Windows 版,用目录里面的 source 文件夹来编译,也是很多教程使用的,但是我编译会报各种错,后来直接换成了 Source 版,没有问题。
将下载的源码解压到 C:/Opencv_341/
目录下,并在该目录下创建build目录,目录结构如下。
为了简便,我们采用命令行的形式来操作,其实与其它使用 cmake-gui 的方式是一样的。
管理员权限打开cmd,进入 C:/Opencv/build
目录,输入如下命令。
cmake -G "MinGW Makefiles" -D CPU_=AVX2 ../
-G "MinGW Makefiles"
-指定 MinGW Makefiles 生成器,就是生成makefile,可以通过 cmake --help
查看生成器。
../
-上一层路径,也就是源码所在相对路径。
另外提下这个参数-D OPENCV_ENABLE_ALLOCATOR_STATS=OFF
-很多较新版本会有 “vs_version.rc.obj gcc: error: long: No such file or directory” 的问题,我用的 Opencv3.4.1,没有这个问题,有问题的可以把这个加上cmake -G "MinGW Makefiles" -D OPENCV_ENABLE_ALLOCATOR_STATS=OFF ../
。
耐心等待一段时间,生成 makefile 文件,完成。
生成makefile后,我们来对源码进行编译。
在cmd继续输入命令。
mingw32-make.exe
mingw32-make.exe
会根据生成的makefile 来对源码进行编译,过程很漫长。
这么漫长的编译过程,显然不会很顺利。。。
遇到了很多问题,而且每次问题都还不一样,经过一番查找,更换了MinGW版本,将 Win32 换成posix 版本。参考链接 MinGW Error1和MinGW Error2。
这里要说明一下,1.1 的链接文章中 MinGW 版本已经换成了 posix 版本,因为之前没有问题,编译Opencv的时候才出现的的问题,所以又翻回去修改了1.1的链接文章的 MinGW 版本。
这里附上 MinGW下载链接,我下载的8.1.0 x86_64-posix-seh。
重新安装了MinGW并添加环境变量后,再次进行上述步骤操作,这次编译很顺利,连 warning
也大大减少了。。。
再次执行mingw32-make.exe
, 会根据生成的makefile 来对源码进行编译,过程很漫长,等待就好。
mingw32-make -j n
会配置多线程编译,n
为线程数量。但是强烈不建议使用,一开始我直接使用了mingw32-make -j 16
,编译快很多,但是出错的时候报的问题,没有办法定位很细,而且也搜不到解决办法,而且线程数更换后报错的地方还不一样了,过程中出现了很多问题,最后直接使用了mingw32-make.exe
,单线程,反正也就这么一次,慢点就慢点吧,至少报错能定位问题。
过程很顺利只报了一个错,invalid register for .seh_savexmm
,很细节,所以很顺利的也搜到了解决办法,参考链接invalid register for .seh_savexmm,就是查找自己的CPU 应该设置的值,设置好就行了,我的是 AVX2。也可以在 1.3 的命令中添加-D CPU_DISPATCH=OFF
,但是对于强迫症的我是接受不了的,把命令修改为了cmake -G "MinGW Makefiles" -D CPU_DISPATCH=AVX2 ../
,重新生成makefile,如果是cmake-gui的话直接在界面选择 AVX2 就行了。
其实过程中还尝试了切换 cmake 版本呢,从3.24.1
切换到了3.13.0
,后来编译成功后又用3.24.1
尝试了一下,也没有问题,应该跟 cmake 版本关系不大。
最终,编译成功。
之后,开始装载Opencv。cmd 继续输入
mingw32-make install
进行安装,没有问题,慢慢等待,出现下面的信息,装载完成。
C:\Opencv_341\build\install\x64\mingw\bin
添加到环境变量 Path。OpenCV_DIR
,变量值C:\Opencv_341\build\install
,添加这个OpenCV_DIR
的原因主要是为了配合find_package
的使用。创建一个空目录,在此目录基础上创建空目录和空文件,如下。
│CMakeLists.txt
│main.cpp
├─bin
├─build
├─include
│ my_cam.h
└─src
my_cam.cpp
之后,创建.vscode目录,并在该目录下创建三个空文件,c_cpp_properties.json,launch.json,tasks.json,最终VSCode目录结构如下。
接下来编写源程序,可以直接复制粘贴。
在 VSCode 中双击打开 main.cpp,复制粘贴。
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"
#include
#include "my_cam.h"
using namespace cv;
using namespace std;
int main()
{
cout << "Built with OpenCV " << CV_VERSION << endl;
Camera mycam;
Mat image;
VideoCapture capture;
capture.open(0);
if(capture.isOpened())
{
cout << "Capture is opened" << endl;
for(;;)
{
capture >> image;
if(image.empty())
break;
mycam.drawText(image);
imshow("Sample", image);
if(waitKey(10) >= 0)
break;
}
}
else
{
cout << "No capture" << endl;
image = Mat::zeros(480, 640, CV_8UC1);
mycam.drawText(image);
imshow("Sample", image);
waitKey(0);
}
return 0;
}
双击打开 my_cam.cpp,复制粘贴。
#include "my_cam.h"
void Camera::drawText(cv::Mat & image)
{
putText(image, "Hello OpenCV",
Point(20, 50),
FONT_HERSHEY_COMPLEX, 1, // font face and scale
Scalar(255, 255, 255), // white
1, LINE_AA); // line thickness and type
}
双击打开 my_cam.h,复制粘贴。
#include "opencv2/imgproc.hpp" //含putText函数
using namespace cv;
class Camera
{
public:
void drawText(Mat & image);
};
源文件和头文件编写好后,开始编写CMakeLists.txt,复制粘贴。
# 指定最小CMake版本
cmake_minimum_required(VERSION 3.0)
# 定义项目的名字
project(HelloWorld)
# 设置编译类型(Debug Release MinSizeRel RelWithDebInfo)
set(CMAKE_BUILD_TYPE debug)
# 设置生成的可执行文件路径
# ${PROJECT_SOURCE_DIR}和${CMAKE_SOURCE_DIR}都指工程的顶级目录
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
find_package(
OpenCV
REQUIRED
)
message(STATUS "OpenCV library status:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
# include_directories,指定头文件搜索路径
# ${CMAKE_CURRENT_SOURCE_DIR}为CMakeList.txt所在目录
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include/
${OpenCV_INCLUDE_DIRS}
# 将 main.cpp 编译生成可执行文件 main
add_executable(
main
main.cpp
src/my_cam.cpp
)
target_link_libraries(
main
${OpenCV_LIBS}
)
这里使用了find_package来包含路径的,省去了在tasks.json中添加路径的繁琐。
源程序准备好后,我们首先要配置tasks.json文件,复制粘贴。
{
"version": "2.0.0",
"options": {"cwd": "${workspaceFolder}/build"},
"tasks": [
// 第一步 生成makefile
{
"type": "shell",
"label": "cmake",
"command": "cmake",
// windows需要指定生成器,目前没有配置默认生成器的方法,除了这个命令行选项参数的方式
"args": [
"-G \"MinGW Makefiles\"",
".."
],
"presentation": {
"showReuseMessage": false,
"reveal": "always",
"panel": "shared",
"close": false
}
},
// 第二步 生成exe
{
"label": "make",
"type": "shell",
"command": "make",
"presentation": {
"showReuseMessage": true,
"reveal": "always",
"panel": "shared",
"close": false
}
},
// 第三步 dependsOn指定执行顺序
{
"label": "build",
"type": "shell",
"dependsOrder": "sequence",// 按列出的顺序执行任务依赖项
"dependsOn": [
"cmake",
"make"
],
}
]
}
tasks.json会生成makefile,并编译,但是windows下cmake的默认生成器并不是我们配置的 MinGW Makefiles
,而且没有设置默认生成器的方法,所以我们在 args
参数中指定了生成器。
接下来就需要配置launch.json,定制运行任务,复制粘贴。
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Cmake",
// 如果使用 GDB/LLDB 调试器,type为cppdbg
// 如果使用 Visual Studio Windows 调试器,type为cppvsdbg
// 只能是这两个,这是C/C++扩展指定的
"type": "cppdbg",
"request": "launch",
"args": [],
"program": "${workspaceFolder}/bin/main",//指定生成的可执行文件的路径
"miDebuggerPath": "C://MinGW//bin//gdb.exe",//gdb的路径
"presentation":{
"hidden": false,
"group": "",
"order": 1
},
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
//"preLaunchTask": "build"//执行Task任务,每次调试时都执行一遍 build 任务
}
]
}
另外提一下c_cpp_properties.json,为什么会有这个文件,因为有的时候可能我们的扩展配置的不完整,需要这个文件来指定一些信息,对本程序,我测试了,加不加这个文件都可以。(可选)
{
"configurations": [
{
"name": "Win",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.17763.0",
"compilerPath": "C:/MinGW/bin/g++.exe",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-x64",
"configurationProvider": "ms-vscode.cmake-tools"
}
],
"version": 4
}
下面我们来运行一下工程。
首先 Ctrl+Shift+P
,输入tasks:
,选择 运行生成任务,我设置的快捷键 F4
。这样就生成 makefile,并编译生成 .exe文件,main.exe 会生成在我们指定的 bin 目录下。
生成完后,按 F5
来运行程序。程序会打开摄像头,如果电脑没有摄像头的话,就会执行 main.cpp 的 else 部分,像下面这样,黑屏的。
如果要调试的话,随便打个断点。
通过按键F5
,或者下面的按钮来进行调试。
可以通过左侧的调试工具栏和下面的调试控制台来观测调试结果。
----------end----------