Update
2023/9/14
- 修改了PATH环境变量参数:在程序执行时,dll所在路径不会覆盖所有已存在PATH
- 添加一个使用VS提供的环境变量以便于拼接PATH的案例
前置知识
Opencv程序需要依靠opencv动态库运行,而依赖动态库运行的程序在内存中没有对应动态库的默认情况下的查找顺序大致是程序所在目录-->系统目录等-->环境变量PATH目录
,而系统目录就是x:/Windows/System32
目录,这就是部分教程直接将opencv动态库直接放进系统目录中的原因。这种污染系统环境的方式大可不必;而另一部分教程是修改系统中的PATH环境变量实现,这种方式也大可不必。记住我们使用的是Visual Studio,是IDE,它已经给我们提供了完善的测试环境和选项,远比修改系统环境有用灵活。
基础准备
opencv下载选择最新版的windows下载(可能需要加速)。
我这里选择的是4.6.0版本。下载后双击程序运行自解压程序,随便解压到一个目录里,我这里解压到D:\app\opencv
中。
修改vs配置
注意,opencv就我所知官网只提供了64位版本,这将导致x86调试时无法正常链接并运行,所以以下所有对项目属性页的操作都要在x64平台运行,并切换调试器为x64模式
vs项目默认有两种配置,一种是Debug,另一种是Release。当我们创建一个空项目后,可以通过项目选项卡-->xxx属性
打开项目属性页,我们几乎所有的操作都会在这里进行。
修改通用配置
选择项目属性页左上方的配置选项卡,切换为所有配置。
附加包含目录
在项目属性页左侧的配置属性菜单中,单击C/C++选项卡
中常规
选项,找到附加包含目录项,在你解压的opencv库的目录寻找build\include
路径,在我的电脑上为D:\app\opencv\opencv\build\include
。将其添加到附加包含目录项中(如果不会可以搜索一下vs如何添加附加包含目录)
这一步让vs能够搜索到opencv的头文件,在写代码时不会因为vs没有导入opencv的文件认为你的代码语法错误而标记红线。
添加附加库目录
在配置属性-->链接器-->常规
选项卡的附加库目录
选项卡中添加你解压的opencv库路径中的build\x64\vc15\lib
路径,我这里是D:\app\opencv\opencv\build\x64\vc15\lib
。
这步的目的是为了在编译源码时候附加lib文件,让程序能够正确识别并加载dll文件(详情可搜索动态链接库生成的lib文件的作用)。
添加环境变量
这步较为重要,目的是在调试opencv程序时指引其链接动态库的目录。在配置属性-->调试
选项卡中修改环境
选项值,添加path=$(PATH);你所解压的opencv目录\build\x64\vc15\bin
我这里的值为PATH=$(PATH);D:\app\opencv\opencv\build\x64\vc15\bin
。
修改debug配置
修改左上角配置为debug配置模式,
在配置属性-->链接器-->输入
的附加依赖项选项中添加opencv_worldxxxd.lib
,我这里是opencv_world460d.lib
修改release配置
修改左上角配置为release配置模式,
在配置属性-->链接器-->输入
的附加依赖项选项中添加opencv_worldxxx.lib
,我这里是opencv_world460.lib
运行与调试
1 |
|
这是我随便找的源码,经过修改后理论上不会有任何报错并可以直接在两种调试模式下运行。找不到原作者是谁了
分发程序
在正常情况下,如果你需要分发程序,需要点击工具栏中生成选项卡的生成解决方案
或者生成xxx(项目名)
。随后在解决方案根目录/x64/Release
中找到生成的程序。此时运行程序会提示无法找到opencv_worldxxx.dll
文件,这时我们需要将opencv库目录/build/x64/vc15/bin
目录中的opencv_worldxxx.dll
复制到Release这个目录。当然也可以通过vs定义生成后事件来自动复制。
这时整个Release目录就是一个可以分发的opencv程序,你可以把它复制到其他人的x64位windows电脑上,不出意外是可以直接运行的。
为什么区分debug和release?
msvc在c++标准上修改和添加了众多配置以适配windows开发,并区分出了debug和release模式,一个显著差别就是debug模式生成的文件由于需要调试等功能,生成的二进制文件可能是release模式生成的二进制文件的数倍,这并不利于分发。例如opencv项目在debug模式下链接带d结尾的动态库,它会在运行时输出调试信息,但是release模式下链接不带d的动态库则不会,两动态库体积差别也极大。如果在两个模式下混合链接对应模式的链接库甚至是无法正常链接成功的。
其他
如果可以,你可以通过使用vs内置的一些环境变量(例如$(SolutionDir)
)修改opencv目录,并将opencv目录解压到某些特定文件夹(例如自己编写的程序项目所在的解决方案文件夹)。经过修改上边我教程中的部分路径甚至可以直接分发vs项目,便于分发源码和二次开发。
例如我最近正在学习CUDA编程,其中的某个例程用到了CUDA by Example
提供的的代码包中的动态库程序,由于无需安装,我将dll所在bin目录放在解决方案路径下,并在配置PATH环境变量时使用PATH=$(PATH);$(ProjectDir)..\cudaBin
通过使用VS提供的ProjectDir
环境变量,这样大约能使得整个项目便于分发。