一、前言
按照这位大佬的方法,首先需要将 compile.m 中 opencv 的安装路径改为自己的路径:
我在电脑总搜索了一下发现之前不知道什么时候下载过一个 opencv4.2.0 ,于是便自作主张将路径改为了 opencv4.2.0 的路径,运行时发现报了如下错误:
尝试改正了几个警告,结果错误越来越多,越来越看不懂。猜测可能是 mexopencv 和 opencv 没有配置成功?使用了这位大佬分享的使用 opencv 调用摄像头的程序,果然运行出错:
于是决定重新配置一遍。为了能直接运行 CSR-DCF ,减少由版本不匹配引起的不必要的麻烦,我选择直接安装 opencv2.4.12 版本。
二、运行环境
win11+matlabR2021a+visual C++ 2022+opencv2.4.12 + mexopencv2.4
三、安装过程
mexopencv。
这里我直接点击了 2.4 版本。
安装过程全程参考文档。
(一)配置编译器
>> mex -setup
这里我选择早就安装好的 Visual C++
(二)安装 opencv 库
opencv 的安装与配置参考这位大佬。
1. 下载 opencv
在官网:https://opencv.org/releases/上找到OpenCV windows版下载下来。
然后解压。
解压之后,我们可以看到文件夹中有两个文件:
根据大佬的解答,build 里面是使用 OpenCV 相关的文件,sources文件夹里是源代码,samples 文件夹里面的示例程序。
打开 build 文件夹,里面有这样两个文件夹:
根据后面的介绍,这两文件夹是需要根据我们的系统选择添加至环境变量的。以 x86 为例,里面是这样两个文件夹:
其中 vc11 代表 Visual Studio 2012 ,vc12 代表 Visual Studio 2013,根据这位大佬以及这位大佬的介绍,更多代表如下:
vc8 = Visual Studio 2005
vc9 = Visual Studio 2008
vc10 = Visual Studio 2010
vc11 = Visual Studio 2012
vc12 = Visual Studio 2013
vc14 = Visual Studio 2015
vc15 = Visual Studio 2017
vc16 = Visual Studio 2019
vc17 = Visual Studio 2022
opencv支持情况:
OpenCV2.4.10 支持 VS2010,VS2012,VS2013 (x64,x86)
OpenCV2.4.13 支持 VS2012,VS2013 (x64,x86)
OpenCV3.0 支持 VS2012,VS2013 (x64,x86)
OpenCV3.1 支持 VS2013,VS2015(x64)取消了对32位的支持
OpenCV3.2 支持 VS2015(x64)
OpenCV3.4 支持 VS2015,VS2017(x64)
OpenCV4.1 支持 VS2015,VS2017(x64) 增加了神经网络的支持
OpenCV4.4 支持 VS2015,VS2017(x64)
OpenCV4.5 支持 VS2017,VS2019(x64)
OpenCV4.6 支持 VS2017,VS2019(x64)
OpenCV4.7 支持 VS2019(x64)
OpenCV4.7 支持 VS2022(x64)
可以看到,文件夹下并没有支持我 VC++2022 的文件夹。在这里,参考这位大佬的博客,将msvcr120d.dll(32位)以及msvcp120d.dll(32位)两个文件添加至 opencv2.4.12 的库路径(x86使用):
E:\\opencv\build\x86\vc12\bin
然后就可以配置环境变量。这里放一下大佬分享的两个文件的网盘链接:
链接:https://pan.baidu.com/s/1nvN3atF 密码:11ak
感谢大佬。
2. 配置环境变量
【此电脑】->【(右键)属性】->【高级系统设置】->【高级(标签)】->【环境变量】->“双击”系统变量中的PATH->在变量值里面添加相应的路径。如图:
(1)
(2)
(3)
(4)
(5)
这里我参照浅墨大佬的做法,将 x86 与 x64 的路径都添加了进去:
”;…… opencv\build\x86\vc10\bin”
和”…… opencv\build\x64\vc10\bin”
(6)
重启电脑。
3. 工程包含(include)目录的配置
(1)打开visual studio,选择空项目
此处参考这位大佬。
(2)写项目名称和设置存储的位置
(3)右键源文件,添加新建项,注意新建项为 .c 文件
(4)【(右键)项目名称】->【属性】->【配置管理器】,将管理器和上下文修成win32
(5)【(右键)项目名称】->【属性】->【连接器】->【系统】->【子系统】,将console修改成windows
根据大佬的解释,这里步骤 (4)和步骤(5)顺序不能换,因为配置管理器的平台换了,属性页也就更新了。在 x64 上面把子系统Console修改成windows,切换到win32平台后,修改好的子系统属性又变成 Console 了。因为换平台了,属性页面是新的了。就要重新设置。
(6)用简单的代码测试一下:
#include <windows.h>
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
MessageBox(NULL, TEXT("一个简单的Win32应用程序"), TEXT("消息窗口"), MB_OK);
return 0;
}
运行结果:
(7)【(右击)源文件】->【添加】->【新建项】,在工程中新建一个cpp源文件
(8)在菜单栏里面点【视图】–>【其他窗口】–>【属性管理器】,那么就会在visual studio中多出一个属性管理器工作区来
(9)在新出现的“属性管理器”工作区中,点击【项目】->【Debug|Win32】->【Microsoft.Cpp.Win32.userDirectories】(右键属性,或者双击)即可打开属性页面
(10)【通用属性】 ->【VC++目录】 ->【包含目录】中:
若之前将OpenCV解压到E:\Program Files\下,则将如下三个目录添加至包含目录中:
E:\Program Files\opencv\build\include
E:\Program Files\opencv\build\include\opencv
E:\Program Files\opencv\build\include\opencv2
具体根据实际情况进行更改。
这样一来,在属性管理器中进行一次配置,就相当于进行了通用的配置过程,以后新建的工程就不用再额外的进行重新配置了。
4. 工程库(lib)目录的配置
【通用属性】 ->【VC++目录】 ->【库目录】中:
按照同样的添加方式将 OpenCV2.4.12 库目录添加到VC++目录的“库目录”中,这里我将 x86 与 x64 都添加了:
x64:E:\opencv2.4\opencv\build\x64\vc12\lib
x86 E:\opencv2.4\opencv\build\x86\vc12\lib
贴一个大佬的解释:
5. 链接库的配置
【通用属性】 ->【链接器】->【输入】->【附加的依赖项】:
添加如下 2412 版本的lib( 这样的lib顺序是:19 个带 d 的 debug 版的 lib 写在前面,19 个不带 d 的 release 版的 lib 写在后面 ):
opencv_calib3d2412d.lib
opencv_contrib2412d.lib
opencv_core2412d.lib
opencv_features2d2412d.lib
opencv_flann2412d.lib
opencv_gpu2412d.lib
opencv_highgui2412d.lib
opencv_imgproc2412d.lib
opencv_legacy2412d.lib
opencv_ml2412d.lib
opencv_nonfree2412d.lib
opencv_objdetect2412d.lib
opencv_ocl2412d.lib
opencv_photo2412d.lib
opencv_stitching2412d.lib
opencv_superres2412d.lib
opencv_ts2412d.lib
opencv_video2412d.lib
opencv_videostab2412d.lib
opencv_calib3d2412.lib
opencv_contrib2412.lib
opencv_core2412.lib
opencv_features2d2412.lib
opencv_flann2412.lib
opencv_gpu2412.lib
opencv_highgui2412.lib
opencv_imgproc2412.lib
opencv_legacy2412.lib
opencv_ml2412.lib
opencv_nonfree2412.lib
opencv_objdetect2412.lib
opencv_ocl2412.lib
opencv_photo2412.lib
opencv_stitching2412.lib
opencv_superres2412.lib
opencv_ts2412.lib
opencv_video2412.lib
opencv_videostab2412.lib
贴大佬提示:
6. 测试是否出图
示例代码:
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main()
{
// 读入一张图片(游戏原画)
Mat img = imread("E:\\\\000001.jpg");
// 创建一个名为 "游戏原画"窗口
namedWindow("游戏原画");
// 在窗口中显示游戏原画
imshow("游戏原画", img);
// 等待6000 ms后窗口自动关闭
waitKey(6000);
}
不出图。
报错如下:
参考这位大佬的分享,我发现预处理器定义中确实是 _CONSOLE,与 4.(5)中设置的子系统为 windows 不符:
于是我将此处的 _CONSOLE 改为了 _WINDOWS。还是不行。
我又将 _WINDOWS 改为了 _CONSOLE,将子系统改为了控制台,还是不行。
然后我直接将函数中的 main 函数改为了 WinMain,报错还是有,但是变为了 “无法解析的外部符号_main” 。
我又将 WinMain 改为了 main,然后,程序没有报错了。。。。图片正确显示:
具体原因我也不知道。。。这个错误的原因可以参考这位大佬或者官方文档,在这里贴一下:
可能原因是 c 语言运行时找不到适当的程序入口函数,一般情况下,如果是 windows 程序,那么 WinMain 是入口函数,如果是 dos 控制台程序,那么 main 是入口函数,而如果入口函数指定不当,很显然c语言运行时找不到配合函数,它就会报告错误。即:
(1)你用 vc 建了一个控制台程序,它的入口函数应该是 main, 而你使用了 WinMain.
(2)你用 vc 打开了一个 .c/.cpp 文件,然后直接编译这个文件,这个文件中使用了 WinMian 而不是 main 作为入口函数。vc 这时的默认设置是针对控制台程序的。
(3)根本就没有WinMain或Main函数。
7. 补充问题
换了另外一台电脑,环境是 win10 + matlab R2021a + visual studio 2015,在测试是否出图时遇到了如下问题:
折腾了好几天,按照大部分人的说法将目标计算计改为 x64 等方法都没有用,有时反而是错误中 x86 与 x64 顺序换了过来。
然后我将上面的步骤在 Debug|win64 属性页中又设置了一遍,将平台改为 win64:
没有再报上面这个错误了,但还是不出图:
直到我看到了这篇帖子。
根据大佬的解释,当在 Win32 平台编译时,不管操作系统和 VS 编译环境是 32 或 64 位时,库目录均应是D:\opencv2410\build\x86\vc10\lib,否则会报错。我跟大佬之前的操作一样,在库目录将 X86 和 X64 的都包含,如下图所示,由于 X64 在上面,编译时率先被包含,就会报错:
按照大佬的说法,将 X64 那个 lib 路径下移,或是将 X64 的 lib 路径删除,如下图:
改好之后,没有再报这个错误了,但是又出现了之前那个错误:
我又按照之前的操作折腾了一遍,然后出现了下面这个错误:
即:
OpenCV Error: Assertion failed (size.width>0 && size.height>0) in cv::imshow, file C:\opencv\modules\highgui\src\window.cpp, line 261
然后,我发现我的路径写的有问题。正确的路径写法为中间有两条斜杠而不是一条。。。。
改好后图片正确显示。
(三)构建 mexopencv
文档中的要求:
操作如下:
-
解压文件到你任意指定的路径下,打开 MATLAB(我安装的 MATLAB 是 R2021a 版本的),选定路径为你将 mexopencv解压的路径:
-
将这个路径及其子路径都添加到MATLAB的设置路径中:
-
在MATLAB命令窗口输入
mex -setup
- 将 mexopencv3_4_1+mexopencv 目录下的 make.m 文件中的 opts.opencv_path 参数设置为OpenCv 原先解压的路径:
默认为 C 盘下的 opencv。注意此处应修改为解压的路径:
- 在MATLAB的命令行中输入:
>> mexopencv.make
版本不匹配。
首先定位到 279 行:
可以看到之所以会报这个错误,是因为 s 为空。
追溯 s,
我们可以看到这个函数实际上就是为了找到匹配版本的编译器。在这里,我选用的是 Microsoft Visual C++ 2022 作为编译器,那么我这里的 cc 就包含下面这些信息:
可以看到 cc.Version 为 17.0。而这个版本对应的 cc.Version 只给出了 8.0、9.0、10.0、11.0、12.0 对应的几种选择方案。于是这里就报错了。
然后我将 cc.Version 强制赋值 12.0:
就可以了。。。。
重新键入 mexopencv.make:
mexopencv.make
编译完成:
- 调用摄像头测试:
这里还是贴一下大佬的代码:
camera = cv.VideoCapture();
pause(2);
for i = 1:50
% Capture and show frame
frame = camera.read;
imshow(frame);
pause(0.3);
end
调用成功。
四、运行 CSR-DCF
三天了。终于到这一步了。
- 打开 compile.m 更改为自己的 OpenCV 安装路径
这里我出现了如下问题:
根据这位大佬的解释,可能是因为程序在 64 位与 32 位机器之间进行切换,即原来的程序是在32位机器上进行执行的,现在的机器是 64 位的,故需显示指定。
我将 compile.m 第 9 行的内容改为如下内容:
mex -DMX_COMPAT_32 gradientMex.cpp
运行成功:
另外,由于我想设置断点调试一下,因此我将 cpp 文件 mex -g 了一下:
第9行:
mex -g -DMX_COMPAT_32 gradientMex.cpp
25到28行:
eval(['mex -g mex_extractforeground.cpp src\segment.cpp -Isrc\ -I' opencv_include ' -L' opencv_libpath ' ' lib]); % 在命令行运行括号中的语句
eval(['mex -g mex_extractbackground.cpp src\segment.cpp -Isrc\ -I' opencv_include ' -L' opencv_libpath ' ' lib]);
eval(['mex -g mex_segment.cpp src\segment.cpp -Isrc\ -I' opencv_include ' -L' opencv_libpath ' ' lib]);
这样便生成了 .pdb 文件:
- 打开 demo_csr.m,更改跟踪算法的存放路径和图像序列存放路径
- 运行 demo_csr.m
运行成功。