工业相机编程模型和流程

不同的工业相机提供不同的编程接口(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相机编程,他们基本流程都是一样,恕不详述!

原创,转载请注明来自http://blog.csdn.net/wenzhou1219

时间: 2024-10-25 01:48:50

工业相机编程模型和流程的相关文章

Linux的I/O模式、事件驱动编程模型

大纲: (1)基础概念回顾 (2)Linux的I/O模式 (3)事件驱动编程模型 (4)select/poll/epoll的区别和Python示例 网络编程里常听到阻塞IO.非阻塞IO.同步IO.异步IO等概念,总听别人装13不如自己下来钻研一下.不过,搞清楚这些概念之前,还得先回顾一些基础的概念. 1.基础知识回顾 注意:咱们下面说的都是Linux环境下,跟Windows不一样哈~~~ 1.1 用户空间和内核空间 现在操作系统都采用虚拟寻址,处理器先产生一个虚拟地址,通过地址翻译成物理地址(内

jQuery插件编写及链式编程模型小结

JQuery极大的提高了我们编写JavaScript的效率,让我们可以愉快的编写代码,做出各种特效.大多数情况下,我们都是使用别人开发的JQuery插件,今天我们就来看看如何把我们常用的功能做出JQuery插件,然后像使用jQuery那样来操作DOM.  一.jQuery插件开发快速上手 1.jQuery插件模板 关于jQuery插件的编写,我们可以通过为jQuery.fn增加一个新的函数来编写jQuery插件.属性的名字就是你的插件的名字,其模板如下: (function($){ $.fn.m

jQuery插件编写及链式编程模型

jQuery插件编写及链式编程模型小结 JQuery极大的提高了我们编写JavaScript的效率,让我们可以愉快的编写代码,做出各种特效.大多数情况下,我们都是使用别人开发的JQuery插件,今天我们就来看看如何把我们常用的功能做出JQuery插件,然后像使用jQuery那样来操作DOM.  一.jQuery插件开发快速上手 1.jQuery插件模板 关于jQuery插件的编写,我们可以通过为jQuery.fn增加一个新的函数来编写jQuery插件.属性的名字就是你的插件的名字,其模板如下:

Atitit..组件化事件化的编程模型--(2)---------Web datagridview 服务器端控件的实现原理and总结

Atitit..组件化事件化的编程模型--(2)---------Web datagridview 服务器端控件的实现原理and总结 1. 服务端table控件的几个流程周期 1 1.1. 确认要显示的字段(开始渲染) 1 1.2. 确认要显示的title 1 1.3. 格式化 1 2. Render显示级别 1 2.1. 简单化...grid.toHTML(); 1 2.2. 有些设置(title,field) 1 2.3. 完全的的设置(模板机制) 1 3. 服务器端控件跟模板的分离实现 2

Atitit . 编程模型的变革总结

Atitit . 编程模型的变革总结 1. 面向对象与面向过程程序设计有如下不同:  1 1.1. 函数与数据是否分离.... 1 1.2. 以功能为中心;以数据为中心..... 1 1.3. 事件驱动 2 1.4. 继承和多态 2 2. 面向对象的弊端 2 2.1.  OO的弊端就是:设计抽象和封装的时间远远超过你解决问题的时间. 2 2.2. 复杂的数据类型 2 2.3. 并发编程/并行计算/多核编程 2 2.4. "面向对象编程语言的问题在于,它总是附带着所有它需要的隐含环境. 2 2.5

嵌入式 Linux网络编程(二)——TCP编程模型

嵌入式 Linux网络编程(二)--TCP编程模型 一.TCP编程模型 TCP编程的一般模型如下图: TCP编程模型分为客户端和服务器端编程,两者编程流程如下: TCP服务器端编程流程: A.创建套接字: B.绑定套接字: C.设置套接字为监听模式,进入被动接受连接状态: D.接受请求,建立连接: E.读写数据: F.终止连接. TCP客户端编程流程: A.创建套接字: B.与远程服务器建立连接: C.读写数据: D.终止连接. 二.TCP迭代服务器编程模型 TCP循环服务器接受一个客户端的连接

朴素、Select、Poll和Epoll网络编程模型实现和分析——朴素模型

做Linux网络开发,一般绕不开标题中几种网络编程模型.网上已有很多写的不错的分析文章,它们的基本论点是差不多的.但是我觉得他们讲的还不够详细,在一些关键论点上缺乏数据支持.所以我决定好好研究这几个模型.(转载请指明出于breaksoftware的csdn博客) 在研究这些模型前,我决定按如下步骤去做: 实现朴素模型 实现发请求的测试程序 实现Select模型,测试其效率 实现Poll模型,测试其效率 实现Epoll模型,测试其效率 分析各模型性能,分析和对比其源码 针对各模型特点,修改上述程序

linux-socket tcp客户端服务器编程模型及代码详解

上一篇文章介绍了 TCP/IP相关协议,socket通信流程和涉及到的各种函数: Socket简单理解 本篇将具体解释tcp客户端服务器编程模型相关的代码 文章分为4个部分: 1. TCP客户端服务器编程模型流程图 2. 网络字节序与主机字节序 3. TCP编程的地址结构 4. 详细案例代码及解释 一: TCP客户端服务器编程模型流程图 上面两张图片将整个流程已经说明的很清楚了; 二: 网络字节序与主机字节序 字节序即是保存数据的方向方式, 分为 大端存储 和 小端存储; 其中 网络字节序 使用

MapReduce编程模型及优化技巧

(一)MapReduce 编程模型 (备注:如果你已经了解MapReduce 编程模型请直接进入第二部分MapReduce 的优化讲解) 在学习MapReduce 优化之前我们先来了解一下MapReduce 编程模型是怎样的? 下图中红色的标注表示没有加入Combiner和Partitioner来进行优化. 上图的流程大概分为以下几步. 第一步:假设一个文件有三行英文单词作为 MapReduce 的Input(输入),这里经过 Splitting 过程把文件分割为3块.分割后的3块数据就可以并行