天天看点

DALSA工业相机工作流程

由于种种原因,智能检测项目只分开购买了设备,打算所有的软件设备都自行研发,购买的硬件设备分别是I/O控制板、触发板、相机。

I/O控制板控制沉箱门开关,触发板控制相机开关(激光外触发),在相机拍照后则还需要编写采集程序。

由于采集程序中必需的DALSA.SaperaLT.SapClassBasic和HalconDotNet都是DLL,HalconDotNet还好说,跟opencv一样都是图像处理的,opencv都有jar包版,那halcon应该也有。但是DALSA.SaperaLT.SapClassBasic这个就难办了,因为这家德国工业相机制造商,只提供了dll版本的开发库,找遍了网上也没有jar包版本,考虑到内部结构不复杂,用JNative跨平台开发阻力太大,所以决定采集程序部分用C#来执行,实属无奈之举。

其他的大部分485串口控制程序已经由JAVA写好,当初也费了不少力气,也不想再迁移至C#平台。

这样一来整个流程就拆成了几分,分别在java和C#两个平台上执行。

采集线性流程如下:

1.相机初始化(常态不循环),只在控制台开启时执行一次,包括加载配置文件------C#

2.从redis缓存获取车辆数据,并针对轨道区段和偏移量进行判断,执行评率为500ms一次------java

3.如果符合条件,串口控制I/O板打开沉箱门------java

4.执行Grab()函数开始采集------C#

5.利用halcon从内存中获取裸数据------C#

6.串口发送速度信号(W20.0km/hd),控制触发板,通过外触发方式启动相机,并开始拍照------java

7.发送TTL信号,关闭激光从而关闭相机,结束拍照------java

8.执行Freeze()函数结束采集------C#

以上8条就是一个完整的工业相机控制、拍照、采集的流程。有几个点需要说明:

1.第5条中利用halcon从内存中获取数据,不一定要放在4和6中间的位置,也可以放在4之前的其他地方,但是一定要在外触发信号(第6条之前)。

2.Grab()这个函数只需要执行一次,没有图像就不会中断调用回调函数,就不会通知你,也就是说是图像告诉你去取,而不是你轮训去问,数据是推送的,没有就不推送。

可以看到1-8中,1.4.5.8是用C#来跑的,2.3.6.7是java来跑的,这之间很多是有先后顺序的,也就是说需要两个项目有所沟通,下面讲述一下程序执行方案。

首先是执行C#控制台程序,相机初始化,一次控制台程序只执行一次;然后是java代码取缓存数据进行判断,循环执行,如果判断ok就控I/O板;I/O打开之后,C#执行Grab()方法,并利用halcon从内存获取数据;Grab()函数执行后,java控触发板,开相机,拍照直到某次缓存判断结果为false就TTL信号停止拍照并关闭相机;关闭相机之后C#代码执行Freeze()方法,结束采集,流程结束。

以上流程可以看出,有多处地方C#和java程序之间,必须要有通信,要有一个信号告诉对方,可以执行下一步骤了,如果没有信号,也就是说上一步执行出错了,那么接下来也不允许执行。这时候,进程间通信就必须走上舞台了来解决这个问题,我曾经想过一个解决方案,就是在一个固定路径(java程序和C#程序在同一台工控机运行),进行文件的创建、读取、删除操作,把这个文件的存在与否当成一个信号,来解决信号问题,但是想了想还是算了,有点太笨了,还是用进程通信吧,顺便可以研究研究这个没接触过的领域,在下一篇博客中将分享C#和java的进程通信方法和demo。