【项目实践】海康威视工业相机SDK开发小白版入门教程(VS2015+OpenCV4.5.1)

前言

  由于学校要求暑期实习,于是找了一位学长开的公司,接了一个项目,是对海康威视工业相机(MV_CE200_10GM)进行二次开发,读取其图像并做分析处理。 于是花了一点时间查找的相关资料并记录一些入门要点

怎么查找资料?

  想先说说一些 “尝试授人与渔” 的话,也是自己的一点经验和体会。
  对于硬件开发,个人觉得最为重要的两点就是手册+例程(而不是疯狂地去找各种视频教程)。比如基于某一款单片机开发,肯定是需要有手册的,了解它的引脚特性和硬件资源,这种资料一般来自官网。而编程的时候,如果能有一个例程引导,会比完全按照手册去摸索强得多。
  同样,这个工业相机的二次开发也是如此:手册+例程,值得称赞的是,海康威视官网完全提供这两者,省去了开发者找资料的大量时间。因此下面简单演示一下官网资料的查找。

数据手册

  这里需要区分两个官网:海康威视【https://www.hikvision.com/cn/海康机器人【https://www.hikrobotics.com/cn,如下图所示。
在这里插入图片描述
在这里插入图片描述
  本项目中使用到的是CE系列工业相机,具体型号为MV_CE200_10GM,故要选择海康机器人官网。
  打开官网后,不要直接搜索所使用相机的型号(因为搜不到。。。),按照下图可以找到相机的型号:
在这里插入图片描述
在这里插入图片描述
  然后向下滚动,找到产品列表,选择对应的相机型号即可。
在这里插入图片描述
  可见其实官网给的资料还是非常丰富的,个人建议结合技术规格书(产品数据手册)将用户手册通读一遍,基本能够建立一个大致的印象,之后有什么具体的问题再来查找。

例程

  说完了数据手册,再来说说例程。值得一提的是,海康机器人还提供了一个能够显示相机画面的软件——MVS
  同样,这个软件也可以在海康机器人官网下载得到:
在这里插入图片描述

在这里插入图片描述

  个人觉得这个软件主要有两个作用:①配置相机,即实现相机与电脑的通信,简而言之,如果没办法在MVS中看到相机画面,那开发也就无从谈起了;②查看相机画面,方便对焦,同时设置参数,帮助开发者了解各个参数的作用(用户手册中有详细描述)。
  此外,就是MVS安装目录下的各种官方例程了,这个非常有用!首先找到MVS的快捷方式图标,然后右键,找到文件所在位置,之后回退到上一级目录,就能看到MVS安装目录的结构了,如下图所示。
在这里插入图片描述
在这里插入图片描述

项目开发

  找完了资料,下面就开始开发了,这里需要根据自己的需要选择使用哪种语言开发,因为官方支持的语言还是非常多的。这里选择的是VS2015 + MFC + OpenCV,选用VS还有一个好处就是,它配置OpenCV确实非常方便。
  由于开发内容过于琐碎,这里只记录一些关键点。

VS版本与OpenCV版本选择

  官方提供的demo支持的VS版本有2008,2010,2012,2015,需要根据自己的需要选择,因为VS的低版本是不兼容高版本的(网上有一些教程似乎可以破解,但比较麻烦),而且VS版本越高,安装包体积越大,可能两个版本后就double了,所以得根据自己电脑的情况和需求程度理智选择。此外就是需要考虑一下OpenCV的版本和VS版本匹配的问题,如下图所示  【附:数据来源链接
在这里插入图片描述
因为我电脑上之前已经安装了OpenCV4.5.1,所以这里选择了VS2015,经过试验发现是能够匹配OpenCV 4.5.1的。

这里有一点需要注意的是:建议直接去官网下载vs最新的2015 community版,不要去一些软件站下载!!!安装包大小为3G左右的最好不要用!!!因为如果安装不成功,想要完全卸载非常麻烦,不信可以去网上搜搜“VS完全卸载”,那都是泪呀。。。。

VS配置OpenCV

  相比于VS Code,VS配置OpenCV是相当地简单,关于这个也有非常多的教程,这里推荐一个比较简洁的,亲测有效。
  下面记录一些关键点:

  • 注意区分x64,x86,debug,release,用一种就贯彻到底,即所有的组件都用一种,否则VS工程就会报莫名其妙的错误。
  • 如果不想每次都配置一遍,可以在属性管理器窗口(菜单栏窗口->其他窗口)中添加一个属性(和上面一样,要注意匹配),然后双击设置,之后如果有工程需要使用到OpenCV,直接将该属性添加到工程即可。

VS添加MVS安装目录下的头文件和库

  为了能够使用相机,还需要在工程属性中包含相机相关的头文件和链接库,方法基本和上面配置VS差不多。

  • 打开官方给的demo,查看项目属性时可以发现它在包含路径处用了大量的宏定义。这是因为在安装MVS时,会在环境变量中添加很多和VS相关的项,这一点在示例程序说明文档中有相关描述,挺有意思的,但是考虑到有可能对方没有安装MVS,所以建议将需要包含的头文件和链接库复制到工程目录中,然后再添加相对路径进行引用,关于相对路径,主要是使用VS自带的路径宏定义,这一点可以参考这篇链接
  • 同样,这里也需要考虑x86,x64的问题,因为官方给的链接库有分别提供,一定要和项目工程属性对应。

VS项目开发

  官方提供的demo中有6个MFC程序,其他的都是控制台程序,对于需要有界面显示的开发者来说还是非常方便的,即单个功能实现可以参考控制台程序,界面制作可以参考MFC程序,关于MFC的开发,可以看看我之前写的一篇博客,虽然版本不同,但基本是相通的。

编程问题记录

  由于本人不是计算机专业,所以在开发的过程中也遇到了很多代码上的问题,确实涨了不少知识,在这里简单记录一下。

相机数据如何转换为OpenCV的Mat类型?

  通过溯源头文件发现,最后相机读取到的数据类型为unsigned char *类型,因为这个相机为黑白相机,数据格式设置的是8位单通道(Moon8),即每个像素点占用一个字节,其颜色的深度从白到全黑分256个等级。因此就面临一个问题是如何将这种格式的数据转换为OpenCV中使用的类型,方便后续的处理。
  参考这个链接,发现这个问题似乎很简单,因为OpenCV的Mat类提供了一个构造函数,能够将unsigned char *类型转换为Mat类型。

函数不能修改全局指针变量?

  在编程时,我定义了一个指针类型的全局变量,用来表示设备句柄,但是发现定义的一个用来修改设备句柄的函数竟然不起作用,那个设备句柄变量始终为空指针。后来查找相关教程后发现这就是经典的无法修改实参的问题,对于这种问题,一般来说有三种解决办法  【参考链接

  • 使用变量的引用
  • 传入变量的指针
  • 将该变量作为函数的返回值

这个问题其实非常低级,但是由于这个变量类型的特殊性(指针类型),导致我找了很久的bug,所以关键还是得要理解这种问题的本质。

OpenCV运行报错“有未经处理的异常: Microsoft C++ 异常: cv::Exception,位于内存位置 0x0000006A6311F318 处”

  首先先说结论,这种问题九成是内存泄漏或内存溢出,存在很多种情况,我当时应该是在一个循环里面调用imshow函数的时候,导致读取相机数据出现内存上的问题,这种情况可以说非常特殊了,其实我也还没真正整明白它内部的原理。这里找到一个链接,比较详细地描述了出现这种报错可能的几种情况,还是非常不错的。

OpenCV的imshow函数使用

  一开始发现imshow函数显示的图片有点问题:只能显示图片的一部分,一开始以为是读取数据不全面的原因,后来发现问题出在imshow函数本身上。即如果直接调用imshow函数,其默认的窗口分辨率是固定的,如果图片超出这个分辨率范围,就只能显示一部分图像了。
  解决办法是先使用nameWindow函数建立一个可变大小的窗口,然后再调用imshow函数显示图片。

namedWindow("Display", WINDOW_NORMAL);  //建立可变大小的窗口
imshow("Display", image);
waitKey(0);

  后来在循环中调用imshow函数又发现一个问题,那就是只能显示窗口内容,而不显示图像,经过排查发现imshow函数后面没有加waitkey(0)函数。

C++实现无阻塞键盘输入

  相当于是按键检测,但不堵塞循环,非常好用

#include <conio.h> //记得包含这个头文件

if (_kbhit()) // 有按键按下:停止图像采集进程,并做好收尾工作(关闭设备并销毁句柄)
{
    
    
	int key = _getch(); // 接收按下的按键
	if (key == ' ') // 如果按下空格
	{
    
    
		process();
	}
}

此外,还可以参考这个链接,提供了两种方案实现按键检测,值得学习。

C++获取实时时间

  这个问题网上的资料非常多,不过我这个有一个特殊的需求,那就是能精确到毫秒。这里采用的是SYSTEMTIME类型的变量,需要包含头文件windows.h。具体使用方法可以参考这篇博客

最后的一些题外话

猜你喜欢

转载自blog.csdn.net/ZHOU_YONG915/article/details/126206342