本文目录
前言怎么查找资料?数据手册例程项目开发VS版本与OpenCV版本选择VS配置OpenCVVS添加MVS安装目录下的头文件和库VS项目开发编程问题记录相机数据如何转换为OpenCV的Mat类型?函数不能修改全局指针变量?OpenCV运行报错“有未经处理的异常: Microsoft C++ 异常: cv::Exception,位于内存位置 0x0000006A6311F318 处”OpenCV的imshow函数使用C++实现无阻塞键盘输入C++获取实时时间最后的一些题外话前言
由于学校要求暑期实习,于是找了一位学长开的公司,接了一个项目,是对海康威视工业相机(MV_CE200_10GM)进行二次开发,读取其图像并做分析处理。于是花了一点时间查找的相关资料并记录一些入门要点。
怎么查找资料?
想先说说一些“尝试授人与渔”的话,也是自己的一点经验和体会。
对于硬件开发,个人觉得最为重要的两点就是手册+例程(而不是疯狂地去找各种视频教程)。比如基于某一款单片机开发,肯定是需要有手册的,了解它的引脚特性和硬件资源,这种资料一般来自官网。而编程的时候,如果能有一个例程引导,会比完全按照手册去摸索强得多。
同样,这个工业相机的二次开发也是如此:手册+例程,值得称赞的是,海康威视官网完全提供这两者,省去了开发者找资料的大量时间。因此下面简单演示一下官网资料的查找。
数据手册
这里需要区分两个官网:海康威视【/cn/】和海康机器人【/cn】,如下图所示。
本项目中使用到的是CE系列工业相机,具体型号为MV_CE200_10GM,故要选择海康机器人官网。
打开官网后,不要直接搜索所使用相机的型号(因为搜不到。。。),按照下图可以找到相机的型号:
然后向下滚动,找到产品列表,选择对应的相机型号即可。
可见其实官网给的资料还是非常丰富的,个人建议结合技术规格书(产品数据手册)将用户手册通读一遍,基本能够建立一个大致的印象,之后有什么具体的问题再来查找。
例程
说完了数据手册,再来说说例程。值得一提的是,海康机器人还提供了一个能够显示相机画面的软件——MVS。
同样,这个软件也可以在海康机器人官网下载得到:
个人觉得这个软件主要有两个作用:①配置相机,即实现相机与电脑的通信,简而言之,如果没办法在MVS中看到相机画面,那开发也就无从谈起了;②查看相机画面,方便对焦,同时设置参数,帮助开发者了解各个参数的作用(用户手册中有详细描述)。
此外,就是MVS安装目录下的各种官方例程了,这个非常有用!首先找到MVS的快捷方式图标,然后右键,找到文件所在位置,之后回退到上一级目录,就能看到MVS安装目录的结构了,如下图所示。
项目开发
找完了资料,下面就开始开发了,这里需要根据自己的需要选择使用哪种语言开发,因为官方支持的语言还是非常多的。这里选择的是VS + MFC + OpenCV,选用VS还有一个好处就是,它配置OpenCV确实非常方便。
由于开发内容过于琐碎,这里只记录一些关键点。
VS版本与OpenCV版本选择
官方提供的demo支持的VS版本有,,,,需要根据自己的需要选择,因为VS的低版本是不兼容高版本的(网上有一些教程似乎可以破解,但比较麻烦),而且VS版本越高,安装包体积越大,可能两个版本后就double了,所以得根据自己电脑的情况和需求程度理智选择。此外就是需要考虑一下OpenCV的版本和VS版本匹配的问题,如下图所示【附:数据来源链接】
因为我电脑上之前已经安装了OpenCV4.5.1,所以这里选择了VS,经过试验发现是能够匹配OpenCV 4.5.1的。
这里有一点需要注意的是:建议直接去官网下载vs最新的 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
。具体使用方法可以参考这篇博客。
最后的一些题外话
海康工业相机运行所需模块 - CSDN工业相机的曝光、曝光时间、快门、增益 - 腾讯云开发者社区海康工业相机使用:常见问题及解决方法关于网线的问题:如果电脑上的以太网卡不是千兆或者没有以太网卡(即有线网卡,因为现在大多数轻薄本都只有无线网卡,表现为没有网线接口),可以考虑上网买一个网口转USB的,一定要是千兆的(一般匹配的就是USB3.0),然后插在电脑上的USB3.0接口上,如果既没有千兆以太网卡又没有USB3.0怎么办?emmmmm,那估计只能换一种型号的相机或者换电脑了~