pypylon Documentation
repository·master·Indexed 20 days ago
https://github.com/basler/pypylonOfficial Python bindings for the Basler pylon C++ APIs. pypylon enables developers to control Basler machine vision cameras, access image data via the pylon parameter API, and execute image processing recipes using the pylon Data Processing API.
What's inside pypylon
- pypylon is the official Python language binding for the Basler pylon C++ APIs. It allows Python applications to control and acquire images from Basler machine vision products, such as cameras.
Manage queue behavior and backpressure
masterWhen using a queue to decouple acquisition from processing, you must manage backpressure. If the queue becomes full, the producer thread will block, which in turn slows down the acquisition process.
Strategies for managing backpressure:
- Increase queue size: Allows for larger bursts of processing delay.
- Drop frames manually: Implement logic to discard old frames if the queue is full.
- Use Grab Strategies:
LatestImageOnly: Reduces backlog by focusing on the most recent data. Best for responsive systems.OneByOne: Ensures every frame is processed. Best for analysis systems where completeness is required.
Recommended Combinations:
LatestImageOnly+queue$\rightarrow$ Responsive systems.OneByOne+ logging $\rightarrow$ Analysis systems.
Choose a Grab Strategy for image acquisition
masterGrab strategies determine how the internal buffer queue handles images when the camera produces frames faster than the application can process them.
Available Strategies
pylon.GrabStrategy_LatestImageOnly: Only the newest image is kept in the buffer. Older frames are discarded. This is ideal for live displays, GUIs, and low-latency systems where seeing the most recent state is more important than seeing every single frame.pylon.GrabStrategy_OneByOne: All frames are queued and processed in the order they were produced. No frames are dropped unless the buffers overflow. This is ideal for inspection systems, recording, and deterministic processing where every frame must be analyzed.
Ensure Resource Safety with Context Managers
masterAlways use the
withstatement when retrieving grab results. This ensures that thegrab_resultis automatically released even if an exception occurs within the block. Failing to release grab results can lead to unavailable buffers and cause the acquisition to stall.with camera.RetrieveResult(...) as grab_result: image = grab_result.ArraySynchronize cameras via software or hardware
masterMulti-camera systems require synchronization to ensure images are captured at the same time.
- Software Synchronization: Trigger cameras via software using
camera.ExecuteSoftwareTrigger(). This has limited precision and is subject to OS scheduling delays. - Hardware Synchronization (Recommended): Use a physical trigger signal (e.g., a Master camera triggering Slave cameras). This provides precise, deterministic timing required for stereo vision or measurement systems.
camera.ExecuteSoftwareTrigger()- Software Synchronization: Trigger cameras via software using
Understand the pypylon Acquisition Lifecycle
masterThe acquisition process follows a decoupled flow where the camera operates asynchronously from the Python application. The data flows from the Camera through the Transport layer into a Buffer Queue, which is then consumed by the Application via
RetrieveResult()calls.Mental Model:
- Camera: Runs asynchronously.
- Python: Retrieves data synchronously.
- Buffers: Decouple the camera's production of frames from the application's consumption of frames.
Choose a grab strategy based on latency vs completeness
masterpypylon uses grab strategies to manage the mismatch between a fast camera (Producer) and a slower application (Consumer). When the application cannot keep up with the camera's frame rate, the grab strategy determines how the buffer queue behaves.
LatestImageOnly
Behavior: Keeps only the most recent frame and drops older frames while the application is busy.
- Pros: Minimal latency; always provides the most recent state.
- Cons: High frame loss.
- Best for: Live displays, GUI monitoring, and real-time visualization where seeing the current state is more important than seeing every frame.
OneByOne
Behavior: Every frame is queued and processed in the order it was received. No frames are intentionally dropped.
- Pros: No frame loss; deterministic processing order.
- Cons: Higher latency if processing is slow; risk of buffer overflow if the overload is sustained.
- Best for: Inspection systems, image recording, and measurement tasks where every frame must be analyzed.
Comparison Summary
Strategy Latency Frame Loss Determinism LatestImageOnlyLow Yes Low OneByOneHigh (if slow) No High Understand the pypylon threading and concurrency model
masterpypylon uses a decoupled execution model to separate hardware acquisition from Python-level processing. The conceptual flow is:
Camera → Native Thread → Buffer Queue → Python ApplicationKey aspects of this model:
- Native Threading: Camera acquisition runs in a native C++ thread managed by pylon.
- Asynchronous Acquisition: Your Python code retrieves images from a buffer queue, allowing acquisition to continue even if your processing logic is temporarily delayed.
- Decoupling: This separation is critical when the camera frame rate (e.g., 100 FPS) exceeds your application's processing capability (e.g., 20 FPS). Without concurrency, buffers will fill up, frames will be dropped, and latency will increase.
Design efficient threading with the Producer–Consumer pattern
masterTo prevent blocking acquisition and improve CPU utilization, separate camera acquisition from image processing using a Producer–Consumer pattern.
- Acquisition Thread (Producer): Grabs images and pushes them into a thread-safe queue.
- Processing Thread(s) (Consumer): Pulls images from the queue for analysis.
Use
queue.Queuefor thread-safe communication between stages.Recommended Pipeline Structure:
Grab → Preprocess → Analyze → Outputimport queue q = queue.Queue()Understand image shape and pixel formats
masterThe shape of the resulting NumPy array depends on the
PixelTypeused. Common mappings include:Pixel Format NumPy Shape Example NumPy Dtype PixelType_Mono8(height, width)uint8PixelType_Mono16(height, width)uint16PixelType_RGB8packed/PixelType_BGR8packed(height, width, 3)uint8You can inspect the dimensions using
image.shapeorimage.ndim.Naming conventions for pypylon samples
masterUse
snake_casefor both sample folders and script names. The naming strategy depends on the module:pylonmoduleUse a topic prefix to categorize the sample:
grab_: Image grabbing illustrations.parametrize_: Camera parameter access and configuration.utility_: Usage of the optional pylon utility C++ library.gige_: GigE-specific features.- No prefix: For all other purposes.
pylondataprocessingmoduleDo not use prefixes. Name the sample directly after the feature it demonstrates (e.g.,
barcode.py,ocr.py,region.py).Test Enum Bindings in pypylon
masterWhen testing enum-like bindings, avoid heavy class wrappers or exhaustive inventories. Instead, use a pattern of short, explicit checks of public names.
Best Practices:
- Prefer Representative Examples: Cover a few meaningful cases rather than rebuilding the entire enum. For example, when testing helpers, include at least one per helper family (e.g.,
GetPixelColorFilter(pylon.PixelType_BayerRG8)). - Use Contrast Sets: For boundaries that are easily confused (e.g., planar vs. packed, Bayer vs. mono), use a small set of 2-4 related assertions.
- Explicit Assertions over Loops: For small fixed sets, use explicit assertions instead of loops to keep the tested public names easy to read and review.
- Assert Invariants, Not Encodings: If an enum value is an internal bit-packed encoding, do not hard-code the integer value. Instead, test documented invariants like sentinel values or distinctness.
- Keep it Simple: Avoid large module-level lists or throwaway aliases.
- Prefer Representative Examples: Cover a few meaningful cases rather than rebuilding the entire enum. For example, when testing helpers, include at least one per helper family (e.g.,