IDS peak genericC++ v1.16.0
Loading...
Searching...
No Matches
Python

Prerequisites

To use IDS peak genericAPI in Python, the ids_peak package can be installed directly from PyPI via pip, Python's package manager:

pip install ids_peak
Note
To be able to install the Python wheels on Linux, pip must be installed in version 20.3 or greater. Otherwise pip will detect the wheel as "not supported on this platform".

Offline Installation

In case of an offline installation, there is a separate Python wheel for each supported Python version and CPU architecture. A Python wheel is a package file (with .whl file ending) which can be installed via pip, Python's package manager. Just call pip install <Path-To-Python-Wheel> to install your chosen Python wheel. The respective .whl file can be obtained from the package's PyPI project page under Download files.

While pip will inform you about missing packages and their version requirements, contrary to the online installation, you need to manually resolve dependencies and respect the correct order of installation.

Import

To finally use IDS peak genericAPI in your Python script, just add import ids_peak.ids_peak or import ids_peak.ids_peak as some_alias at the top of your Python script. The latter should be preferred.

Usage

The Python API works much like the C++ API. Nearly the same principles, class and method names apply. For example, listing all available devices:

import ids_peak.ids_peak as some_alias
try:
some_alias.Library.Initialize()
device_manager = some_alias.DeviceManager.Instance()
device_manager.Update()
device_descriptors = device_manager.Devices()
for device_descriptor in device_descriptors:
print(device_descriptor.DisplayName())
except ids_peak_alias.Exception as ex:
print("Exception: " + str(ex))
finally:
some_alias.Library.Close()

Converting a Buffer to an Image

It is possible to convert the content of a Buffer into an image by directly employing Buffer::BasePtr alongside a custom conversion routine to ensure compatibility with any image processing library. However, the recommended method is to use the BufferToImage function. This function is included in the supplementary module ids_peak_ipl_extension. BufferToImage is specifically engineered to simplify the conversion process of raw memory data stored within a Buffer into an peak::ipl::Image that can be used for further processing.

An example usage could look like as follows:

from ids_peak import ids_peak_ipl_extension
buffer = datastream.WaitForFinishedBuffer(1000)
# Get image from buffer (shallow copy)
image = ids_peak_ipl_extension.BufferToImage(buffer)
Warning
The resulting image still uses the underlying memory of buffer. For this reason, you must ensure that you do not re-queue the buffer until you have finished processing image.

Comparison to the C++ API

There are only a few differences between the C++ API and the Python API. The most important ones are listed here:

Resource Management

The C++ API utilizes smart pointers for deterministic memory management, where the last smart pointer that holds a reference to the object destroys it when the smart pointer goes out of scope.

To close a module (e.g. the Device), you have to release all its shared_ptr instances (out-of-scope, call reset(), set to nullptr), then the module closes immediately.

  • C++
    {
    auto device = deviceDescriptors[0].OpenDevice(DeviceAccessType.Control);
    // ...
    } // Device closes here

Since Python uses garbage collection, when an object is released in Python, it won't be closed and deleted immediately. Instead, it will be deleted at some point in the future, when the garbage collection deems it necessary. Often, that's no problem. But if it is, you could do the following:

  • Python
    device = deviceDescriptors[0].OpenDevice(some_alias.DeviceAccessType_Control)
    del device # Device gets closed here

Naming of Enumeration Values

Since Python had no native concept of enumeration types, the values are mapped to individual constants. A rule of thumb is that each scope resolution operator :: in C++ is replaced with an underscore in Python:

  • C++
    const auto deviceAccessType = DeviceAccessType::Control;
    std::cout << ToString(deviceAccessType) << '\n';
  • Python
    device_access_type = some_alias.DeviceAccessType_Control
    print(some_alias.DeviceAccessTypeEnumEntryToString(device_access_type))

Change Notification

To be notified when certain events happen, the C++ API employs callbacks that you have to register and unregister. This concept exists almost equivalently in the Python API. Likewise it's necessary to store the callback handle for subsequent unregistering of the callback.

Attention
An important difference is that the callback needs to be kept alive, by keeping a reference to it, until it isn't needed anymore. Otherwise the callback will be unregistered prematurely.
  • C++
    const auto deviceFoundCallbackHandle = deviceManager.RegisterDeviceFoundCallback(
    [](const std::shared_ptr<peak::core::DeviceDescriptor>& newDev)
    { std::cout << "Device found: " << newDev->DisplayName() << '\n'; });
    deviceManager.Update()
    deviceManager.UnregisterDeviceFoundCallback(deviceFoundCallbackHandle);
  • Python
    device_found_callback = device_manager.DeviceFoundCallback(
    lambda new_dev: print("Device found: {}", new_dev.DisplayName()))
    device_found_callback_handle = device_manager.RegisterDeviceFoundCallback(device_found_callback)
    device_manager.Update()
    device_manager.UnregisterDeviceFoundCallback(device_found_callback_handle)