OpenCV 4.11.0
开源计算机视觉库
加载中…
搜索中…
无匹配项
如何在“Microsoft Visual Studio”中构建OpenCV应用程序

上一篇教程: Windows 安装
下一篇教程: 图像监视:在 Visual Studio 调试器中查看内存中的图像

原作者Bernát Gábor
兼容性OpenCV >= 3.0
警告
本教程可能包含过时信息。

此处描述的所有内容都适用于OpenCV的`C\C++`接口。我假设您已经阅读并成功完成了Windows 安装教程。因此,在继续之前,请确保您拥有包含OpenCV头文件和二进制文件的OpenCV目录,并且已按照设置OpenCV环境变量并将其添加到系统路径中所述设置了环境变量。

我们分发的Microsoft Windows操作系统上的OpenCV库是动态链接库(DLL)。它们的优点是库的所有内容仅在运行时按需加载,并且无数程序可以使用相同的库文件。这意味着如果您有十个使用OpenCV库的应用程序,则无需为每个应用程序都保留一个版本。当然,您需要在所有要运行应用程序的系统上都拥有OpenCV的dll

另一种方法是使用扩展名为lib的静态库。您可以按照Windows 安装教程中所述,使用我们的源文件构建这些库。当您使用此方法时,库将内置到您的exe文件中。因此,用户不可能由于某种原因而删除它们。缺点是您的应用程序会更大,并且加载时间会更长。

要使用OpenCV构建应用程序,您需要执行两件事

  • 告诉编译器OpenCV库的外观。您可以通过显示头文件来实现。
  • 告诉链接器在需要时从哪里获取OpenCV的函数或数据结构。

    如果您使用lib系统,则必须设置库文件所在的路径,并指定要在其中查找库文件的路径。在构建过程中,链接器将查找这些库,并将所有已使用的函数和数据结构的定义和实现添加到可执行文件中。

    如果您使用DLL系统,则必须再次指定所有这些信息,但原因有所不同。这是Microsoft OS特有的内容。链接器似乎需要知道在运行时在哪个DLL中搜索数据结构或函数。此信息存储在lib文件中。但是,它们不是静态库。它们是所谓的导入库。这就是为什么当您在Windows中创建一些DLL时,您最终也会得到一些lib扩展库的原因。好的一面是,运行时只需要DLL

要将所有这些信息传递给Visual Studio IDE,您可以全局执行(因此所有未来的项目都将获得此信息)或局部执行(仅限于当前项目)。全局方法的优点是您只需要执行一次;但是,始终将所有项目与所有这些信息捆绑在一起可能并不理想。对于全局方法,具体操作方法取决于您使用的Microsoft Visual Studio 版本。存在2008及更早版本2010版本的操作方法。在本教程的全局部分,我将展示主要区别。

Visual Studio 中项目的基元是解决方案。一个解决方案可能包含多个项目。项目是应用程序的构建块。每个项目都将实现某些功能,您将拥有一个主项目,您可以在其中将这些项目拼图组合在一起。对于许多简单的应用程序(例如许多教程中的应用程序),您无需将应用程序分解为模块。在这些情况下,您的主项目将是唯一存在的项目。现在,通过“文件”->“新建”->“项目”菜单选择,在 Visual Studio 中创建一个新的解决方案。选择Win32控制台应用程序作为类型。输入其名称并选择创建它的路径。然后在接下来的对话框中,确保创建一个空项目。

局部方法

每个项目都与其他项目分开构建。因此,每个项目都有自己的规则包。在这些规则包中存储了IDE需要知道以构建您的项目的所有信息。对于任何应用程序,至少存在两种构建模式:Release(发布)和Debug(调试)。Debug具有许多功能,因此您可以更容易地查找和解决应用程序中的错误。相反,Release是优化版本,其目标是使应用程序运行速度尽可能快或大小尽可能小。您可能会发现这些模式在构建期间也需要使用不同的规则。因此,每个构建模式都有不同的规则包。这些规则包在IDE中被称为项目属性,您可以使用属性管理器查看和修改它们。您可以通过“视图”->“属性页”(对于 Visual Studio 2013 及更高版本,请转到“视图”->“其他窗口”->“属性管理器”)来调出它。展开它,您可以看到现有的规则包(称为属性表)。

这些真正有用的东西是,您可以一次创建规则包,然后将其添加到新项目中。创建一次,以后重复使用。我们要创建一个新的属性表,其中将包含编译器和链接器需要知道的所有规则。当然,我们需要为Debug和Release构建分别创建一个。从Debug开始,如下面的图像所示。

例如,使用OpenCV_Debug名称。然后通过选择该表,右键单击->属性。在下文中,我将展示如何局部设置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* 添加包含目录即可。

测试它!

现在,要试用它,请下载我们的小测试源代码,或从OpenCV源代码的示例代码文件夹中获取它。将其添加到您的项目并构建它。以下是其内容:

#include <opencv2/core.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;
}
n维密集数组类
定义 mat.hpp:829
bool empty() const
如果数组没有元素,则返回 true。
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
定义 core.hpp:107
STL 命名空间。

您可以从两个地方启动 Visual Studio 构建。一个是在 IDE 内部(键盘组合:Control-F5),另一个是导航到您的构建目录并双击启动应用程序。关键是这两个**不一样**。当您从 IDE 启动它时,它的当前工作目录是项目目录,而否则是应用程序文件当前所在的文件夹(因此通常是您的构建目录)。此外,如果从 IDE 启动,则完成时控制台窗口不会关闭。它将等待您的按键。

在编写代码打开和保存命令时,记住这一点很重要。您的资源将相对于您的工作目录保存(并在打开时查询!!!)。除非您为 I/O 函数提供完整的显式路径作为参数。在上面的代码中,我们打开了这个 OpenCV 徽标。启动应用程序之前,请确保将图像文件放在当前工作目录中。修改代码中的图像文件名以在其他图像上试用它。运行它,瞧!

Visual Studio 命令行参数

在我们未来的部分教程中,您会看到程序的主要输入方式是通过提供运行时参数来实现。为此,您可以启动一个命令窗口(在开始菜单中输入 cmd + Enter),导航到您的可执行文件并使用参数启动它。例如,在我的上述项目中,这将如下所示:

D:
CD OpenCV\MySolutionName\Release
MySolutionName.exe exampleImage.jpg

在这里,我首先更改了我的驱动器(如果您的项目不在操作系统本地驱动器上),然后导航到我的项目并使用示例图像参数启动它。虽然在 Linux 系统下经常需要使用控制台窗口,但在 Microsoft Windows 上许多人几乎从未使用过它。此外,在测试应用程序时一遍遍添加相同的参数是一项繁琐的任务。幸运的是,在 Visual Studio 中有一个菜单可以自动化所有这些操作。

在此处指定输入的名称,当您从 Visual Studio 环境启动应用程序时,您可以自动传递参数。在下一个入门教程中,您将看到上述源代码的深入解释:图像入门