zoukankan      html  css  js  c++  java
  • 关于相机SDK开发

    网上找的一些资料,整理了一下,留着仔细看一看。

    内容纲要:

    1.工业相机编程模型和流程

    2.工业相机SDK接口使用总结

    3.Basler Pylon工业相机SDK的使用

    4.Pylon 以实时图像采集讲解PylonC SDK使用流程

    5.关于使用维视工业相机 SDK 采集图像的问题

    6.工业相机SDK之opencv二次开发

    1.工业相机编程模型和流程

    不同的工业相机提供不同的编程接口(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

    2. 工业相机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 白

    3. Basler Pylon工业相机SDK的使用

    Pylon库有C++ .Net等各种封装版本,一般用C++版本,功能全面效率高,但对于不同接口(GigE USB3.0 CameraLink)的相机必须对应使用不同的类,之间不能通用。

    基于GenAPI通用相机抽象接口使用的是Node结构,以字符串形式访问相机参数,可以统一管理不同接口类型的相机。但效率低,使用不方便。

    Pylon高层用C++封装,形成本地相机对象

    如何管理多个相机,最靠谱的方法是按相机ID标定顺序,需要读一个配置文件,比如XML或JSON,然而一开始不知道ID,需要先列举出来。

    4.Pylon 以实时图像采集讲解PylonC SDK使用流程

    一般的对于提供硬件编程来说,硬件生产厂家都会提供好SDK使用的手册和实例。手册中一般包括安装和配置流程,一些基本概念的介绍,SDK每个函数使用,SDK使用流程和实例(有些硬件实例直接写在手册中,有些会以单独文件存在,还有的两者皆有)。对于上位机软件开发人员来说拿到一个硬件上位机编程任务。

    首先应该阅读了解其SDK概念,再按照其介绍的SDK开发流程阅读其提供的实例,修改相应的实例为自己所用,有不懂的函数查询一下其用法即可。有些开发人员习惯性的去记其API,这是费时费力的做法,并不推荐。下面主要以实时图像采集讲解Basler相机的PylonC SDK的使用流程。

    PylonC SDK的使用的总体流程图如下:

    下面是其中对于不同的工作要求,加载相机对象和卸载相机对象是通用的。而要使用其他模块,如事件对象时,相应的改为加载事件对象和卸载事件对象,以及使用事件对象完成相关任务即可。编程时一定要对整个流程做好规划,特别是硬件编程时一定留意内存泄露,前面分配的资源一定要在后面释放。

    下面是五个大流程的详细解析,需要的地方已经加以说明,并注解了需要用到的函数

    加载相机对象

    卸载相机对象

    加载数据流抓取对象

    卸载数据流抓取对象

    单帧或连续抓图过程

    按照以上介绍的流程即可实现实时图像采集

    源代码下载链接:http://download.csdn.net/download/wenzhou1219/8721495 (点击阅读原文进入) 。很多人问我要源代码,翻了以前的程序文件夹找到了这个程序,演示了利用Pylon SDK进行相机采集的过程,使用MIL完成界面显示,采集部分封装成了类,可以直接重用。测试相机为Basler相机。注意Pylon仅完成Raw Data的采集,使用MIL的MbufPut完成图像数据的重组,然后MIL自动显示。

    转自:http://blog.csdn.net/wenzhou1219

    作者:文大侠

    在工业控制当中,用到basler工业相机sdk编程,主要是使用c或者c++,当项目庞大时,又需要良好的用户界面,用C++是不错的选择。

    以实例和看过的一些参照讲讲PylonCppSDK使用流程。

    首先,同C一样,这里给出一个bolg链接,写的不错,即上面文大侠这篇http://blog.csdn.net/wenzhou1219/article/details/7543420。

    从中我们知道,总的开发流程图如下:

    那么,用C++开发也大抵如此。

    这里我们看一个basler的cpp sample:

    把这个和上面的流程图对比理解,再看看文档和sdk的结构,理解起来就容易多了。

    5.关于使用维视工业相机 SDK 采集图像的问题

    问:最近一直在研究怎么用相机的SDK采集图像且能实时采集。用的维视MV-1300UC,它提供了DEMO,还有说明文档(一些函数的定义),我发现例子里面没有给出类,就直接定义类中的函数,看不明白。有开发经验的老师吗?给点指导,自己一个人学习一点进展也没有,谢谢!

    答:

    引用
    工业相机的SDK,为了通用性应该提供的是C接口

    既然如此,例子中的类应该就只限那个例子有效,并不是使用该相机必须的

    只要你看懂了每个函数的功能,用不着照抄例子中使用的类

    有包含文件(.h)和静态链接库(.lib)我看了例子都没有看到主函数基本都是void 类名::函数名(){ }这种形式。

    所以说你的问题在于看不懂例程,而不是看不懂相机开发包

    一般工控领域提供的例程都是MFC程序,你到里面找main函数当然找不到

    问:哦,这样啊,老师你有这方面的经验吗?这个东西我都弄了两周了,还是无从下手,难怪我还一直找主函数。给的说明文档我都看了好几遍了,感觉例子里面用到的也不多,自己想把里面的函数单独拿出来来实现功能,参数经常发生错误。

    答:你说的这款相机我没用过。

    建议你简单学习一下MFC。工控方面的编程用MFC比较多,毕竟搞工控的都不是专业程序员,没精力去专研那些复杂先进的软件技术,MFC算是最普及最简单的图形界面库了。

    相机的话,应该是程序启动时【Open】,关闭时【Close】,采集图像前需要【设置采集参数】,采集单幅图像可以随时【采集】,采集连续图像的话需要【Start】和【Stop】,Start前要【设置连续采集参数】大多还需要【设置回调函数】。你可以去找这些功能的函数以及它们在例程中的位置和用法,配合MFC简单编程的学习,应该能快一点上手吧。

    转自:CSDN论坛

    6.工业相机SDK之opencv二次开发

    做视觉的第一步是选好相机镜头等硬件设备,接下来就是将自己开发的算法在硬件上实现。我最近做一个项目,实现了一下Opencv在相机SDK上的运用,下面小结一下具体实现步骤.

    1. 安装相机自带的驱动和SDK开发包;

    2. 用VS2010新建一个工程,配置好SDK的动态链接库(或者静态),具体动态链接库的使用可参见孙鑫的那本书,这里不多说;

    3. 条用SDK开发包中的函数建立相机和PC机件的链接;

    4. 建立视频流数据,设立一个回调函数(具体参见各SDK),并将数据拷贝到Mat中的data中;

    5. 有了opencv中的Mat数据结构,接下来就可以实现我们的各种算法了。

    我使用的是LuCam相机,由于时间关系没有研究很深入

    转自:http://blog.sina.com.cn/s/blog_662c78590100zslr.htm

  • 相关阅读:
    java web项目打包.war格式
    version 1.4.2-04 of the jvm is not suitable for thi
    Sugarcrm Email Integration
    sharepoint 2010 masterpage中必须的Content PlaceHolder
    微信开放平台
    Plan for caching and performance in SharePoint Server 2013
    使用自定义任务审批字段创建 SharePoint 顺序工作流
    Technical diagrams for SharePoint 2013
    To get TaskID's Integer ID value from the GUID in SharePoint workflow
    how to get sharepoint lookup value
  • 原文地址:https://www.cnblogs.com/eve612/p/13841736.html
Copyright © 2011-2022 走看看