Library / SDK
genicam/harvesters avatar
genicam/harvesters

Harvesters: a Python front end for GenTL Producers and GenICam node maps

Image Acquisition Library for GenICam-based Machine Vision System

613 stars106 forksPythonApache-2.0

At a glance

What is it?
Harvesters wraps GenICam-compliant cameras and GenTL transport layers in a Python API built around add_file, update, create and fetch. It is a thin control and acquisition layer, not a capture framework with its own drivers, and the README shows both the shape of that API and how little it commits to about supported hardware.
Who is it for?
Adopt Harvesters if your camera already ships a GenTL Producer .cti file and you want to drive it from Python without writing C++ against the GenTL C API. Do not adopt it if you have no .cti for your hardware, or if you need a GUI or a recording pipeline out of the box.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 167 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What Harvesters actually removes from the acquisition loop

Machine vision cameras that follow GenICam expose their settings as a node tree, and the transport layer that moves pixels off the camera is described by the GenTL standard. In C++ and C, using those two standards means linking against a vendor producer, walking the node map by hand, and managing buffer queues yourself. Harvesters is a Python library that sits on top of that and presents the producer, the camera and the buffers through a small set of Python objects. The README states the aim plainly: to make image acquisition in a computer vision application easy, and it lists three features, acquisition through GenTL Producers, loading several producers in one script, and manipulation of GenICam feature nodes. The audience is therefore narrow and specific. It is for people who already have a GenICam camera and a GenTL producer file, and who want the acquisition part of their pipeline in Python rather than in a compiled layer. The README does not claim to support any particular camera vendor, and it does not ship a driver. Everything below the Python API comes from the producer you supply.

Harvester, ImageAcquirer and the buffer payload

The object model is visible in the IPython session the README reproduces. A Harvester instance is the top-level container. You point it at one or more GenTL producer files with add_file, then call update, after which device_info_list holds one dictionary per discovered device. Each dictionary carries display_name, id_, model, serial_number, tl_type, user_defined_name, vendor and version. You select a device by index with create, which returns an ImageAcquirer. That acquirer holds a remote_device whose node_map is the GenICam feature tree, so width, height and pixel format are set as attributes on node_map rather than through a vendor SDK call. Acquisition starts with ia.start() and each frame arrives from ia.fetch(), used as a context manager. The fetched buffer has a payload, and payload.components is a list. For a single 2D image the README takes index 0 and reads component.data, component.height and component.width, then reshapes the flat array. The README notes that the number of components can vary and that a multi-part transmission would produce two or more entries, which is the detail that separates this from libraries that assume one frame equals one image. Teardown is explicit: ia.stop(), ia.destroy(), h.reset().

Installation and the first ten lines of code

The package is distributed on PyPI as harvesters, and the README links that page plus the Read the Docs site. Installation is a normal pip install, and the import path shown in the session is from harvesters.core import Harvester. There is no configuration file and no environment variable in the material; the only required input is the path to a GenTL producer, given as an absolute path ending in .cti. The README example uses /Users/kznr/dev/genicam/bin/Maci64_x64/TLSimu.cti, which is the EMVA simulation producer, and the resulting device_info_list has four entries with vendor EMVA_D and version 1.2.3. From there the sequence is h.add_file(path), h.update(), h.create(index), set node_map values, ia.start(), and a with ia.fetch() as buffer block. Because add_file can be called more than once, a single script can hold producers for different transport layers at the same time, which the README presents as the main benefit of the GenTL standard. The library does not bundle a producer, so the first thing to verify on any machine is that the .cti file exists and that its architecture matches the Python interpreter.

The producer is the dependency, and that is the weak point

Harvesters cannot talk to a camera without a GenTL producer. If your vendor does not ship a .cti file for your operating system and CPU architecture, the library has nothing to load, and no amount of Python will change that. The README's own example uses the EMVA simulation producer rather than a physical camera, which is a reasonable documentation choice but also a hint about how much of the real work happens outside this repository. Producer quality varies: buffer handling, timestamping and reconnect behaviour belong to the vendor, not to Harvesters, so a bug in the transport layer will surface as a bug in your Python script. A second limitation is the explicit lifecycle. You must call start, fetch, stop and destroy in the right order, and the README shows reset on the Harvester object at the end. There is no background thread or callback model described in the material, so a fetch loop is yours to write. Finally, the release history is uneven. Version 1.4.1 is marked Discontinued in its own release title, 1.4.2 followed in February 2023 and 1.4.3 in May 2024. That is not a project in rapid motion, and anyone planning to depend on it should read the issue tracker before assuming a fix will arrive quickly.

Harvesters against a vendor Python SDK

The obvious alternative is the Python wrapper each camera vendor publishes alongside its SDK. Those wrappers are usually generated or hand-written bindings to a C library, and they expose vendor-specific function names, vendor-specific enums and a vendor-specific buffer model. They tend to cover features that GenICam does not standardise, such as firmware update or vendor diagnostics. Harvesters takes the opposite position: it implements the standard and nothing else, so the same script works against any producer that conforms. The practical difference shows up when you have two cameras from different vendors. With vendor SDKs you maintain two code paths. With Harvesters you call add_file twice and select devices by index, though the README does not show a worked multi-vendor example, only the statement that multiple producers can be loaded. The trade is that Harvesters gives you less than a vendor SDK does, and when a producer misbehaves you are debugging someone else's C code through a Python layer.

The GUI is a separate project, not a feature flag

The README points to harvester_gui as a sister project for anyone who wants to look at image data rather than write a fetch loop. That is a deliberate split, and it means Harvesters itself ships no viewer, no recording format and no calibration tooling. If your goal is to check focus or exposure interactively, the library alone will not do it. The README also points to a wiki FAQ and the issue tracker, which is where the practical answers about producer configuration appear to live rather than in the main documentation. The IPython example ends by suggesting Matplotlib for visualisation in a notebook, which is a fair description of the intended workflow: acquire in Harvesters, inspect and process in the rest of the scientific Python stack. It also means the reshape step is on you. The payload gives a flat array plus width and height, and the README shows component.data.reshape(component.height, component.width) as the conversion.

Licence and the cost of staying current

Harvesters is released under Apache License 2.0, and the README states that you can use, modify and distribute it for personal, internal or commercial purposes without worrying about the effect on your own software. That is a permissive licence, which matters here because the library is meant to be embedded inside a larger application. It does not cover the GenTL producer, which is a separate binary from your camera vendor and carries its own terms. The maintenance picture is a single Python package with a small dependency surface and no server component, so upgrading is a pip install away. The real cost is not the upgrade, it is the revalidation: a new producer version can change buffer behaviour, and a new Harvesters version can change the acquirer API. The gap between 1.4.2 in February 2023 and 1.4.3 in May 2024 suggests you should pin the version you validate against rather than tracking the latest release.

Editorial conclusion

Adopt Harvesters if your camera already ships a GenTL Producer .cti file and you want to drive it from Python without writing C++ against the GenTL C API. Do not adopt it if you have no .cti for your hardware, or if you need a GUI or a recording pipeline out of the box. Before committing, install the package, call add_file on your vendor's producer, run update, and confirm that device_info_list is non-empty and that create(0) returns an acquirer whose node_map exposes the features you actually set on the camera.

Official sources

  1. genicam/harvesters on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
Community notes

Community notes