上一个教程 : 在 Windows 中安装
下一个教程 : 图像观察:在 Visual Studio 调试器中查看内存图像
原作者 | Bernát Gábor |
---|---|
兼容性 | OpenCV >= 3.0 |
警告
本教程可能包含过时信息。
我在这里描述的所有内容都适用于 OpenCV 的 C/C++
界面。在开始时,我假设您已经阅读并成功完成了 Windows 安装教程 。因此,在继续学习之前,请确保您有一个包含 OpenCV 头文件和二进制文件的 OpenCV 目录,并且您已经按照此处所述设置了环境变量 设置 OpenCV 环境变量,并将其添加到系统路径 .
我们在微软视窗操作系统上分发的 OpenCV 库是动态链接库(DLL)形式的。这样做的好处是,库中的所有内容只在运行时按需加载,而且无数程序都可以使用同一个库文件。这意味着,如果有十个应用程序使用 OpenCV 库,就无需为每个程序都准备一个版本。当然,您需要在所有要运行应用程序的系统上安装 OpenCV 的 dll。
另一种方法是使用具有 lib 扩展库的静态库。您可以按照 Windows 安装教程中的描述,使用我们的源文件构建这些库。使用这种方法时,库将内置在您的 exe 文件中。因此,用户不会因为某种原因而删除它们。但这样做的缺点是应用程序会比较大,启动时加载需要更多时间。
要使用 OpenCV 构建应用程序,您需要做两件事:
- 告诉编译器 OpenCV 库的外观。具体做法是向编译器显示头文件。
- 告诉链接器在需要时从何处获取 OpenCV 的函数或数据结构。
如果使用 lib 系统,则必须设置库文件所在的路径,并指定在哪个路径下查找。在构建过程中,链接器将查看这些库,并将所有使用过的函数和数据结构的定义和实现添加到可执行文件中。
如果使用 DLL 系统,则必须再次指定所有这些内容,但现在的原因不同了。这是微软操作系统的特殊要求。链接器似乎需要知道在 DLL 中的哪个位置,以便在运行时搜索数据结构或函数。这些信息存储在 lib 文件中。不过,它们并不是静态库。它们是所谓的导入库。这就是为什么当你在 Windows 中制作一些 DLL 时,最终也会产生一些 lib 扩展库。好在运行时只需要 DLL。
要将所有这些信息传递给 Visual Studio IDE,您可以选择全局传递(这样您未来的所有项目都会得到这些信息)或本地传递(这样只针对您当前的项目)。全局传递的优点是只需传递一次;但是,将所有项目与所有这些信息捆绑在一起可能并不可取。如果使用全局信息,则取决于您使用的 Microsoft Visual Studio。有 2008 版和以前的版本,也有 2010 版。在本教程的全局部分,我将介绍其中的主要区别。
在 Visual Studio 中,项目的基本项是解决方案。一个解决方案可以包含多个项目。项目是应用程序的构件。每个项目都会实现一些功能,你可以通过一个主项目来拼凑这个项目拼图。如果是许多简单的应用程序(如许多教程),则不需要将应用程序分解成模块。在这种情况下,您的主项目将是唯一存在的项目。现在,通过 “文件”->“新建”->"项目 "菜单选择,在 Visual studio 中创建一个新的解决方案。选择 Win32 控制台应用程序作为类型。输入名称并选择创建路径。然后在即将出现的对话框中确保创建了一个空项目。
局部方法
每个项目都是单独构建的。因此,每个项目都有自己的规则包。规则包中存储了集成开发环境在构建项目时需要了解的所有信息。任何应用程序都至少有两种构建模式:发布模式和调试模式。调试模式有很多功能,可以让你更容易地发现和解决应用程序中的错误。相比之下,Release 是一个优化版本,其目标是使应用程序运行得尽可能快或尽可能小。您可能会发现,这些模式在构建过程中也需要使用不同的规则。因此,每种构建模式都有不同的规则包。这些规则包在集成开发环境中被称为项目属性,你可以使用属性管理器查看和修改它们。您可以通过 “视图”->“属性页”(对于 Visual Studio 2013 以上版本,请转到 “视图”->“其他窗口”->“属性管理器”)调出该管理器。展开后就能看到现有的规则包(称为属性表)。
这些规则包的真正用处在于,您可以一次性创建一个规则包,然后将其添加到您的新项目中。一次创建,日后重复使用。我们要创建一个新的属性表,其中包含编译器和链接器需要知道的所有规则。当然,我们需要为调试版本和发布版本分别创建一个属性表。如下图所示,从调试版开始:
例如,使用 OpenCV_Debug 名称。然后选择工作表,点击右键 -> 属性(Properties)。在下文中,我将介绍如何在本地设置 OpenCV 规则,因为我觉得没有必要用不使用的自定义规则来污染项目。进入 C++ 组常规条目,在 "附加包含目录 " 下添加 OpenCV 包含的路径。如果没有*“C/C++”*组,则应在项目中添加任何 .c/.cpp 文件。
$(OPENCV_DIR)\...\include
在添加第三方库设置时,使用环境变量背后的功能通常是个好主意。在每个系统中,OpenCV 库的完整位置都可能发生变化。此外,你甚至可能因为某些原因而移动安装目录。如果你在属性表中给出了明确的路径,那么当你将项目传递给拥有不同 OpenCV 安装路径的其他人时,项目最终将无法运行。此外,要解决这个问题还需要手动修改每一个显式路径。一个更优雅的解决方案是使用环境变量。在运行时,任何放在以美元符号开头的括号内的内容都将被当前的环境变量值取代。我们在之前的教程中已经对环境变量进行了设置,这里就开始发挥作用了 设置 OpenCV 环境变量,并将其添加到系统路径 中。
接下来进入链接器 -> 常规,在 "附加库目录 " 下添加 libs 目录:
$(OPENCV_DIR)\lib
然后,你需要指定链接器应该查找的库。为此,请进入链接器 -> 输入,在*"附加依赖关系 "*条目下添加要使用的所有模块名称:
这些库的名称如下:
opencv_(模块名称)(所用库的版本号)d.lib
最新版本的完整列表包括
opencv_calib3d300d.lib
opencv_core300d.lib
opencv_features2d300d.lib
opencv_flann300d.lib
opencv_highgui300d.lib
opencv_imgcodecs300d.lib
opencv_imgproc300d.lib
opencv_ml300d.lib
opencv_objdetect300d.lib
opencv_photo300d.lib
opencv_shape300d.lib
opencv_stitching300d.lib
opencv_superres300d.lib
opencv_ts300d.lib
opencv_video300d.lib
opencv_videoio300d.lib
opencv_videostab300d.lib
或者,您下载的 OpenCV 可能已经内置到一个大的 .lib 文件中。请查看 OpenCV\build\architecture\vc14\lib 文件。在这种情况下,您只需为 3.3.0 版本添加
opencv_world330.lib
末尾的字母 d 只表示这些是调试所需的库。现在单击确定保存,并在 "发布规则 "部分添加新属性。确保省略库名称中的 d 字母,并用上方的保存图标保存属性表。
您可以在项目目录中找到属性表。此时,明智的决定是将它们备份到某个特殊目录中,以便将来创建 OpenCV 项目时随时可以使用。请注意,Visual Studio 2010 的文件扩展名为 props,而 2008 的文件扩展名为 vsprops。
下次创建新的 OpenCV 项目时,只需使用 "属性管理器 "中的 "添加现有属性表… "菜单项,即可轻松添加 OpenCV 构建规则。
全局方法
如果你觉得在每个项目中添加属性页太麻烦,也可以将这些规则添加到*"全局属性页 "*中。不过,这只适用于附加的包含目录和库目录。要使用的库名称仍需手动指定,例如使用属性页。
在 Visual Studio 2008 中,您可以在 工具 -> 选项 -> 项目和解决方案 -> VC++目录。
在 Visual Studio 2010 中,这被移到了全局属性表中,它会自动添加到您创建的每个项目中:
过程与局部方法相同。只需使用环境变量 OPENCV_DIR 添加 include 目录即可。
测试
现在,下载我们的小测试源代码,或从 OpenCV 源代码的示例代码文件夹中获取它,试试看。将其添加到您的项目中并构建。下面是它的内容:
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
if( argc != 2)
{
cout <<" Usage: " << argv[0] << " ImageToLoadAndDisplay" << endl;
return -1;
}
Mat image;
image = imread(argv[1], IMREAD_COLOR); // 读取文件
if( image.empty() ) // 检查输入是否无效
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
namedWindow( "Display window", WINDOW_AUTOSIZE ); // 创建一个显示窗口。
imshow( "Display window", image ); // 在窗口中显示图像。
waitKey(0); // 等待窗口中的按键操作
return 0;
}
您可以从两个地方启动 Visual Studio 构建。一是从集成开发环境内部(键盘组合:Control-F5),二是导航到构建目录,双击启动应用程序。问题是这两种方式并不相同。从集成开发环境启动时,当前工作目录是项目目录,而从其他目录启动时,当前工作目录是应用程序文件所在的文件夹(通常是构建目录)。此外,从集成开发环境启动时,控制台窗口不会在完成后关闭。它会等待你的按键。
当你在代码打开和保存命令中编写代码时,一定要记住这一点。您的资源将相对保存(并在打开时查询!!!)到您的工作目录。除非你为 I/O 函数提供一个完整、明确的路径作为参数。在上面的代码中,我们打开了 OpenCV 徽标。在启动应用程序之前,请确保将图像文件放在当前工作目录下。在代码中修改图片文件名,也可以在其他图片上试用。运行它,瞧
使用 Visual Studio 的命令行参数
在我们今后的一些教程中,你会看到程序的主要输入方法是给出运行时参数。要做到这一点,你只需启动一个命令窗口(开始菜单中的 cmd + Enter),导航到可执行文件,然后用参数启动它。因此,以我的上层项目为例,就可以这样做:
D:
CD OpenCV\MySolutionName\Release
MySolutionName.exe exampleImage.jpg
在这里,我首先更改了我的驱动器(如果你的项目不在操作系统的本地驱动器上),导航到我的项目,然后用示例图像参数启动它。在 Linux 系统下,在 Microsoft Windows 系统的控制台窗口中操作是很常见的,但很多人几乎从未使用过。此外,在测试应用程序时反复添加相同的参数也是一件麻烦事。幸运的是,Visual Studio 中有一个菜单可以自动完成这些工作:
在这里指定输入的名称,当你从 Visual Studio 环境启动应用程序时,就会自动传递参数。在下一个入门教程中,你将看到对上层源代码的深入解释: 图像入门。