Capturing Images with Hardware Trigger¶
When working with hardware trigger you need to make sure that the camera is continuously armed and waiting for a new trigger signal in order to not miss any trigger edges. The pseudo code opens a camera, enables hardware trigger and captures and processes a fixed number of images.
Code Examples¶
Using the Trigger and Retrieve commands and a polling wait loop
NxLibItem root; // References the tree's root item at path "/"
auto const serial = "1234"; // Replace with your camera's serial number
// References the camera's item at path "/Cameras/BySerialNo/<Serial Number>"
NxLibItem camera = root[itmCameras][serial];
// Call the Open command to open the camera
// Note: the variable name 'open' does not matter; the constant 'cmdOpen' specifies the name of the command to be
// executed when '.execute()' is called on the object.
NxLibCommand open(cmdOpen);
// Set parameters for the command
open.parameters()[itmCameras] = serial;
open.execute();
// Set the camera to trigger on a falling edge on the GPIO port
camera[itmParameters][itmCapture][itmTriggerMode] = valFallingEdge; // the default for TriggerMode is "Software"
for (int imageIndex = 0; imageIndex < 10; imageIndex++) {
// Trigger cameras that are not yet armed and waiting for a hardware trigger (e.g. when taking the first image).
// With default settings this will trigger untriggered cameras only.
NxLibCommand(cmdTrigger).execute();
// Call Retrieve in a loop to poll for newly arrived images; you could also use the Timeout parameter here if
// you don't want to poll
NxLibCommand retrieve(cmdRetrieve);
while (true) {
retrieve.parameters()[itmTimeout] = 0;
retrieve.execute();
if (retrieve.result()[serial][itmRetrieved].asBool()) {
// A new image has been received and copied into the raw image node
break;
}
}
// Trigger the camera again, so that it is immediately armed for the next trigger again
NxLibCommand(cmdTrigger).execute();
// Compute the disparity map, point map, and process the data according to your needs
}
* References the tree's root item at path "/"
open_framegrabber ('Ensenso-NxLib', 0, 0, 0, 0, 0, 0, 'default', 0, 'Raw', -1, 'false', 'Item', '/', 0, 0, RootHandle)
* Open the camera and reference the camera's item at path "/Cameras/BySerialNo/1234"
* replace "1234" with your camera's serial number
Serial := '1234'
open_framegrabber ('Ensenso-NxLib', 0, 0, 0, 0, 0, 0, 'default', 0, 'Raw', 'auto_grab_data=0', 'false', 'Stereo', Serial, 0, 0, CameraHandle)
set_framegrabber_param (CameraHandle, 'grab_data_items', 'Images/DisparityMap')
* Set the camera to trigger on a falling edge on the GPIO port
set_framegrabber_param (CameraHandle, 'Parameters/Capture/TriggerMode', 'FallingEdge')
for Index := 1 to 10 by 1
* Trigger cameras that are not yet armed and waiting for a hardware trigger (e.g. when taking the first image)
set_framegrabber_param (RootHandle, 'do_execute', 'Trigger')
while (1)
* Call Retrieve in a loop to poll for newly arrived images; you could also use the Timeout parameter here if you don't want to poll
set_framegrabber_param (RootHandle, 'exec:Parameters/Timeout', 0)
set_framegrabber_param (RootHandle, 'do_execute', 'Retrieve')
get_framegrabber_param (RootHandle, 'exec:Result/' + Serial + '/Retrieved', Retrieved)
if (Retrieved == 'true')
break
endif
endwhile
* Trigger the camera again, so that it is immediately armed for the next trigger again
set_framegrabber_param (RootHandle, 'do_execute', 'Trigger')
* Compute the disparity map, point map, and process the data according to your needs (see Grabbing 3D Data for an example on this)
* ...
endfor
Using the Capture command and a fixed wait timeout
When using the Capture command the entire trigger, wait and re-arm sequence can be accomplished with a single command:
for (int imageIndex = 0; imageIndex < 10; imageIndex++) {
NxLibCommand capture(cmdCapture);
// Trigger any camera that is not armed yet at the beginning of the command execution
capture.parameters()[itmInitialTrigger] = valUntriggered;
capture.parameters()[itmWaitFor] = valTriggered; // Wait for all triggered cameras
capture.parameters()[itmTimeout] = 10000; // wait up to 10 seconds
// After the wait period trigger all cameras again to arm them for the next hardware trigger signal
capture.parameters()[itmFinalTrigger] = valAll;
capture.execute(); // Execute the command with the previously specified parameters
// Compute the disparity map, point map, and process the data according to your needs.
// ...
}
for Index := 1 to 10 by 1
* Trigger any camera that is not armed yet at the beginning of the command execution
set_framegrabber_param (RootHandle, 'exec:Parameters/InitialTrigger', 'Untriggered')
* Wait for all triggered cameras
set_framegrabber_param (RootHandle, 'exec:Parameters/WaitFor', 'Triggered')
* wait up to 10 seconds
set_framegrabber_param (RootHandle, 'exec:Parameters/Timeout', 10000)
* After the wait period trigger all cameras again to arm them for the next hardware trigger signal
set_framegrabber_param (RootHandle, 'exec:Parameters/FinalTrigger', 'All')
* Call the Capture command with the previously specified parameters
set_framegrabber_param (RootHandle, 'do_execute', 'Capture')
* Compute the disparity map, point map, and process the data according to your needs (see Grabbing 3D Data for an example on this)
* ...
endfor
Note
See Grabbing 3D Data for an example on how to process data according to your needs.
Using the Capture command with a polling loop
You can also use the Capture command to trigger the camera and retrieve images by polling:
int imageIndex = 0;
while (imageIndex < 10) {
NxLibCommand capture(cmdCapture);
// Skip trigger phase 1 at the beginning of the command (see documentatio of the Capture command for a
// description of the execution phases)
capture.parameters()[itmInitialTrigger] = valNone;
// Don't wait for any cameras; the command will still retrieve images in phase 2 if they are ready
capture.parameters()[itmWaitFor] = valNone;
// Re-arm all idle cameras again for the next hardware trigger signal
capture.parameters()[itmFinalTrigger] = valUntriggered;
// Execute the command with the previously specified parameters
capture.execute();
// Check if an image has been retrieved; you need to know the camera serial number ("1234") to query the flags
// for the camera of interest.
if (capture.result()["1234"][itmRetrieved].asBool()) {
// Compute the disparity map, point map, and process the data according to your needs
// ...
imageIndex++;
}
}
NumImages := 0
while (NumImages < 10)
* Skip trigger phase 1 at the beginning of the command (see Capture for a description of the execution phases)
set_framegrabber_param (RootHandle, 'exec:Parameters/InitialTrigger', 'None')
* Don't wait for any cameras; the command will still retrieve images in phase 2 if they are ready
set_framegrabber_param (RootHandle, 'exec:Parameters/WaitFor', 'None')
* Re-arm all idle cameras again for the next hardware trigger signal
set_framegrabber_param (RootHandle, 'exec:Parameters/FinalTrigger', 'Untriggered')
* Call the Capture command with the previously specified parameters
set_framegrabber_param (RootHandle, 'do_execute', 'Capture')
* Check if an image has been retrieved; you need to know the camera serial number to query the flags for the camera of interest.
get_framegrabber_param (RootHandle, 'exec:Result/' + Serial + '/Retrieved', Retrieved)
if (Retrieved == 'true')
* Compute the disparity map, point map, and process the data according to your needs (see Grabbing 3D Data for an example on this)
* ...
NumImages := NumImages + 1
endif
endwhile
Note
See Capture for a description of the execution phases.
See Grabbing 3D Data for an example on how to process data according to your needs.