Stabilizing Basler Camera Acquisition with Event-Driven Capture and Async Saving (C# / pylon SDK)

Stabilizing Basler Camera Acquisition with Event-Driven Capture and Async Saving (C# / pylon SDK)

In previous articles, we covered burst capture (continuous acquisition) and performance tuning using ROI.

As a follow-up, this article explains how to make your acquisition loop more robust by combining event-driven image grabbing with asynchronous save processing.


✅ Why Event-Driven Acquisition Helps

Key characteristics:

  • Your handler is called only when a frame arrives
  • It integrates cleanly with UI frameworks like WPF

For single-frame capture, you can simply use GrabOne(). However, for GUI applications (live previews, start/stop capture buttons, etc.), using the ImageGrabbed event often results in a cleaner design and more responsive UI.


🔧 Minimal Event-Based Implementation

We will extend the same BaslerCameraSample class used in previous articles:

  • ROI article: Using ROI to Boost Burst Capture Performance
  • Single-frame capture article: How to Capture a Single Image with Basler pylon SDK in C#

First, we register an ImageGrabbed event handler and start streaming.

It’s convenient to expose an IsGrabbing property on BaslerCameraSample:

To stop continuous acquisition, detach the event handler and stop the stream grabber:

Whether you attach/detach the event handler every time depends on your application design. For simple apps, you might register the handler once (e.g., in the constructor) and keep it for the lifetime of the object.


Example: 1 Second of Continuous Capture


⚠️ Problem: Saving Overhead Can Stall the Pipeline

Depending on your PC and image size, saving each image may take several to tens of milliseconds. At higher frame rates, a simple event handler that saves directly inside ImageGrabbed may not keep up, causing:

  • Increased latency
  • Dropped frames
  • Unstable frame intervals

🧭 Solution: Buffer with ConcurrentQueue and Save on a Separate Thread

Overall flow:

First, modify OnImageGrabbed to push cloned results into a queue instead of saving immediately.

Next, run a separate asynchronous loop that dequeues items and saves them:


Example: Combining Event-Driven Capture with Async Saving

We can now update the test to run acquisition and saving concurrently:

Depending on your requirements:

  • If real-time streaming is critical and your CPU has enough headroom, you can save while grabbing.
  • If your CPU is heavily loaded but RAM is sufficient, you can buffer during capture and save after stopping (by starting SaveBufferedImages only after StopGrabbing).

✅ Summary

  • Using the ImageGrabbed event yields a clean, C#-idiomatic structure for continuous acquisition.
  • Directly saving in the event handler can become a bottleneck at higher frame rates.
  • A robust pattern is: Clone → Enqueue → Async Save on a background task using ConcurrentQueue.
  • This separation helps stabilize continuous acquisition and makes your pipeline more resilient under load.

In the next article, we’ll look at integrating Basler cameras with OpenCV, enabling more advanced image processing workflows.


Author: @MilleVision


📦 Full Sample Project(With Japanese Comment)

A complete C# project that includes event-driven acquisition, ROI, burst capture, and asynchronous saving is available here(With Japanese Comment):

👉 https://millevision.booth.pm/items/7316233

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA