工业相机编程模型和流程及SDK接口使用

内容纲要:
1.工业相机编程模型和流程
2.工业相机sdk接口使用总结
3.basler pylon工业相机sdk的使用
4.pylon 以实时图像采集讲解pylonc sdk使用流程
5.关于使用维视工业相机 sdk 采集图像的问题
6.工业相机sdk之opencv二次开发
一、工业相机编程模型和流程
不同的工业相机提供不同的编程接口(sdk),尽管不同接口不同相机间编程接口各不相同,他们实际的api结构和编程模型很相似,了解了这些再对工业相机编程就很简单了。
dma技术:
dma是一种高速的数据传输操作,允许在外部设备和存储器之间直接读写数据,既不通过cpu,也不需要cpu干预。整个数据传输操作在一个称为dma控制器的控制下进行的。cpu除了在数据传输开始和结束时做一点处理外,在传输过程中cpu可以进行其他的工作。这样,在大部分时间里,cpu和输入输出都处于并行操作。因此,使整个计算机系统的效率大大提高。
对于工业相机来说,当cmos或ccd芯片曝光然后将数据转到相机缓存后,这时候dma会负责将缓存中数据保存到硬盘上指定位置,正好满足相机高速大数据的传输。一般都会使用dma来完成实时的数据采集和保存。
多数时候,dma控制器存在各种接口的图像采集卡中,包括1394/gige/usb/camera link等,这些采集卡有自己的时间控制单元完成和相机曝光的同步,并控制dma的存取行为。
工作流程:
当相机工作时,就是连续的采集-处理-采集-处理...的过程,但是这就存在一个问题,如果采集的速度比处理速度快,处理不过来,怎么办?在实际中,我们使用队列来解决这个问题,当前帧没有处理完,下一帧到来时直接放入队列等待当前处理完成后再处理它。
如下图

这里使用三个队列完成采集和处理同步。
dma队列:
当cmos或ccd芯片曝光然后将数据转到相机缓存后,这时候dma会负责将缓存中数据写入到“dma队列”头buffer中。
准备队列:
一旦“dma队列”头buffer被填充完成,会被加到“准备队列”尾后,这时候会发送中断通知用户程序:当前又有一帧数据采集完成,您看着处理吧。
处理队列:
当用户接收到中断会自动跳转到中断函数中,使用getframe拿取“准备队列”头buffer,然后加到当前用户程序“处理队列”尾,用户程序从“处理队列”头拿取buffer处理完成后使用putframe将buffer再添加到原始的“dma队列”尾。
需要说明如下几点:
1.这里的初始队列为1-10,都是初始分配为dma队列的,这个内存分配和释放过程有的sdk是自己负责的,有的则需要用户自己分配和释放,sdk只负责托管使用。
2.一般最开始注册一个中断处理函数,当“准备队列”填充完成会自动跳转到中断函数中,借此完成同步操作。也可以是用户自己维护同步结构体,使用查询和等待的方式判断“准备队列”头是否填充完成,是否该用户程序获取数据和处理了。
3.如果用户处理任务非常简单,可以去掉“处理队列”,每次直接getframe->处理->putframe。如果用户处理任务比较复杂而不希望出现丢帧的现象,则需要用户使用“处理队列”来保存所有可用的buffer。
4.这里队列也只是能够解决处理速度比采集速度慢少许的情况,主要是对不同处理速度做平均来保证采集和处理同步。如果每一帧的处理时间太长,这时候“dma队列” buffer全部转移到“处理队列” buffer,就会出现异常情况,这时不同的相机会有不同的处理方法。
数据传输和显示流程

如图,每个相机可能有不同的流采集器(grab streamer)或同一接口上安装了多个相机(也对应多个流采集器),对应多个通道(channel)。对每个通道来说,在实际采集时数据传输实际上是拆分成如图的数据包(packet) rawdata形式传递的,内存中存储形式为一维数组,在每一帧图像的起始存在不同的标识表明一帧的开始和结束,每一个packet都有标识表明当前所属的通道。为了显示图像,用户程序需要重新将一维数组数据拼装成图像形式,这一过程由用户完成,通常可借助opencv或mil等图像处理包完成该操作。
编程模型和流程
对于相机来说,常见编程时我们关注三个对象——相机对象、采集对象、参数对象。
相机对象(camera object):负责相机的连接、断开等工作。
采集对象(grab streamer):负责相机的采集队列分配、相机单帧、连续采集。
参数对象(parameter object):负责相机参数的设置。
不同的sdk可能安排不一样,一般来说要不是三种对象的功能合并到“相机对象”中,要不是分为三种对象,其实采集对象和参数对象都是在“相机对象”上封装而来。
通用编程流程如下图

可以看到相机编程需要做三方面工作:
1.初始化操作
首先初始化相机驱动com环境,然后遍历得到当前的相机列表,根据相机id或list 编号选择对应相机。
之后连接指定相机,首先设置本次采集的相机参数(帧速、图像大小、缩放比等),然后是分配和注册当前dma队列,这里有的是用户完成,有的是sdk完成。
之后先开启dma逻辑等待相机采图,然后使相机开始工作采图,整个系统就按照之前工作流程运作起来了,许多sdk将“开启dma”和“相机开始工作”合并为“开始采集”。
2.结束操作
先停止相机工作再关闭dma逻辑,许多sdk将“开启dma”和“相机开始工作”合并为“结束采集”。
然后清理dma队列,和分配时对应,这里有的是用户完成,有的是sdk完成。
最后断开相机并清理工作环境。
3.中断响应操作
当相机一帧采集完成后,自动跳转进入中断回调函数,这里分了两种中断回调函数。
第一种为简单的取buffer->处理->放回。
第二种结合windows的消息队列,在此处再给一个“处理队列”,给处理一个缓冲时间。
这里的处理包括常见的图像处理、计算和显示及rawdata拼装为图像等用到buffer的地方。
前面也说过,常用的是中断响应处理,除此之外,自己去查询buffer填充状态并作相关同步操作在某些场合也会用到,这个请查询不同相机sdk给出的同步方案。
差不多所有的工业相机sdk都是这样的编程模型和流程,avt 1394相机和basler camera link相机和avt gige相机相关代码在笔者网站可下载,还有之前讲的basler pylon sdk相机编程,他们基本流程都是一样,恕不详述!
二、 工业相机sdk接口使用总结
相机调用 :
我们利用相机采集图像,首先要对相机进行相关参数设置及控制,这需要对相机的sdk包比较了解,一般相机厂家都会提供相机sdk,其中包含用户手册和调用demo,这些都大大降低了调用门槛,提高了二次开发用户的效率。目前用过balser、海康、大华等相机,其实都是一个套路,都是按照下面几个步骤进行的。
1)枚举设备
2)创建句柄
3)打开设备
4)开始抓图
5)获取一帧并保存图像
6)停止抓图
7)关闭设备
8)销毁句柄
相机同步:
若是开发过程中用到双目或者多目的话,则需要外接同步触发器或者外部触发信号,通过相机同步触发线来实现同步问题。以实际应用过的basler aca1300-200uc为例,其相机同步触发线具体类型如下:
1 -—— +12 vdc 红
2 —— i/o input 1 黄
3 —— vcc(加电阻) 蓝
4 —— i/o out 1 绿
6 —— dccam power gnd 黑
0000—— i/o gnd 白
三、 basler pylon工业相机sdk的使用
pylon库有c++ .net等各种封装版本,一般用c++版本,功能全面效率高,但对于不同接口(gige usb3.0 cameralink)的相机必须对应使用不同的类,之间不能通用。
基于genapi通用相机抽象接口使用的是node结构,以字符串形式访问相机参数,可以统一管理不同接口类型的相机。但效率低,使用不方便。
pylon高层用c++封装,形成本地相机对象
如何管理多个相机,最靠谱的方法是按相机id标定顺序,需要读一个配置文件,比如xml或json,然而一开始不知道id,需要先列举出来。
四、pylon 以实时图像采集讲解pylonc sdk使用流程
一般的对于提供硬件编程来说,硬件生产厂家都会提供好sdk使用的手册和实例。手册中一般包括安装和配置流程,一些基本概念的介绍,sdk每个函数使用,sdk使用流程和实例(有些硬件实例直接写在手册中,有些会以单独文件存在,还有的两者皆有)。对于上位机软件开发人员来说拿到一个硬件上位机编程任务。
首先应该阅读了解其sdk概念,再按照其介绍的sdk开发流程阅读其提供的实例,修改相应的实例为自己所用,有不懂的函数查询一下其用法即可。有些开发人员习惯性的去记其api,这是费时费力的做法,并不推荐。下面主要以实时图像采集讲解basler相机的pylonc sdk的使用流程。
pylonc sdk的使用的总体流程图如下

下面是其中对于不同的工作要求,加载相机对象和卸载相机对象是通用的。而要使用其他模块,如事件对象时,相应的改为加载事件对象和卸载事件对象,以及使用事件对象完成相关任务即可。编程时一定要对整个流程做好规划,特别是硬件编程时一定留意内存泄露,前面分配的资源一定要在后面释放。
下面是五个大流程的详细解析,需要的地方已经加以说明,并注解了需要用到的函数
加载相机对象:
卸载相机对象:
加载数据流抓取对象:
卸载数据流抓取对象:
单帧或连续抓图过程:
按照以上介绍的流程即可实现实时图像采集:
在工业控制当中,用到basler工业相机sdk编程,主要是使用c或者c++,当项目庞大时,又需要良好的用户界面,用c++是不错的选择。
以实例和看过的一些参照讲讲pyloncppsdk使用流程。
首先,同c一样,这里给出一个bolg链接,写的不错,即上面文大侠这篇http://blog.csdn.net/wenzhou1219/article/details/7543420。
从中我们知道,总的开发流程图如下

那么,用c++开发也大抵如此。
这里我们看一个basler的cpp sample:
把这个和上面的流程图对比理解,再看看文档和sdk的结构,理解起来就容易多了。
五、关于使用维视工业相机 sdk 采集图像的问题
问:最近一直在研究怎么用相机的sdk采集图像且能实时采集。用的维视mv-1300uc,它提供了demo,还有说明文档(一些函数的定义),我发现例子里面没有给出类,就直接定义类中的函数,看不明白。有开发经验的老师吗?给点指导,自己一个人学习一点进展也没有,谢谢!
答:
引用
工业相机的sdk,为了通用性应该提供的是c接口
既然如此,例子中的类应该就只限那个例子有效,并不是使用该相机必须的
只要你看懂了每个函数的功能,用不着照抄例子中使用的类
有包含文件(.h)和静态链接库(.lib)我看了例子都没有看到主函数基本都是void 类名::函数名(){ }这种形式。
所以说你的问题在于看不懂例程,而不是看不懂相机开发包
一般工控领域提供的例程都是mfc程序,你到里面找main函数当然找不到
问:哦,这样啊,老师你有这方面的经验吗?这个东西我都弄了两周了,还是无从下手,难怪我还一直找主函数。给的说明文档我都看了好几遍了,感觉例子里面用到的也不多,自己想把里面的函数单独拿出来来实现功能,参数经常发生错误。
答:你说的这款相机我没用过。
建议你简单学习一下mfc。工控方面的编程用mfc比较多,毕竟搞工控的都不是专业程序员,没精力去专研那些复杂先进的软件技术,mfc算是最普及最简单的图形界面库了。
相机的话,应该是程序启动时【open】,关闭时【close】,采集图像前需要【设置采集参数】,采集单幅图像可以随时【采集】,采集连续图像的话需要【start】和【stop】,start前要【设置连续采集参数】大多还需要【设置回调函数】。你可以去找这些功能的函数以及它们在例程中的位置和用法,配合mfc简单编程的学习,应该能快一点上手吧。
转自:csdn论坛
六、工业相机sdk之opencv二次开发
做视觉的第一步是选好相机镜头等硬件设备,接下来就是将自己开发的算法在硬件上实现。我最近做一个项目,实现了一下opencv在相机sdk上的运用,下面小结一下具体实现步骤.
1. 安装相机自带的驱动和sdk开发包;
2. 用vs2010新建一个工程,配置好sdk的动态链接库(或者静态),具体动态链接库的使用可参见孙鑫的那本书,这里不多说;
3. 条用sdk开发包中的函数建立相机和pc机件的链接;
4. 建立视频流数据,设立一个回调函数(具体参见各sdk),并将数据拷贝到mat中的data中;
5. 有了opencv中的mat数据结构,接下来就可以实现我们的各种算法了。

芯动神州发布DAC2163LFP-500高速DAC芯片
电容器充电器的制作教程
详解计算机缓存Cache以及Cache Line
5G智慧医疗未来的发展会是怎样的
制造行业应该怎样从生成式AI这项新兴技术中获益呢?
工业相机编程模型和流程及SDK接口使用
在STM32平台上实现基于汽车音频总线的解决方案
区域水稻田土壤-作物系统重金属污染高光谱遥感定量估测
中频炉有源滤波器怎么选择
硅基量子点激光器与硅波导单片集成进展
EMC滤波知多少
如何提升介质厚度匹准度来满足阻抗设计要求
利用CPLD器件和微处理器实现I2C总线控制器的应用方案
中国联通宣布在六城启动一号双终端业务,穿戴设备无需SIM卡
如何实现PCB过孔设计?
鸿蒙os系统有什么特点
长虹CN-9机型的电容通病
中京电子预计2023年亏损1.1亿至1.2亿,同比大幅收窄
芯华章完成数亿B轮融资 深耕EDA敏捷验证赋能系统创新
基于matlab免疫算法求解生产调度零等待问题