VS2017开发C++学习(三)OpenCV的配置方法

作为萌新最初听说到opencv,以为是一个集成开发环境IDE。后来因为毕设原因不得不去使用opencv,才了解到OpenCV是一个广受欢迎的开源计算机视觉库 ,它提供了很多函数,实现很多计算机视觉算法,从最基本的滤波到高级物体检测皆有涵盖。换言之,opencv只不过是一个写好的库,方便在编程的时候对视觉数据进行处理。

网上有各式各样的配置方式,但是大部分都没说每一步做法的原因 ,导致opencv版本不大一样的话,很多人就把所有教程都试个遍,结果还不一定配成功。我个人是很反感这种方式的,所以下文会解释做每一步的原因,了解了做每一步的必要性后,配置不同版本的opencv环境就游刃有余了。

一、下载opencv库
百度搜一下就能找到官网https://opencv.org/,在releases选项页找到下载的地方。Documentation是程序相关说明文档,Sources是opencv的源码,Win pack与Sources的区别是,Win pack不仅包含了源码,还包含了利用源码编译后的库。

下载Win pack解压后得到文件目录如下:

sources文件夹下的是源码,配置环境的话是用不上的,有用的是源码经过编译后的库,位于build文件夹下。

二、开始配置环境
官方只提供了部分语言环境的编译库,一开始我是想着在devc++上配来着,毕竟devc++轻量一点,操作起来也方便简单一点。后来发现官方根本没有提供这个编译库,需要自己用cmake拿源码来编译,查了下好像有点麻烦,索性在VS2017下配算了,官方在opencv4.0.1有提供VS2017(VC15)的编译库,而且只提供了64位版的。

下面我们来看用一个外部导入的库时,需要怎么配置。

以C++为例,编译时需要用到库的头文件(用于include),一般是.h之类的文件;链接时用到静态链接库(.lib),运行时用到动态链接库(.dll或.exe之类)。通俗地说,静态链接库编译后会整合到程序中,而动态链接库不会整合到程序中。动态链接库更像是给运行提供环境,就像平时装游戏时可能要先装什么VC、DX之类环境软件才能玩。

配置系统环境变量
正如前面所说,动态链接库是为运行时提供环境,所以程序在运行时怎么知道动态链接库在什么位置呢。因此我们需要将动态链接库的位置告诉操作系统,方法就是设置系统变量。动态链接库位于build\x64\vc15\bin文件夹下(bin是指二进制文件,说明已经是一个相对独立的程序),于是我们在此电脑属性->高级系统属性->环境变量->系统变量Path下增加上述路径。

这个地方需要填绝对路径,我把我解压的opencv放在D盘的opencv文件夹下,因此具体路径还是要参照你自己文件所在的位置。盲目抄我的路径一般都会出错。

配置VS2017环境
配置编译环境无非是让编译器能找到引用头文件以及相关的静态链接库,引用头文件在build\include\opencv2文件夹下,静态链接库在build\x64\vc15\lib文件夹下,下面所配置的路径都是基于这两个路径。

考虑到不同的工程、项目等可能会用到不同的库,VS2017已经将工具=》选项=》项目和解决方案下的全局VC++目录改成了属性页,每个project项目可以有自己的属性页,甚至各个模式下都可以有自己的属性页。点击 视图=》其他窗口=》属性管理器 打开属性管理器,可以看到如下:

在这里,我的配置方式与网上其他文章所介绍的不太一致。他们的方法是双击Microsoft.Cpp.x64.user这一个属性页去修改,这样就可以一劳永逸,以后都不用再配环境。按照他们的方法配置出现的一个问题就是会导致release模式或debug模式下报异常,导致程序无法正常执行,如下:

其原因是附加依赖项中,他们把带d后缀和不带d后缀的.lib静态链接库写在了一起,带d是属于debug模式下要使用静态链接库,不带d的是release模式下要使用的静态链接库。VS只会取写在前面的静态链接库,因此会导致debug或release模式之一不可用(取决于你把哪个写在前面)。查阅了很多博客以及stack overflow的很多回答,回答基本上都是说这是opencv的一个BUG,其实我个人感觉更像是VS的一个BUG。

另一方面,Microsoft.Cpp.x64.user实际上是位于C:\Users\Admin\AppData\Local\Microsoft\MSBuild\v4.0\下的一个属性页文件,所有项目都会默认使用他,这不太符合项目独立性的设计初衷。

下面是我的一个配置方法。

在Debug | x64处右击新建一个新的属性表opencv_property401d_x64(名字随便起),双击新建的属性表,开始配置包含文件和静态链接库。

在包含目录处配置包含的头文件路径:

在库目录处配置静态链接库位置:

配置附加依赖项:

特别说明一下,在配置附加依赖项时需要先查看,静态链接库文件夹下有什么文件,如我的opencv4.0.1静态链接库文件夹D:\opencv\build\x64\vc15\lib下有如下文件。

我们只关注.lib文件,带d结尾的是用于debug模式的静态链接库,不带d结尾的是用于release模式的静态链接库,4.0.1版本比较简洁只剩两个.lib文件了,老版2代左右的opencv有一大堆静态链接库,所以在附加依赖项处要写一大堆。因为我们这里配置的是Debug | x64的属性表,所以我们只把带d结尾的.lib文件写进去。总而言之,此处附加依赖项填写静态依赖库文件夹下所有带d结尾的.lib文件路径,静态依赖库文件夹在4.0.1版本是build\x64\vc15\lib,具体路径可能会因版本而异。

再次说明,上面所填的所有具体的绝对路径一定要根据自己电脑上相关文件的路径去写,不要盲目抄我的。

最后,在Release | x64处右击新建一个新的属性表opencv_property401_x64,双击新建的属性表,配置方法与上面一致,唯一的区别在于,附加依赖项中填写的是所有不带d结尾的.lib文件路径。

配置完成后的属性表结构如下:

这些属性结构表将会应用于其对应的模式,opencv_property401_x64用于release的64位模式,opencv_property401d_x64用于debug的32位模式,因为没有官方提供32位模式的,所以32位下没有对属性页进行设置,因此也不能使用32位模式进行编译。

每种模式的属性表工作方式类似于CSS中的层叠方式,双击项目或Debug | x64之类的也可以进行属性设置,但这类属性页是存储于项目的工程文件中的,不是独立的属性表文件。上述配置完成后的opencv_property401_x64和opencv_property401d_x64是外部的独立属性表文件,建议进行备份保存,以后遇到需要使用opencv库的项目时,直接导入这两个属性表文件即可。

三、最终测试
简单写一个显示图片的C++程序进行配置测试。

图片如下:

代码如下:

#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;

int main()
{
// 读入一张图片(小熊猫)
Mat img = imread("picture.png");
// 创建一个名为 "小熊猫"窗口
namedWindow("小熊猫");
// 在窗口中显示小熊猫
imshow("小熊猫", img);
// 等待6000 ms后窗口自动关闭
waitKey(6000);
return 0;
}
把图片放在项目目录下,命名为picture.png,测试运行。

注意debug x64模式和release x64模式都测试下,确保没有问题。

四、一个小bug
在我测试的时候遇到过报这样一个异常。

一开始还以为是配环境出了问题,最后发现把我的搜狗输入法切换成系统默认输入法这个问题就解决了。这个输入法已经在我的程序生涯坑了我不止一次了,我也在想为毛我还没卸这个输入法。

五、参考文章
https://blog.csdn.net/poem_qianmo/article/details/19809337

http://www.opencv.org.cn/forum.php?mod=viewthread&tid=33549

原文:https://blog.csdn.net/goldenbullet/article/details/86016921

原文地址:https://www.cnblogs.com/YiYA-blog/p/10296224.html

时间: 2024-08-03 03:45:15

VS2017开发C++学习(三)OpenCV的配置方法的相关文章

Spring学习三、Spring配置与DI依赖注入

五.Spring配置 5.1别名 <!-- 别名--> <alias name="user" alias="user2"/> 5.2 Bean的配置 <!-- id : bean的唯一标识符,相当于对象名 class : 全限定名 包名 + 类名 name : 也是别名,name可以同时起多个别名 --> <bean id="userT" class="cn.imut.pojo.User&quo

ios开发runtime学习二:runtime交换方法

#import "ViewController.h" /* Runtime(交换方法):主要想修改系统的方法实现 需求: 比如说有一个项目,已经开发了2年,忽然项目负责人添加一个功能,每次UIImage加载图片,告诉我是否加载成功 当系统提供的控件不能满足我们的需求的时候,我们可以 1:通过继承系统控件,重写系统的方法,来扩充子类的行为(super的调用三种情况) 2:当需要为系统类扩充别的属性或是方法的时候,与哪个类有关系,就为哪个类创建分类.3:利用runtime修改系统的类,增加

Cmdlet开发与学习(三)

5.流程或诊断信息输出,错误以及异常处理       在使用PowerShell的过程中,如果cmdlet执行有输出结果,我们会在PS界面看到结果输出信息.如果cmdlet执行出现异常,那我们就会看到异常信息.接着我们就开始学习这些输出信息的实现. Cmdlet基类给我们提供了几种输出方法:WriteDebug, WriteError, WriteObject, WriteProcess, WriteVerbose, WriteWarning. WriteDebug:该方法是为cmdlet开发人

ios开发网络学习三:NSURLConnection小文件大文件下载

一:小文件下载 #import "ViewController.h" @interface ViewController ()<NSURLConnectionDataDelegate> /** 注释 */ @property (nonatomic, strong) NSMutableData *fileData; @property (nonatomic, assign) NSInteger totalSize; @property (weak, nonatomic) IB

Android Studio使用OpenCV的配置方法

1.下载 进入官网(http://opencv.org/)下载OpenCV4Android并解压.目录结构如下图所示. 其中,sdk目录即是我们开发opencv所需要的类库:samples目录中存放着若干opencv应用示例(包括人脸检测等),可为我们进行android下的opencv开发提供参考:doc目录为opencv类库的使用说明及api文档等:而apk目录则存放着对应于各内核版本的OpenCV_2.4.3.2_Manager_2.4应用安装包.此应用用来管理手机设备中的opencv类库,

反射学习(三)--------利用反射调用方法

利用反射调用方法 C1 newC1Instance = new C1(); var funM = newC1Instance.GetType().GetMethod("fun", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); object[] para = { }; if (funM == null) { Console.Write("error, fu

拜小白教你OpenCV3.2.0+VS2017开发环境配置

第一部分:OpenCV3.2.0的下载 OpenCV官方下载地址: http://opencv.org/releases.html# 本人选择opencv3.2.0基于Windows平台.读者根据自己需要选择合适版本及平台下载. 下载完成后,双击进行解压  解压即是安装OpenCV库的过程,读者自己选择好安装路径 [建议]在英文路径下,不用有中文和空格  第二部分:配置Path系统环境变量 此电脑-右键"属性"-高级系统设置   找到Path进行编辑 把之前解压(安装)好的OpenCV

Beaglebone Back学习三(开发环境搭建)

开发环境搭建 1 Ubuntu环境搭建 2 Window环境搭建 3 开发板环境搭建 1 Ubuntu环境搭建 (1)安装必要的网络工具 samba nfs tftp vmware-tools samba nfs apt-get install nfs-kernel-server vim  /etc/exports  (/path/to/nfs  *(rw,sync,no_root_squash) ) /etc/init.d/nfs-kernel-server restart (2)配置通信网络

Jetty学习三:配置概览-需要配置什么

上一节讲述了怎么配置Jetty,这节将告诉你使用Jetty你需要配置些什么. 配置Server Server实例是Jetty服务端的中心协调对象,它为所有其他Jetty服务端组件提供服务和生命周期管理.在标准Jetty发布中,核心的服务端配置是在etc/jetty.xml文件中,你也能在其中包含其他服务端配置,可以包括: 1)ThreadPool Server实例提供了一个线程池,你可以在etc/jetty.xml中配置最大线程数和最小线程数. 2)Handlers Jetty服务端只能有一个H