使用图像采集 GUI 和导出的 HDevelop 代码的性能冲突

Conflicting performance using Image acquisition GUI and the exported HDevelop code

我有一个带有相机和闪光灯系统的设置,当它与 HDevelop 中的图像采集 GUI 一起使用时,可以提供适当的性能。即,使用闪光灯触发一次的图像捕获。我转到代码生成选项卡并导出相同的代码,执行时我得到另一个性能。即用闪光灯触发两次拍摄的图像。我一直无法查明问题所在。

下面是使用上述代码生成选项卡 ​​GUI 导出的代码

open_framegrabber ('GigEVision', 0, 0, 0, 0, 0, 0, 'default', -1, 'default', -1, 'false', 'default', camID , 0, -1, AcqHandle)
set_framegrabber_param (AcqHandle, 'DeviceTemperatureSelector', 'Main')
set_framegrabber_param (AcqHandle, 'TriggerSelector', 'FrameStart')
set_framegrabber_param (AcqHandle, 'EventSelector', 'AcquisitionStart')
set_framegrabber_param (AcqHandle, 'bits_per_channel', -1)
* Image Acquisition 01: Attention: The initialization may fail in case parameters need to
set_framegrabber_param (AcqHandle, 'AcquisitionMode', 'SingleFrame')
grab_image_start (AcqHandle, -1)
grab_image_async (Image, AcqHandle, -1)
* Image Acquisition 01: Do something
close_framegrabber (AcqHandle)

要了解正在发生的事情,您需要了解 HALCON 获取图像的两种不同方式,同步方式和异步方式。以及参数 AcquisitionMode 如何影响相机本身的采集。

采集模式

对于 GigE Vision 相机,相机必须具有的 AcquisitionMode 默认值为 'Continuous'。其他可能的值是 'SingleFrame'(您在发布的代码中使用的)和 'MultiFrame'(我现在将省略)。

连续

在此模式下,相机会不断获取图像,直到它被告知停止这样做。获取一张图像后,直接开始获取下一帧,或者如果相机设置为特定帧速率,则相机会等待,直到需要根据其设置获取下一张图像。

单帧

在此模式下,相机获取一张图像,然后暂停获取,直到被告知获取下一张图像。

同步抓取

运算符grab_image用于获取图像。执行此运算符时,将执行以下步骤:

  1. 如果任何图像仍在任何内部缓冲区中,它们将被丢弃。
  2. 相机被告知开始采集。
  3. 获取图像后,相机会被告知停止获取。
  4. 图片由grab_image算子传回

使用同步抓取的好处是,在您致电操作员后,您将始终获得由相机获取的图像。缺点是,清空缓冲区和 starting/stopping 相机上的采集需要时间,因此使用此模式并不总是能够达到相机的最大帧速率。另一个缺点是,当您为相机使用外部触发器时,同步抓取时可能会丢失触发信号。当触发信号在调用 grab_image 之前激活时,可能会发生这种情况。此时相机没有采集,触发信号被忽略。

如果您使用的是图像采集助手,那么当您按下 Snap 按钮时会发生这种情况。在您的设置中,这意味着对于单个 grab_image 调用,您将看到闪光一次。

异步抓取

相关运算符为grab_image_startgrab_image_async。还有一个重要的参数start_async_after_grab_async,默认设置为'enabled'。

在您发布的代码中,您通常首先调用 grab_image_start 启动相机采集,但在采集第一张图像后不会停止采集。相机接下来做什么取决于 AcquisitionMode 的设置('Continuous':持续采集,'SingleFrame':等待信号开始下一次采集).相机获取的所有图像都被发送到 HALCON 并存储在缓冲区队列中。当您调用 grab_image_async 时,将检索缓冲区队列中最早的图像。如果 start_async_after_grab_async 设置为 'enabled',在 grab_image_async 检索图像后立即向相机发送命令以获取下一张图像。如果在调用 grab_image_start 之前调用 grab_image_asyncgrab_image_async 内部调用 grab_image_start.

异步抓取的好处是(至少在 'Continuous' 模式下)采集始终处于活动状态并且不太可能丢失触发信号。缺点是您可能会从缓冲区队列中检索较旧的图像,或者在某些时候当图像检索速度不够快时队列已满。当图像处理时间长于图像采集之间的延迟时,这当然会发生。

异步抓取也是图像采集助手在您按下实时而不是快照按钮时所做的。

生成的代码

现在我们可以看看您发布的代码中发生了什么。您正在使用 grab_image_startgrab_image_asyncAquisitionMode 设置为 'SingleFrame' 和 start_async_after_grab_async设置为 'enable'.

    调用
  1. grab_image_start 并在相机上开始采集。获取图像时,闪光灯会闪光一次。由于 'SingleFrame' 模式,相机会暂停采集。
  2. 调用
  3. grab_image_async 并返回闪光灯首次闪光时获取的图像。因为在相机上采集没有停止,只是暂停了,并且因为启用了 start_async_after_grab_async,所以命令被发送到相机以开始下一次采集。因此,当获取下一张图像时,闪光灯会第二次闪光,然后相机再次等待下一条命令。

tl;dr

如果你想让相机只采集一张图像然后停止,你只需要更换线

grab_image_start (AcqHandle, -1)
grab_image_async (Image, AcqHandle, -1)

用单行

grab_image (Image, AcqHandle)