カテゴリー: Camera

  • Implementing High-Speed Burst Capture with the Basler pylon SDK (C# / .NET 8)

    Implementing High-Speed Burst Capture with the Basler pylon SDK (C# / .NET 8)

    In machine vision and inspection systems, it’s often not enough to capture a single frame—you frequently need to capture multiple images in rapid succession, also known as burst capture or continuous acquisition.

    In this article, we walk through how to implement burst capture using the Basler pylon SDK in C#, including:

    • A basic capture loop
    • Controlling frame interval
    • Saving images with timestamps
    • Practical performance considerations

    ✔ What You Will Learn

    • How to implement a burst capture loop
    • How to control acquisition interval using frame-rate settings
    • How to save frames with timestamps for later analysis
    • How to avoid dropped frames and performance bottlenecks

    ✔ Environment

    Item Details
    Camera Basler acA2500-14gm
    SDK Basler pylon Camera Software Suite
    Lang C# / .NET 8 (Windows)

    🔄 Basic Burst Capture: Capturing N Consecutive Frames

    Before implementing burst capture, define a helper method to control trigger mode:

    The following method performs a free-run (trigger-off) burst capture, saving each frame with both an index and elapsed time. Including timestamps makes later debugging and performance analysis much easier.


    🕒 Controlling the Capture Interval

    Burst capture does not automatically enforce timing. To control the interval—for example, 10 fps—enable and set AcquisitionFrameRate:

    Reference: How to Control and Verify Frame Rate Using the Basler pylon SDK (C# / .NET 8)


    📷 Example: Capturing 10 Frames at 10 fps


    📊 Example Output

    Captured images at 10 fps while the object was rotating:

    45ms 143ms 243ms 343ms 443ms
    BurstCaptureTest_000_45ms.png BurstCaptureTest_001_143ms.png BurstCaptureTest_002_243ms.png BurstCaptureTest_003_343ms.png BurstCaptureTest_004_443ms.png
    543ms 643ms 743ms 843ms 943ms
    BurstCaptureTest_005_543ms.png BurstCaptureTest_006_643ms.png BurstCaptureTest_007_743ms.png BurstCaptureTest_008_843ms.png BurstCaptureTest_009_943ms.png

    ⚠️ Common Problems & How to Fix Them

    Issue Cause / Solution
    Missing frames Saving images takes too long → save in a background thread using ConcurrentQueue
    CPU load too high Full-resolution images are heavy → reduce ROI
    First-frame timestamp inconsistent Trigger mode behavior → use hardware/software trigger for strict timing

    🔁 Slow Burst Capture at Full Resolution?

    → Reduce ROI to Increase Frame Rate

    Full-resolution capture (e.g., 2592×1944) can bottleneck both bandwidth and processing time. Reducing the Region of Interest (ROI) often dramatically improves:

    • Frame rate
    • Latency
    • Stability

    ROI-based optimization will be covered in the next article.


    📝 Summary

    • Burst capture in pylon is implemented with StreamGrabber.Start() + a loop
    • Frame rate control determines capture timing
    • Image saving can become a bottleneck—offload saving to another thread if necessary
    • Combining ROI with burst capture greatly improves performance

    筆者: @MilleVision


    📦 Full Sample Code Package

    A complete working version of all code shown in this article (including burst capture templates) is available here:

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

  • How to Control and Verify Frame Rate Using the Basler pylon SDK (C# / .NET 8)

    How to Control and Verify Frame Rate Using the Basler pylon SDK (C# / .NET 8)

    When developing vision applications—especially for real-time inspection or production environments—one of the most important performance metrics is frame rate (fps). You may need to know:

    • Can the camera actually capture frames at the rate I’ve set?
    • What limits the maximum achievable frame rate?
    • How do I read both the requested and the actual frame rate?

    This article explains how to set frame rate, enable frame-rate control, and check the actual resulting fps using the Basler pylon SDK in C#.


    ✔ Environment

    Item Details
    Camera Basler acA2500-14gm
    SDK Basler pylon Camera Software Suite
    Lang C# / .NET 8 (Windows)

    💡 AcquisitionFrameRate vs. ResultingFrameRate

    Parameter Meaning
    AcquisitionFrameRate The requested frame rate (user setting)
    ResultingFrameRate The actual achievable frame rate calculated by the camera

    Even if you set 30 fps, the resulting fps may be lower depending on exposure time, ROI, interface bandwidth, etc.


    🔧 Enabling Frame Rate Control

    Frame-rate control must be explicitly enabled:

    Helper method for Boolean parameters

    AcquisitionFrameRateEnable is a boolean parameter (IBoolean), so we define:


    🔧 Setting the Desired Frame Rate

    💡 Depending on the camera model, the parameter name may be:

    • AcquisitionFrameRate
    • AcquisitionFrameRateAbs

    Verify via pylon Viewer or by checking:


    📏 Reading the Requested and Actual Frame Rate

    Requested (user-set) frame rate:

    Actual achievable rate:

    ResultingFrameRate is essential—it tells you whether your settings are physically achievable given the exposure time, bandwidth, and ROI.


    🚧 What Limits Maximum Frame Rate?

    1. Image Size / ROI

    Smaller ROI = fewer pixels = higher possible fps.

    2. Exposure Time

    If exposure is too long, the sensor cannot start the next frame.

    Example: ExposureTime = 50,000 µs (50 ms) → max possible fps is 20 fps.

    3. Interface Bandwidth (USB3 / GigE)

    High-resolution images or 24-bit RGB increase bandwidth usage, lowering achievable fps.


    📝 When Your Frame Rate Setting Is Ignored

    If you set AcquisitionFrameRate but nothing changes, check:

    ✔ Is AcquisitionFrameRateEnable set to true?

    If false, the camera ignores your setting and runs at the highest allowable frame rate.


    🧪 Example Test: 5 fps → 15 fps → 30 fps

    Example output on my machine:

    Even though 30 fps was requested, the actual fps dropped to ~14.6 fps due to bandwidth or exposure constraints.


    🧭 Troubleshooting

    Symptom Likely Cause
    Frame rate does not increase Exposure too long / ROI too large
    Cannot set AcquisitionFrameRate AcquisitionFrameRateEnable is false
    ResultingFrameRate reads 0 Camera not streaming or not initialized

    📝 Summary

    • Enable frame-rate control via AcquisitionFrameRateEnable = true
    • Set target fps with AcquisitionFrameRateAbs
    • Verify actual achievable fps via ResultingFrameRateAbs
    • Exposure time, ROI size, and bandwidth all influence the maximum fps

    Understanding both the requested and actual frame rate is essential for designing stable, real-time machine vision systems.


    🔜 Next Article

    Next, we will build on frame-rate control by implementing continuous acquisition (burst capture) for high-speed inspections and inline processing.


    筆者: @MilleVision

  • Manual Gain Control with the Basler pylon SDK (C# / .NET 8)

     

    筆者: [@MilleVision](https://qiita.com/MilleVision)

    Manual Gain Control with the Basler pylon SDK (C# / .NET 8)

    When working with industrial cameras such as those from Basler, exposure time alone is not always enough to achieve the brightness you need. This is especially true when:

    • The subject moves quickly
    • You must keep exposure time short
    • The lighting environment limits the available exposure

    In these situations, manual gain control becomes an important tool.

    This article explains how to read, set, and validate gain values in C# using the Basler pylon SDK. We will also examine how gain affects noise and how to balance exposure vs. gain using practical example images.


    ✔ Environment

    Item Details
    Camera Basler acA2500-14gm
    Lens VS Technology VS-LD25N (25 mm C-mount)
    SDK Basler pylon Camera Software Suite
    Lang C# / .NET 8 (Windows)

    💡 What Is Gain?

    Gain represents electronic amplification of the sensor signal.

    • Increasing gain brightens the image
    • But it also amplifies noise, reducing image quality

    Because of this trade-off, gain should be balanced with exposure time rather than used alone. Exposure increases brightness with lower noise, but may blur moving objects. Gain brightens the image without changing shutter time but introduces noise.


    🔧 Code: Setting and Reading Gain

    Below are simple helper methods for manual gain control.

    Set Gain (manual mode)

    Auto Gain Mode

    Read Gain


    📷 Gain in Practice: Image Comparisons

    ① Exposure Fixed, Gain Increased

    In this test, exposure time is constant while only gain is changed. You can clearly see how higher gain results in brighter images but more noise.

    Gain 0 dB Gain 12 dB Gain 24 dB
    Gain0fixed Gain12fixed Gain24fixed

    ② Same Brightness, Different Gain (Exposure Adjusted)

    Here, exposure time was adjusted so that the brightness remained approximately constant, allowing you to see just the difference in noise.

    Gain 0 dB (60ms) Gain 12 dB (24ms) Gain 24 dB (12ms)
    Gain0exp60ms Gain12exp24ms Gain24exp12ms

    💡 GainRaw ↔ Gain (dB) Conversion

    Basler cameras often expose two gain parameters:

    • Gain (in dB) — user-friendly
    • GainRaw — internal integer register value

    The mapping between them varies by camera model, but it can typically be approximated by a linear transform:

    This is useful when a camera supports only GainRaw or when you need precise dB control.


    🧭 Troubleshooting Common Gain Issues

    Issue Cause / Solution
    Gain does not change GainAuto is not set to Off
    Parameter write error Value outside the allowed range — check GetMin() / GetMax()
    Noise becomes excessive Gain too high — prefer exposure when possible
    Cannot write to Gain Parameter not writable → likely because auto gain is active

    When Gain Cannot Be Set

    If GainAuto is not disabled, the parameter:

    will be false, preventing manual writes.

    Always check IsWritable before writing to avoid runtime exceptions.


    📝 Summary

    • Gain amplifies brightness and noise — unlike exposure, which brightens with less noise

    • Set GainAuto = Off to enable manual gain control

    • The balance between exposure and gain is crucial:

      • Exposure = cleaner images, but motion blur risk
      • Gain = no blur, but increased noise

    By comparing images side-by-side, we can see why most machine-vision systems prioritize exposure first, then use gain sparingly.


    🔜 Next Article

    With exposure and gain under control, the next major topic is trigger modes and frame synchronization. We’ll explore hardware triggers, software triggers, and best practices for synchronized acquisition.


    筆者: @MilleVision

  • How to Manually Control Exposure Time Using the Basler pylon SDK (C# / .NET 8)


    How to Manually Control Exposure Time Using the Basler pylon SDK (C# / .NET 8)

    Have you ever felt that your industrial camera images look too dark, too bright, or fluctuate unexpectedly?
    Automatic exposure (auto-exposure) can be useful, but in many machine-vision or inspection systems, consistent lighting is essential, and automatic adjustments can cause instability.

    With the Basler pylon SDK, you can switch exposure control to manual mode and specify an exact exposure time (in microseconds), enabling stable and predictable imaging.

    This article explains how to set, read, and validate exposure time manually using C# and the pylon SDK.


    ✔ Environment

    ItemDetails
    CameraBasler acA2500-14gm
    SDKBasler pylon Camera Software Suite
    LangC# / .NET 8.0 (Windows)

    💡 Background: GenICam and Camera Parameters

    Parameters such as ExposureTimeAbs used in this article follow GenICam (Generic Interface for Cameras) — an industry standard used by Basler, FLIR, IDS, JAI, and many other industrial camera manufacturers.

    With GenICam SFNC (Standard Features Naming Convention), you can access:

    • Exposure
    • Gain
    • ROI / image size
    • Trigger settings
    • Acquisition modes

    all using a common parameter model.

    👉 GenICam SFNC specification:
    https://www.emva.org/standards-technology/genicam/

    This article focuses on practical usage, but knowing that pylon follows GenICam helps when switching between camera brands.


    🔧 Setting Exposure Time Manually

    Below is an extension to the BaslerCameraSample class from the previous article.

    Method: Set Exposure Time (manual mode)


    Helper Functions

    Set auto-exposure mode (Off / Once / Continuous)

    Set an enum parameter

    Set a floating-point parameter (e.g., ExposureTimeAbs)


    🔍 Reading the Current Exposure Time

    Use GetValue() to read exposure parameters from the camera.


    💡 About ExposureAuto Modes

    ValueBehavior
    OffManual exposure (used in this article)
    OnceAdjusts exposure once, then fixes it
    ContinuousContinuously adjusts to maintain brightness

    📷 Example: Change Exposure and Capture Images

    The test below captures images at 5 ms, 20 ms, and 50 ms.


    📊 Exposure Comparison


    5 ms (darker) 20 ms (balanced) 50 ms (brighter)
    5ms 20ms 50ms

    🧭 Common Issues & Troubleshooting

    IssueCause / Solution
    Exposure does not changeExposureAuto is still On
    Value outside valid rangeExposure too long or too short for the camera model
    Image too dark/brightLighting or gain settings are insufficient
    Exposure fluctuatesExternal lighting or auto exposure still enabled

    📝 Summary

    • Set ExposureAuto = Off to enable manual exposure control
    • Exposure time is specified in microseconds (μs)
    • pylon SDK accesses all parameters through Camera.Parameters[...], following GenICam SFNC

    🔜 Coming Up Next

    Exposure alone may not give enough brightness range depending on your lighting environment.
    The next article will cover manual gain control using the pylon SDK.

  • How to Capture a Single Image from Basler ace Camera using pylon SDK in C#


    How to Capture a Single Image from Basler ace Camera using pylon SDK in C#

    Basler industrial cameras can be controlled easily using the pylon Camera Software Suite.
    In this article, I’ll show you how to connect to a camera, grab a single frame, convert it to a BitmapSource, and save it as a .bmp file—all using C# and .NET 8.

    When I first started working with Basler cameras in a .NET environment, I found very few practical code examples.
    This guide is based on tested code from my own applications.

    This article covers:

    • Connecting to a camera
    • Capturing one frame (Snap)
    • Converting to BitmapSource (WPF-friendly)
    • Saving the image as .bmp

    ⚠️ Important Notice

    This article demonstrates how to develop custom applications using the Basler pylon Camera Software Suite SDK.

    • The content here is based on my own testing and implementation
    • It is not endorsed by Basler AG
    • The SDK itself is not redistributed here (no DLLs, headers, etc.)

    To use the SDK, download it directly from Basler’s official website:

    🔗 pylon SDK download
    https://www.baslerweb.com/en/products/software/basler-pylon-camera-software-suite/

    Make sure to review the EULA, especially if using the SDK in commercial or high-risk environments:
    https://www.baslerweb.com/en/service/eula/

    The sample code in this article is provided strictly for learning and reference. Use it at your own responsibility.


    ✔ Environment

    ItemDetails
    SDKBasler pylon Camera Software Suite
    LanguageC# (.NET 8.0 — Windows)
    CameraBasler acA2500-14gm
    OSWindows 10 / 11

    1. Connecting to the Camera

    First, create a simple wrapper class for managing the connection.
    You can connect to the first available camera or use a specified camera name (as shown in Basler pylon Viewer).


    2. Capturing a Single Image

    The simplest way to grab one frame is by calling GrabOne() through the Stream Grabber.


    3. Converting to BitmapSource (for WPF)

    IGrabResult cannot be displayed directly in WPF.
    We convert it to a BitmapSource using PixelDataConverter.

    Supports:

    • RGB8packed
    • BGR8packed
    • Mono8 (default fallback)

    4. Saving the Image as .bmp

    A simple helper method using BmpBitmapEncoder:


    5. Example Test Code

    You can easily test the entire pipeline (grab → convert → save) using the following:


    ✔ Output Example

    The captured image will be saved as:SaveBitmapTest.bmp

    Example output:

    (Image from the original article)


    ✨ Conclusion

    Although official documentation covers the basics, hands-on .NET examples for pylon are still relatively rare.
    Fortunately, pylon’s .NET API is clean and integrates smoothly with Windows desktop applications such as WPF.