harvesters

repository·master·Indexed 20 days ago

https://github.com/genicam/harvesters

A Python-based image acquisition engine that leverages the GenTL standard to provide a unified interface for interacting with GenICam compliant cameras across different transport layers. It enables loading GenTL Producers (.cti files), enumerating devices, manipulating GenICam feature nodes, and acquiring images as NumPy arrays.

Tokens
11.2K
Snippets
33
Records
51
Agent score
68%

What's inside harvesters

  1. What is Harvester?

    master

    Harvester is a Python library designed to simplify the image acquisition process in computer vision applications. It acts as an image acquisition engine that gathers image data from GenTL Producers and stores it in buffers.

    Key capabilities include:

    • Image acquisition via GenTL Producers.
    • Support for loading multiple GenTL Producers within a single Python script, allowing for various transport layers.
    • Manipulation of GenICam feature nodes for device configuration.
  2. Harvester Terminology and Architecture

    master

    Understanding the relationship between these components is key to using Harvester:

    • Harvester: The main image acquisition engine.
    • GenTL Producer: A library with a C interface that hides transport layer details (e.g., GigE, USB) from the consumer.
    • GenTL-Python Binding: The module that allows Python to communicate with GenTL Producers.
    • GenApi-Python Binding: A module that communicates with the GenICam GenApi reference implementation.
    • GenICam compliant device: Typically a camera that can be dynamically configured/controlled via the GenApi binding.
    • Harvester GUI: A separate graphical user interface project based on Harvester.
  3. Install a GenTL Producer

    master

    Harvester requires a GenTL Producer to acquire images from GenICam compliant cameras.

    • Compatibility: Harvester supports only 64-bit versions of GenTL Producers.
    • Finding Producers: Once an SDK is installed, you can locate the appropriate producer by searching for files with the .cti extension.
    • Example: The MATRIX VISION SDK (mvGenTL_Acquire, formerly mvIMPACT_Acquire) is a reliable option that does not block cameras from other competitors.
    • More options: A list of other reliable GenTL Producers is available on the project's Wiki.
  4. Get started with Harvester installation and tutorials

    master

    For detailed setup and workflow instructions, refer to the following documentation files:

    • Installation: See docs/INSTALL.rst for installing Harvester and its prerequisites.
    • Tutorial: See docs/TUTORIAL.rst for a guide on a typical image acquisition workflow.
  5. Typical Harvester Workflow Overview

    master

    A standard image acquisition workflow using Harvester follows these five steps in order:

    1. Loading GenTL Producers: Import Harvester and load one or more .cti files using add_file().
    2. Enumerating devices: Call update() to populate the device list.
    3. Getting ownership of a target device: Create an ImageAcquirer object using create().
    4. Acquiring images: Start acquisition with start() and retrieve images via fetch() or try_fetch().
    5. Closing application: Stop acquisition with stop(), destroy the acquirer with destroy(), and reset the Harvester object with reset().
    from harvesters.core import Harvester
    
    h = Harvester()
    h.add_file('path/to/foo.cti')
    h.update()
    ia = h.create(0)
    ia.start()
    # ... acquire images ...
    ia.stop()
    ia.destroy()
    h.reset()
  6. Clean up resources and close applications

    master

    To prevent resource leaks, always release hardware and software handles:

    • ia.stop(): Stops the acquisition process.
    • ia.destroy(): Disconnects the device from the acquirer. You must call h.create() again to reconnect to this device.
    • h.reset(): Releases all resources held by the Harvester object.

    Best Practice: Use Python's with statement for both Harvester and ImageAcquirer. This ensures destroy() and reset() are called automatically even if errors occur.

    from harvesters.core import Harvester
    
    # Recommended pattern using context managers
    with Harvester() as h:
        h.add_file('path/to/foo.cti')
        h.update()
        
        with h.create(0) as ia:
            ia.start()
            # ... acquire images ...
            ia.stop()
        # ia.destroy() is called automatically here
    # h.reset() is called automatically here
  7. How to use Harvester for image acquisition

    master

    To use Harvester, you typically follow these steps:

    1. Initialize the Harvester instance.
    2. Add GenTL Producer files (.cti) using add_file().
    3. Update the harvester state with update() to populate device_info_list.
    4. Create an ImageAcquirer using create(index).
    5. Configure the device via ia.remote_device.node_map.
    6. Start acquisition with ia.start().
    7. Fetch images using ia.fetch() as a context manager.
    8. Stop and destroy the acquirer using ia.stop() and ia.destroy().
    9. Reset the harvester with h.reset().
    from harvesters.core import Harvester
    import numpy as np
    
    h = Harvester()
    h.add_file('/path/to/your_producer.cti')
    h.update()
    
    # Create an acquirer for the first device found
    ia = h.create(0)
    
    # Configure GenICam nodes
    ia.remote_device.node_map.Width.value = 8
    ia.remote_device.node_map.Height.value = 8
    ia.remote_device.node_map.PixelFormat.value = 'Mono8'
    
    ia.start()
    
    try:
        with ia.fetch() as buffer:
            # Access the first image component in the payload
            component = buffer.payload.components[0]
            
            # Convert 1D data to 2D NumPy array
            image_2d = component.data.reshape(component.height, component.width)
            print(f'Average: {np.average(image_2d)}')
    finally:
        ia.stop()
        ia.destroy()
        h.reset()
  8. Install Harvester via pip

    master

    You can install the harvesters package via PyPI. Note that the package name is harvesters (plural), not harvester.

    Installing via pip will automatically install required dependencies such as numpy and genicam if they are not already present in your environment.

    # Standard installation
    $ pip install harvesters
    
    # Upgrade existing installation
    $ pip install --upgrade harvesters
    # OR
    $ pip install -U harvesters
    
    # Install without using cached packages
    $ pip install -U --no-cache-dir harvesters
  9. System Requirements for Harvester

    master

    To use Harvester, ensure your system meets the following requirements:

    • Python Compatibility: Supported CPython versions are determined by the genicam package. If your CPython version is not supported by genicam, Harvester will not be available.
    • Compiler Compatibility: Cygwin GCC is not supported on Windows due to restrictions in the GenICam reference implementation.
    • Hardware/Software Dependencies:
      • GenTL Producers: Required for image acquisition.
      • GenICam compliant devices: Machine vision cameras or devices.
  10. Create an isolated Conda environment for Harvester

    master

    It is highly recommended to use an isolated environment (e.g., via Anaconda/Conda) to avoid corrupting your system Python.

    To create and use an environment named genicam with Python 3.6, follow these steps:

    1. Create the environment: conda create -n genicam python=3.6
    2. Activate the environment: conda activate genicam
    3. Verify the installation: python --version
    4. Install optional tools (like IPython) and Harvester within the environment.
    5. Deactivate when finished: conda deactivate
    # Create environment
    $ conda create -n genicam python=3.6
    
    # Activate environment
    $ conda activate genicam
    
    # Verify Python version
    $ python --version
    
    # Install IPython (optional)
    $ conda install ipython
    
    # Deactivate
    $ conda deactivate
  11. Reshape acquired images from 1D to 2D NumPy arrays

    master

    Harvester returns acquired images as 1D NumPy arrays to avoid imposing a specific shape that might limit downstream algorithms. To use the image in applications like VisPy or OpenCV, you must reshape the array using the metadata provided by the component.

    Mono Formats

    For monochrome images, reshape using height and width:

    content = component.data.reshape(height, width)

    Color Formats (RGB, RGBA, BGR, BGRA)

    For color images, you must include the number of components per pixel. Note that component.num_components_per_pixel returns a float, so you must cast it to an int to avoid NumPy errors.

    If the format is bgr_formats, you may need to swap the R and B channels to convert to RGB:

    content = component.data.reshape(
        height, 
        width, 
        int(component.num_components_per_pixel)
    )
    if data_format in bgr_formats:
        content = content[:, :, ::-1]
    from harvesters.util.pfnc import mono_location_formats, rgb_formats, bgr_formats, rgba_formats, bgra_formats
    
    payload = buffer.payload
    component = payload.components[0]
    width = component.width
    height = component.height
    data_format = component.data_format
    
    if data_format in mono_location_formats:
        content = component.data.reshape(height, width)
    elif data_format in rgb_formats or data_format in rgba_formats or data_format in bgr_formats or data_format in bgra_formats:
        content = component.data.reshape(
            height, width,
            int(component.num_components_per_pixel)
        )
        if data_format in bgr_formats:
            content = content[:, :, ::-1]