1

I have a setup with a camera and a flash system, which when used with the Image acquisition GUI within HDevelop gives me proper performance. i.e, image capture with the flash triggered once. I go to the Code generation tab and export the code for the same, and when executing I get another performance. i.e. image captured with the flash triggered twice. I have been unable to pinpoint the issue.

Below is the code exported using the above mentioned Code Generation tab 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)
MSK
  • 448
  • 2
  • 5
  • 18

1 Answers1

2

To understand what is happening you need to know about the two different ways of acquiring images HALCON has, a synchronous and an asynchronous one. And also how the parameter AcquisitionMode influences the acquisition on the camera itself.

AcquisitionMode

For GigE Vision cameras the default value for AcquisitionMode that is mandatory for the camera to have is 'Continuous'. Other possible values are 'SingleFrame' (which you are using in the code you posted) and 'MultiFrame' (which I will omit for now).

Continuous

In this mode the camera is continuously acquiring images until it is told to stop doing so. After one image is acquired, either the acquisition of the next frame starts directly, or if the camera is set to a specific frame-rate the camera waits until it needs to acquire the next image according to its settings.

SingleFrame

In this mode the camera acquires one image and then pauses the acquisition until it is told to acquire the next image.

Synchronous grabbing

The operator grab_image is used to acquire an image. When this operator is executed the following steps are performed:

  1. If any images are still in any internal buffer they are discarded.
  2. The camera is told to start the acquisition.
  3. After an image is acquired, the camera is told to stop the acquisition.
  4. The image is transferred and returned by the grab_image operator

The benefit of using synchronous grabbing is that you will always get an image that was acquired by the camera after you called the operator. The downside is, that emptying the buffers and starting/stopping the acquisition on the camera takes time, so it will not always be possible to reach the maximum frame-rate of a camera with this mode. Another downside is that when you are using an external trigger for your camera it can happen that you loose trigger signals when grabbing synchronously. This can happen when the trigger signal is activated before the call of grab_image. At this point the camera is not acquiring and the trigger signal is ignored.

If you are using the Image Acquisition Assistant this is what happens when you press the Snap button. In your setup this would mean that for a single grab_image call you will see the flash fire once.

Asynchronous grabbing

The relevant operators are grab_image_start and grab_image_async. There is also one more parameter start_async_after_grab_async that is important and that is set to 'enabled' by default.

As in the code you posted you usually first call grab_image_start which starts the acquisition on the camera, but does not stop it after the first image is acquired. What the camera does next depends on the setting of the AcquisitionMode ('Continuous': it keeps on acquiring, 'SingleFrame': it waits for a signal to start the next acquisition). All images the camera acquires are sent to HALCON and stored in a queue of buffers. When you call grab_image_async the oldest image in the buffer queue is retrieved. If start_async_after_grab_async is set to 'enabled', immediately after grab_image_async retrieves the image a command is sent to the camera to acquire the next image. In case of calling grab_image_async before calling grab_image_start, grab_image_async internally calls grab_image_start.

The benefit of asynchronous grabbing is that (at least in 'Continuous' mode) acquisition is always active and it is more unlikely to loose trigger signals. The downside is that you might retrieve an older image from the buffer queue or that at some point the queue is full when images are not retrieved fast enough. This of course happens when the image processing takes longer than the delay between the acquisition of the images.

Asynchronous grabbing is also what the Image Acquisition Assistant does when you press the Live instead of the Snap button.

The generated code

Now we can have a look at what happens in the code you posted. You are using grab_image_start, grab_image_async, AquisitionMode is set to 'SingleFrame' and start_async_after_grab_async is set to 'enable'.

  1. grab_image_start is called and acquisition is started on the camera. The flash fires once when the image is acquired. Because of the 'SingleFrame' mode the camera then pauses the acquisition.
  2. grab_image_async is called and the image that was acquired when the flash first fired is returned. Because acquisition was not stopped, only paused, on the camera and because start_async_after_grab_async is enabled a command is sent to the camera to start the next acquisition. So the flash fires a second time when the next image is acquired and then the camera again waits for the next command.

tl;dr

If you want the camera to only acquire one single image and then stop, you just need to replace the lines

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

with the single line

grab_image (Image, AcqHandle)
der_berni
  • 58
  • 9
  • thanks a lot for your response, that explanation really helped me. Basically what you suggested was to use the synchronous mode of image capture, which in fact causes the flash to fire once. The same implementation of single flash in asynchronous mode would be setting the start_async_after_grab_async to 'disable' and then grab_image_async, right? P.S. I have tried it and it does in fact fire the flash once – MSK Sep 03 '18 at 07:29