FG Camera Library  1.7.3.0 (2026-04-13)
Loading...
Searching...
No Matches
Python

How to use the Python bindings.

Note
Please take a look at the Linux SDK documentation on how to install the Python bindings.

The C functions for this library are implemented by the Python module fg.

The Pyton API reference for the module briefly describes the function arguments and return values. Refer to this documentation for a detailed description.

C API comparison

  • C API:
    • All functions return a UINT32 value to indicate the status of each function.
    • Additional function results are returned by passing pointer arguments.
  • Python API:
    • Functions will raise a Python exception in case of an error.
    • Function results are regular return values of the function. Mupltiple result values are returned as a tuple.
    • Image buffers are represented by the 'voidptr' object which implements the Python buffer protocol.
    • Enumerations are implemented by enum.Enum objects.

Examples

Python examples can be found in the following SDK folder:
/opt/ImagoTechnologies/SDK/python/examples

FG_Example.py: a basic acquisition example
#!/usr/bin/python3
# Prerequisites:
# The python bindings for the FG Camera Library (module 'fg') are installed automatically,
# if the package python3-pip is present during installation of the SDK.
# The bindings can be installed manually by running the following commands:
# $ apt install python3-pip
# $ python3 -m pip install --upgrade --no-index --find-links=file:///opt/ImagoTechnologies/SDK/python fg
# Import the fg module:
import fg
print("Initializing grabber...")
# initialize the camera using automatic type detection
fg.install_camera(fg.CAMERA_TYPE.Vxx_AUTO)
# set sensor AOI and pixel format if desired:
# fg.set_scan_param(x, y, width, height, 1, fg.PIXEL_TYPE.Y_8)
# set the exposure time:
# fg.set_shutter_time(1000)
# get the size of the recorded images (usually the sensor's size)
result = fg.get_image_size()
width = result[0]
height = result[1]
# allocate image buffers
imageList = []
for i in range(4):
imageList.append(fg.alloc_image())
# add buffers to the acquisition queue
for image in imageList:
fg.append_image(image)
# set trigger mode to free-run
fg.set_trigger_mode(fg.TRIGGER_MODE.FREERUN)
print("Starting acquisition loop, press CTRL-C to stop the program.");
while True:
try:
# wait for the next frame
result = fg.get_image(1000)
error = result[0]
if error == fg.ERROR_CODE.NoError:
ptr = result[1]
image_number = result[2]
if (image_number % 100) == 0:
print("Frame: {}".format(image_number))
# todo: work with the image data.
# For example, convert to numpy array:
# image = numpy.ndarray((height, width), dtype=np.uint8, buffer=ptr)
# add buffer to the acquisition queue again
fg.append_image(ptr);
elif error == fg.ERROR_CODE.BrokenImage:
# the buffer is valid, but the contents are invalid
print("get_image() returned a broken image")
ptr = result[1]
fg.append_image(ptr);
elif error == fg.ERROR_CODE.GrabTimeOut:
# timout occured, the image is invalid
print("get_image() timeout occured")
else:
# other errors
print("get_image() failed, error code: {}".format(error))
except KeyboardInterrupt:
break
# stop image acquisition
print("Stopping acquisition")
fg.stop_image()
# free buffers
for image in imageList:
fg.free_image(image)
# close the camera
fg.uninstall_camera()
FG_Live_OpenCV.py: this example uses OpenCV to display the camera image
#!/usr/bin/python3
# This example uses OpenCV to display the camera image.
# To use the virtual file camera, the script can be started with a folder name as argument
# containing the BMP files.
# To connect to a IMAGO GigE device, start the script with the IP address as argument.
# Prerequisites: See FG_Example.py
# A X11 server is required to run this example.
# A remote X11 server can also be used, for example by creating a X11 SSH tunnel with MobaXterm.
import sys
import os
import fg
try:
import numpy as np
import cv2 as cv
except:
raise RuntimeError("OpenCV not found, run 'apt install --no-install-recommends python3-opencv'")
def live(arg):
if arg == None:
print("Detecting camera...")
fg.install_camera(fg.CAMERA_TYPE.Vxx_AUTO)
print("Found {}".format(fg.get_camera_type().name))
elif os.path.exists(arg):
print("Installing BMP file camera using directory '{}'...".format(arg))
fg.install_camera(fg.CAMERA_TYPE.FILE_BMP)
fg.set_special_option("FilePath:{}".format(arg), 0)
print("{} BMP files found".format(fg.get_special_option("FileCount")))
else:
print("Installing GigE camera using IP address {}...".format(arg))
import socket
fg.install_camera(fg.CAMERA_TYPE.GigE_AUTO, socket.inet_aton(arg))
result = fg.get_scan_param()
width = result[2];
height = result[3] * result[4]; # scan_height * scan_count
print("Image size: {} x {}".format(width, height))
print("Pixel type: {}".format(result[5].name))
if (result[5] == fg.PIXEL_TYPE.RGBX_32):
print(" switching to RGB_24...")
fg.set_scan_param(result[0], result[1], result[2], result[3], result[4], fg.PIXEL_TYPE.RGB_24)
pixel_order = fg.get_pixel_order()
print("Pixel order: {}".format(pixel_order.name))
# allocate image buffers
imageList = []
for i in range(4):
imageList.append(fg.alloc_image())
# add buffers to the acquisition queue
for image in imageList:
fg.append_image(image)
# set trigger mode to free-run
fg.set_trigger_mode(fg.TRIGGER_MODE.FREERUN)
# create window
cv.namedWindow("Camera", cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO)
scale = int(width/1024) + 1;
cv.resizeWindow("Camera", int(width/scale), int(height/scale))
print("\nOpenCV window keys:")
if fg.get_camera_type() != fg.CAMERA_TYPE.FILE_BMP:
print(" '+': Increase exposure time")
print(" '-': Decrease exposure time")
print(" 'q': Exit")
while True:
key = cv.waitKey(1)
if key == ord('q'):
break
elif key == ord('+'):
# increase exposure time, ignore errors
try:
fg.set_shutter_time(fg.get_shutter_time() + 100)
except:
pass
print("Exposure: {} us".format(fg.get_shutter_time()))
elif key == ord('-'):
# decrease exposure time, ignore errors
try:
fg.set_shutter_time(fg.get_shutter_time() - 100)
except:
pass
print("Exposure: {} us".format(fg.get_shutter_time()))
# wait for the next frame
result = fg.get_image(1000)
error = result[0]
if error == fg.ERROR_CODE.NoError:
ptr = result[1]
image_number = result[2]
# create numpy array from image pointer
if (pixel_order == fg.PIXEL_ORDER.RGB):
image = np.ndarray((height, width, 3), dtype=np.uint8, buffer=ptr)
# swap red and blue channels
image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
elif (pixel_order == fg.PIXEL_ORDER.BGR):
image = np.ndarray((height, width, 3), dtype=np.uint8, buffer=ptr)
# copy image
image = image.copy()
else:
image = np.ndarray((height, width), dtype=np.uint8, buffer=ptr)
# De-bayer image if necessary
if pixel_order == fg.PIXEL_ORDER.Y:
image = image.copy()
if pixel_order == fg.PIXEL_ORDER.RG:
image = cv.cvtColor(image, cv.COLOR_BayerRG2RGB)
elif pixel_order == fg.PIXEL_ORDER.BG:
image = cv.cvtColor(image, cv.COLOR_BayerBG2RGB)
elif pixel_order == fg.PIXEL_ORDER.GR:
image = cv.cvtColor(image, cv.COLOR_BayerGR2RGB)
elif pixel_order == fg.PIXEL_ORDER.GB:
image = cv.cvtColor(image, cv.COLOR_BayerGB2RGB)
cv.putText(image, "Frame: {}".format(image_number), (30, 50),
cv.FONT_HERSHEY_SIMPLEX, 1.4, (128, 255, 128), 2, cv.LINE_AA)
# show the image
cv.imshow("Camera", image)
# add buffer to the acquisition queue again
fg.append_image(ptr);
elif error == fg.ERROR_CODE.BrokenImage:
# the buffer is valid, but the contents are invalid
print("get_image() returned a broken image")
ptr = result[1]
fg.append_image(ptr);
elif error == fg.ERROR_CODE.GrabTimeOut:
# timout occured, the image is invalid
print("get_image() timeout occured")
else:
# other errors
print("get_image() failed, error code: {}".format(error))
fg.stop_image()
for image in imageList:
fg.free_image(image)
fg.uninstall_camera()
cv.destroyAllWindows()
print("End.")
if __name__ == "__main__":
arg = None
if len(sys.argv) > 1:
arg = sys.argv[1]
live(arg)