VS + OpenCV + cmake,源码编译,使用及调试
文章目录
- 为什么要源码编译
- 工具和环境准备
- cmake构建VS工程
- VS编译OpenCV
- VS使用OpenCV
- VS调试OpenCV
- 源码编译的路径未发生过变化
- 源码编译的路径已发生变化
为什么要源码编译
OpenCV的安装包只有针对特定版本VS的dll,这就比较不灵活了,在不换VS版本的情况下靠安装包没法随心所欲使用各个版本的OpenCV,而使用OpenCV源码进行编译则可以。另外源码编译时能够生成一些pdb文件,这些文件使得我们能够进入OpenCV函数内部进行源码级调试。这就是为什么要学会使用OpenCV源码编译。
工具和环境准备
Windows操作系统,win10
- 安装过程略
VS2019 community
- 安装过程略
OpenCV源码
- 官网:https://opencv.org/
- 下载页面:https://opencv.org/releases/
- 进入下载页面,随便下一个OpenCV的源码包,即点击
Sources
进行下载,这里下载的是opencv-4.4.0.zip
cmake
- 官网:https://cmake.org/
- 下载页面:https://cmake.org/download/
- 进入下载页面,下载最新的cmake安装包,
.msi
后缀的那种,这里下载的是cmake-3.18.4-win64-x64.msi
- 双击安装包,安装cmake。除了安装路径的地方可能根据需要改一下外,其他一路火花闪电的next就行了
cmake构建VS工程
- 解压
opencv-4.4.0.zip
,我这里解压后的路径是D:\software\opencv-4.4.0
,在此路径下新建一个文件夹build-vs2019
,cmake构建的结果就输出在这个文件夹下(build文件夹可建立在任何地方,之所以建立在opencv解压目录下,为了清楚了解build对应的源代码是哪一份,个人习惯而已) - 双击cmake-gui,配置两个路径:
(1)源码路径:D:\software\opencv-4.4.0
(2)构建输出路径:D:\software\opencv-4.4.0\build_vs2019
点击
Configure
开始配置。这个过程耗时较长,并且经常一次不能成功,因为配置过程需要再下载一些东西,然而常常无法通过cmake下载成功,需另外手动下载。即便第一次Configure
经常不能成功,也还是得先点一次,这样才能通过下面的日志信息了解到为什么不能成功。
上图中上面一坨红,表明Configure不成功,翻一翻下面的日志发现一些组件没有下载下来,特别是Video I/O 里的 FFMPEG。不是所有组件都必须补齐的,但是FFMPEG跟视频编解码相关,几乎一定会用到,所以必须补齐。可以打开下载日志文件
D:/software/opencv-4.4.0/build_vs2019/CMakeDownloadLog.txt
查看哪些组件下载失败,此文件中也会告诉我们到哪里下载缺失的组件。打开该日志文件后可以找到如下信息:#do_copy “opencv_videoio_ffmpeg.dll” “854b3460c435d04277e1f1ecc06cb809” “https://raw.githubusercontent.com/opencv/opencv\_3rdparty/1df9bf0c0c6c2cf225bd3d8e4cf5985198352454/ffmpeg/opencv\_videoio\_ffmpeg.dll” “D:/software/opencv-4.4.0/build_vs2019/3rdparty/ffmpeg”
#missing “D:/software/opencv-4.4.0/build_vs2019/3rdparty/ffmpeg/opencv_videoio_ffmpeg.dll”
#check_md5 “D:/software/opencv-4.4.0/.cache/ffmpeg/854b3460c435d04277e1f1ecc06cb809-opencv_videoio_ffmpeg.dll”上面的日志至少告诉我们如下信息:1.
opencv_videoio_ffmpeg.dll
的下载网址;2. 本地存放的路径;3. 需要校验md5。因为要校验md5,所以我们不能随便下载一个同名dll放到本地存放路径下,必需下载上述网址的dll。接下来手动下载上述文件并放入
.../build_vs2019/3rdparty/ffmpeg
中即可。同理下载opencv_videoio_ffmpeg_64.dll
和ffmpeg_version.cmake
。需要注意 ffmpeg_version.cmake 点击链接后可能直接打开了链接而不是下载,此时不能使用复制粘贴的方式把信息搞下来,而应该在网页上点右键 -> 另存为
的方式保存文件,然后把后缀.txt干掉,不然MD5校验不通过。除了FFMPEG组件之外,我这里还有一个ippicv_2020_win_intel64_20191018_general.zip
也下载失败了,一并手动下载掉。(这几个东西下载是真的慢)下载好并放入相应文件夹之后,再次点击
Configure
进行配置,这次速度会快一些,因为已经配置好的内容会直接跳过去。配置好后上面的一坨红消失了,并且下面日志也不会有诡异的错误。(至于下面图片中Java那里显示的NO,就忽略好了,不搞Java)- 点击
Generate
生成VS工程,这一步通常没有什么坑,并且速度比较快。之后进入build文件夹D:\software\opencv-4.4.0\build_vs2019
,现在文件夹下有OpenCV的VS工程OpenCV.sln
。
VS编译OpenCV
- 打开
OpenCV.sln
- 把Debug模式改成Release模式
- 依次点击
生成 -> 生成解决方案
,然后等待一段时间。电脑不太好的话可以去吃个饭或者干点其他的。生成后vs的输出如下,至于跳过的项目,暂且不用在意。 在VS
解决方案管理器
展开CMakeTargets
,右键点击INSTALL
,然后点击生成
。之后会将我们需要用到的东西全部放在D:\software\opencv-4.4.0\build_vs2019\install
文件夹下,包括以下内容:
(1) include,头文件
(2)x64/vc16/bin,dll文件
(3)x64/vc16/lib,lib文件install文件夹下所有的东西在其他地方都存在,比如dll文件在
D:\software\opencv-4.4.0\build_vs2019\bin\Release
,lib文件在D:\software\opencv-4.4.0\build_vs2019\lib\Release
,但是头文件比较零散。INSTALL项目只是将这些我们调用OpenCV时需要用到的所有文件统一拷贝到了一个地方,省得自己找来找去。- 改成Debug模式,将上面流程再来一套。Debug模式下生成的dll和lib文件,文件名后面都带个
d
,表示是Debug模式下生成的,比如opencv_core440d.dll
,opencv_highgui440d.lib
。而Release模式下生成的文件是没有这个d
的。
VS使用OpenCV
新建VS工程,起名为TestOpenCV。
在TestOpenCV工程文件夹下新建一个文件夹,起名
opencv
,然后将...\opencv-4.4.0\build_vs2019\install
中的部分文件拷贝到该文件夹下,常用的需拷贝的文件有:
(1) include,整个文件夹全拷贝进去(include是必需的)
(2)在opencv
中新建bin
文件夹,将opencv_core440(d).dll
,opencv_highgui440(d).dll
,opencv_imgcodecs440(d).dll
,opencv_imgproc440(d).dll
,opencv_videoio440(d).dll
,opencv_videoio_ffmpeg440_64.dll
,拷贝进bin
中。(d)
的意思表示Debug模式可选,如果你需要在Debug模式下调试程序,那么就把Debug模式的依赖库也拷进去,否则可以不用拷,此时你的程序可能只能在Release模式下跑。
(3)在opencv
中新建lib
文件夹,将opencv_core440(d).lib
,opencv_highgui440(d).lib
,opencv_imgcodecs440(d).lib
,opencv_imgproc440(d).lib
,opencv_videoio440(d).lib
,拷贝进lib
中为什么要把文件拷贝到VS工程文件夹下呢?这样的话只要我们把后续的路径配置成相对路径,那么当我们把工程文件夹拷贝给别人后,别人不需要额外配置就可以直接打开运行。而如果我们把所有的dll,lib,头文件放在一个地方,每次使用绝对路径进行后续配置,那么拷给别人后就会很麻烦。
- 右键点击工程名字,然后在弹出菜单中点
属性
进行配置。Debug和Release需要分别配置,但是此处除了链接器 -> 输入
之外,其他的配置Debug和Release是相同的,所以可以在属性界面的左上角将配置
通过下拉框改为所有配置
,意思就是把Debug和Release配置成相同的参数。 - 配置dll路径。依次点击
调试 -> 环境
,配置bin文件夹路径,前面要加PATH=,即PATH=./opencv/bin
- 配置include目录。依次点击
VC++ 目录 -> 包含目录
,增加./opencv/include
- 配置lib目录。依次点击
VC++ 目录 -> 库目录
,增加./opencv/lib
- 配置lib文件名,此处需区分Debug和Release。依次点击
链接器 -> 输入
,在Debug模式下添加opencv_core440d.lib,opencv_highgui440d.lib,opencv_imgproc440d.lib,opencv_imgcodecs440d.lib,opencv_videoio440d.lib
;在Release模式下添加opencv_core440.lib,opencv_highgui440.lib,opencv_imgproc440.lib,opencv_imgcodecs440.lib,opencv_videoio440.lib
写一段测试代码:
include
include
include
using namespace std;
using namespace cv;int main()
{string imagePath = "D:/data/1.bmp";
Mat image = imread(imagePath);
resize(image, image, Size(1024, 1024));
namedWindow("TestOpenCV", 0);
imshow("TestOpenCV", image);
waitKey(0);
destroyAllWindows();
return 0;
}
这段测试代码简单地读入一张图片,然后做个resize,然后将其显示出来,道理上讲前面配置没问题的话,这里不论是Debug模式还是Release模式都能正常运行。
VS调试OpenCV
前面一部分使用OpenCV的方法不能够进入到OpenCV的函数内部进行调试。假如OpenCV某个函数比较玄妙,我们想要单步进去看看执行情况,怎么办?比如现在想要看OpenCV的resize实现方式,此时对着resize点F12只能看到头文件中的函数声明,函数实现无法看到。
源码编译OpenCV后会生成一些后缀名为.pdb
的文件, 这些文件是调试的关键。下面分两种情况说明如何对OpenCV进行源码调试。
源码编译的路径未发生过变化
这种情况非常简单,在想要调试的地方打个断点,然后点F11
进行单步,不停地点,点着点着就进入到源码里了。
源码编译的路径已发生变化
这种情况我们只是有源码编译过的文件,包括dll,lib,pdb,头文件,源码等等都有,但是路径不再是源码编译时的路径了。有可能我们编译过,但是路径改了,也有可能这些文件是从别人那里拷过来的。不管怎样,此时点F11无法进入到函数内部。为了能够进入函数内部,在之前VS工程设置的基础上,我们需要再做如下操作:
- 将相关的Debug的
pdb
文件考入到.../opencv/bin
文件夹下。pdb文件在...\opencv-4.4.0\build_vs2019\bin\Debug
路径下 - 在想要调试的地方打断点,不停地点F11
- 由于此时通过pdb无法直接找到源码,所以取而代之地,会弹出一个窗口,让我们选择源码路径,此时手动选择一下即可。实际上并不需要精准地找到
resize.cpp
的路径,只要找到OpenCV的根目录即可。
还没有评论,来说两句吧...