Grabbing an Image

This article shows in detail how to set up a data stream from a video capture device and grab a single image.

Opening and Configuring the Video Capture Device

First, the library is initialized, and the first available video capture device is opened:

import imagingcontrol4 as ic4
ic4.Library.init()

# Create a Grabber object
grabber = ic4.Grabber()

# Open the first available video capture device
first_device_info = ic4.DeviceEnum.devices()[0]
grabber.device_open(first_device_info)

Then, the device has to be configured. This step is important because in most situations, programs want the camera to be in a defined state before starting operation. In this example, the resolution is configured using the device’s PropId.WIDTH and PropId.HEIGHT properties:

# Set the resolution to 640x480
grabber.device_property_map.set_value(ic4.PropId.WIDTH, 640)
grabber.device_property_map.set_value(ic4.PropId.HEIGHT, 480)

At this point, an application could also load a prepared device configuration file (using Grabber.device_open_from_state()) or apply a serialized property configuration using PropertyMap.deserialize().

Setting up the Sink and Data Stream

After the device has been configured, it is time to setup a data stream. To receive image data from the video capture device, a Sink object has to be created. The SnapSink is the sink most suitable to grab images on demand:

# Create a SnapSink. A SnapSink allows grabbing single images (or image sequences) out of a data stream.
sink = ic4.SnapSink()
# Setup data stream from the video capture device to the sink and start image acquisition.
grabber.stream_setup(sink, setup_option=ic4.StreamSetupOption.ACQUISITION_START)

The data stream is established by calling Grabber.stream_setup(), passing the sink as a parameter. We also set the setup_option parameter to StreamSetupOption.ACQUISITION_START, so that the device is instructed to start image acquisition immediately after the data stream was created.

After the Grabber.stream_setup() call returned successfully, the device is continuously sending images to the host computer.

Grabbing an Image

By calling SnapSink.snap_single(), the sink is instructed to wait for the next image to arrive at the sink and, if an image is received during the specified timeout period, return it:

try:
    # Grab a single image out of the data stream.
    image = sink.snap_single(1000)

    # Print image information.
    print(f"Received an image. ImageType: {image.image_type}")

    # Save the image.
    image.save_as_bmp("test.bmp")

except ic4.IC4Exception as ex:
    print(ex.message)

In this example, we print information about the received image and save it in a bitmap file.

Both SnapSink.snap_single() and ImageBuffer.save_as_bmp() could potentially fail. Therefore, we wrap the code into a try..except block to print the error message in case an error occurs.

Stopping the Data Stream

A call to Grabber.stream_stop() stops the data stream:

# Stop the data stream.
grabber.stream_stop()

Stopping acquisition and data stream is important, because keeping the acquisition active would waste CPU and memory resources as well as bandwidth on the transmission medium.