- Add new brightness-deadband property (default 10.0, range 0.0-50.0) - Implements deadband/tolerance zone around target brightness - When brightness is within ±deadband, no adjustments are made - Prevents oscillation at fast update rates (10-100ms) - Allows fast corrections when brightness significantly deviates - Enables fast ramp rates without flicker/oscillation - Updated README with detailed deadband documentation and usage examples - Solves exposure fluctuation issue at high frame rates with fast updates
417 lines
16 KiB
Markdown
417 lines
16 KiB
Markdown
# GStreamer Intervalometer Filter
|
||
|
||
**Automatic Exposure Control for IDS uEye Cameras**
|
||
|
||
Inspired by [YASS (Yet Another Sunset Script)](../../yass/README.md) for CHDK cameras.
|
||
|
||
## Overview
|
||
|
||
The `intervalometer` element is a GStreamer filter that automatically adjusts camera exposure and gain settings during changing light conditions. It analyzes video brightness in real-time and smoothly ramps camera parameters to maintain optimal exposure - perfect for time-lapse photography during sunset, sunrise, or other variable lighting scenarios.
|
||
|
||
## Features
|
||
|
||
- **Automatic Exposure Ramping**: Smoothly adjusts exposure time based on scene brightness
|
||
- **Automatic Gain Control**: Increases/decreases sensor gain when exposure limits are reached
|
||
- **Configurable Ranges**: Set custom min/max values for exposure (0.85-1.24ms) and gain (0-52)
|
||
- **Multiple Ramp Rates**: Choose from VSlow/Slow/Medium/Fast/VFast adjustment speeds
|
||
- **Exposure Compensation**: Fine-tune brightness with ±4 stops of compensation
|
||
- **CSV Logging**: Optional detailed logging of all exposure parameters
|
||
- **Multiple Format Support**: Works with GRAY8, GRAY16, RGB, BGR, and BGRA video
|
||
|
||
## Requirements
|
||
|
||
- GStreamer 1.0+
|
||
- IDS uEye camera with `idsueyesrc` element
|
||
- Camera must support runtime exposure and gain property changes
|
||
|
||
## Installation
|
||
|
||
The filter is built as part of the gst-plugins-vision project. Build and install normally:
|
||
|
||
```bash
|
||
mkdir build
|
||
cd build
|
||
cmake ..
|
||
make
|
||
make install
|
||
```
|
||
|
||
## Properties
|
||
|
||
### Control Properties
|
||
|
||
| Property | Type | Range | Default | Description |
|
||
|----------|------|-------|---------|-------------|
|
||
| `enabled` | boolean | - | TRUE | Enable/disable auto-exposure |
|
||
| `target-brightness` | double | 0-255 | 128.0 | Target average brightness level |
|
||
| `compensation` | double | -4.0 to 4.0 | 0.0 | Exposure compensation in stops |
|
||
| `camera-element` | string | - | "" | Name of upstream idsueyesrc element |
|
||
|
||
### Exposure Range
|
||
|
||
| Property | Type | Range | Default | Description |
|
||
|----------|------|-------|---------|-------------|
|
||
| `exposure-min` | double | 0.01-1000.0 | 0.85 | Minimum exposure time (ms) |
|
||
| `exposure-max` | double | 0.01-1000.0 | 1.24 | Maximum exposure time (ms) |
|
||
|
||
### Gain Range
|
||
|
||
| Property | Type | Range | Default | Description |
|
||
|----------|------|-------|---------|-------------|
|
||
| `gain-min` | int | 0-100 | 0 | Minimum gain value |
|
||
| `gain-max` | int | 0-100 | 52 | Maximum gain value |
|
||
|
||
### Ramping
|
||
|
||
| Property | Type | Values | Default | Description |
|
||
|----------|------|--------|---------|-------------|
|
||
| `ramp-rate` | enum | VSlow, Slow, Medium, Fast, VFast | Medium | Speed of parameter changes |
|
||
| `update-interval` | int | 10-10000 | 100 | Time between exposure updates (ms) |
|
||
|
||
### Brightness Filtering
|
||
|
||
| Property | Type | Range | Default | Description |
|
||
|----------|------|-------|---------|-------------|
|
||
| `brightness-smoothing` | double | 0.0-1.0 | 0.1 | Temporal smoothing factor (EMA alpha) |
|
||
| `brightness-deadband` | double | 0.0-50.0 | 10.0 | Deadband zone to prevent oscillation (0=disabled) |
|
||
|
||
### Logging
|
||
|
||
| Property | Type | Range | Default | Description |
|
||
|----------|------|-------|---------|-------------|
|
||
| `log-file` | string | - | "" | Path to CSV log file (empty = disabled) |
|
||
|
||
## Usage Examples
|
||
|
||
### Basic Auto-Exposure
|
||
|
||
```bash
|
||
gst-launch-1.0 idsueyesrc name=cam ! \
|
||
intervalometer enabled=true camera-element=cam ! \
|
||
videoconvert ! autovideosink
|
||
```
|
||
|
||
### Custom Range for Day/Night Transition
|
||
|
||
Configure for the typical day (0.85ms exposure, gain 52) to night (1.24ms exposure, gain 0) range:
|
||
|
||
```bash
|
||
gst-launch-1.0 idsueyesrc name=cam ! \
|
||
intervalometer enabled=true camera-element=cam \
|
||
exposure-min=0.85 exposure-max=1.24 \
|
||
gain-min=0 gain-max=52 \
|
||
ramp-rate=medium ! \
|
||
videoconvert ! autovideosink
|
||
```
|
||
|
||
### With Exposure Compensation
|
||
|
||
Adjust overall brightness with compensation:
|
||
|
||
```bash
|
||
gst-launch-1.0 idsueyesrc name=cam ! \
|
||
intervalometer enabled=true camera-element=cam \
|
||
compensation=1.0 \
|
||
target-brightness=140 ! \
|
||
videoconvert ! autovideosink
|
||
```
|
||
|
||
### With CSV Logging
|
||
|
||
Log all exposure data to a CSV file:
|
||
|
||
```bash
|
||
gst-launch-1.0 idsueyesrc name=cam ! \
|
||
intervalometer enabled=true camera-element=cam \
|
||
log-file=exposure_log.csv ! \
|
||
videoconvert ! autovideosink
|
||
```
|
||
|
||
### Dawn/Dusk Time-Lapse (Recommended)
|
||
|
||
Optimized settings for smooth sunrise/sunset time-lapse:
|
||
|
||
```bash
|
||
gst-launch-1.0 \
|
||
idsueyesrc config-file=ini/whole-presacler64_autoexp-binningx2.ini \
|
||
exposure=0.85 framerate=50 gain=0 name=cam device-id=2 ! \
|
||
intervalometer enabled=true camera-element=cam \
|
||
ramp-rate=vslow \
|
||
update-interval=1000 \
|
||
brightness-smoothing=0.1 \
|
||
brightness-deadband=10.0 \
|
||
log-file=timelapse.csv ! \
|
||
videocrop bottom=3 ! queue ! videoconvert ! autovideosink
|
||
```
|
||
|
||
**Key settings:**
|
||
- `ramp-rate=vslow`: 5% exposure steps per update (smooth transitions)
|
||
- `update-interval=1000`: Updates every 1 second (not too aggressive)
|
||
- `brightness-smoothing=0.1`: Filters out moving objects (cars, people, birds)
|
||
- `brightness-deadband=10.0`: Prevents oscillation by creating a stable zone
|
||
|
||
### Complete Time-Lapse Recording
|
||
|
||
Record a time-lapse with auto-exposure:
|
||
|
||
```bash
|
||
gst-launch-1.0 idsueyesrc name=cam framerate=1 ! \
|
||
intervalometer enabled=true camera-element=cam \
|
||
exposure-min=0.85 exposure-max=1.24 \
|
||
gain-min=0 gain-max=52 \
|
||
ramp-rate=slow \
|
||
log-file=timelapse_exposure.csv ! \
|
||
videoconvert ! x264enc ! mp4mux ! \
|
||
filesink location=timelapse.mp4
|
||
```
|
||
|
||
## How It Works
|
||
|
||
### Exposure Control Algorithm
|
||
|
||
The filter uses a YASS-inspired algorithm with deadband control:
|
||
|
||
1. **Brightness Analysis**: Calculates average brightness of each frame
|
||
2. **Deadband Check**: If brightness is within deadband zone, skip adjustments (prevents oscillation)
|
||
3. **Error Calculation**: Compares to target brightness (with compensation)
|
||
4. **Ramping Priority**:
|
||
- When too bright: Decreases exposure first, then gain
|
||
- When too dark: Increases exposure first (up to max), then gain
|
||
5. **Smooth Ramping**: Changes are gradual based on ramp-rate setting
|
||
|
||
### Typical Behavior
|
||
|
||
- **Daytime**: Fast shutter (low exposure), high gain for noise reduction
|
||
- **Sunset/Dusk**: Gradually increases exposure time as light fades
|
||
- **Night**: Maximum exposure time, minimum gain
|
||
|
||
### CSV Log Format
|
||
|
||
When logging is enabled, the filter creates a CSV file with:
|
||
|
||
```csv
|
||
Frame,Time_s,Brightness,Exposure_ms,Gain,Target_Brightness
|
||
0,0.000,145.32,0.850,52,128.00
|
||
1,0.033,143.21,0.851,52,128.00
|
||
2,0.067,142.15,0.853,52,128.00
|
||
...
|
||
```
|
||
|
||
## Camera Property Control
|
||
|
||
The filter finds and controls the upstream `idsueyesrc` element using the `camera-element` property. It sets:
|
||
|
||
- **exposure**: Exposure time in milliseconds
|
||
- **gain**: Master gain (0-100 range)
|
||
|
||
Ensure your camera source is named and the name matches the `camera-element` property.
|
||
|
||
## Configuration Reference
|
||
|
||
### Ramp Rates
|
||
|
||
| Rate | Multiplier | Step Size | Best For |
|
||
|------|------------|-----------|----------|
|
||
| VSlow | 0.5x | 5% per update | Dawn/dusk time-lapse (recommended) |
|
||
| Slow | 1.0x | 10% per update | Gradual sunset/sunrise over hours |
|
||
| Medium | 2.0x | 20% per update | Normal time-lapse scenarios |
|
||
| Fast | 4.0x | 40% per update | Faster light changes, clouds passing |
|
||
| VFast | 8.0x | 80% per update | Quick adaptation, testing |
|
||
|
||
**Note:** The base ramping rate is 10% of the delta between current and target values, multiplied by the ramp rate setting.
|
||
|
||
### Update Intervals
|
||
|
||
| Interval | Updates/sec | Best For |
|
||
|----------|-------------|----------|
|
||
| 100ms | 10 Hz | Fast-changing scenes (clouds, indoor) |
|
||
| 500ms | 2 Hz | Moderate changes |
|
||
| **1000ms** | **1 Hz** | **Dawn/dusk time-lapse (recommended)** |
|
||
| 2000ms | 0.5 Hz | Very slow lighting changes |
|
||
| 5000ms | 0.2 Hz | Extremely slow changes |
|
||
|
||
**Important:** At high frame rates (50fps), avoid very short update intervals (< 500ms) to prevent oscillation and flickering.
|
||
|
||
### Brightness Smoothing
|
||
|
||
The `brightness-smoothing` property uses Exponential Moving Average (EMA) to filter out transient brightness changes from moving objects:
|
||
|
||
```
|
||
smoothed_brightness = (alpha × current_brightness) + ((1 - alpha) × previous_smoothed)
|
||
```
|
||
|
||
| Value | Behavior | Best For |
|
||
|-------|----------|----------|
|
||
| 0.05 | Very heavy smoothing | High traffic scenes |
|
||
| **0.1** | **Heavy smoothing (default)** | **Time-lapse with moving objects** |
|
||
| 0.3 | Moderate smoothing | Some filtering needed |
|
||
| 0.5 | Light smoothing | Quick response |
|
||
| 1.0 | No smoothing | Instant response to changes |
|
||
|
||
**Effect:** With `brightness-smoothing=0.1`, the algorithm effectively averages brightness over ~10 frames, filtering out cars, people, and birds while still tracking slow lighting trends.
|
||
|
||
### Brightness Deadband
|
||
|
||
The `brightness-deadband` property creates a tolerance zone around the target brightness where no adjustments are made. This prevents oscillation caused by continuous micro-adjustments.
|
||
|
||
**How it works:**
|
||
- When brightness is within ±deadband of target, no changes are made
|
||
- When brightness exceeds the deadband, normal adjustments resume
|
||
- Allows fast corrections when needed, prevents hunting when stable
|
||
|
||
| Value | Behavior | Best For |
|
||
|-------|----------|----------|
|
||
| 0.0 | No deadband (disabled) | Maximum responsiveness (may oscillate) |
|
||
| 5.0 | Narrow deadband | Slow update rates (>500ms) |
|
||
| **10.0** | **Standard deadband (default)** | **Fast update rates (10-100ms), prevents oscillation** |
|
||
| 20.0 | Wide deadband | Very stable, less responsive |
|
||
|
||
**Example:**
|
||
- With `target-brightness=128` and `brightness-deadband=10.0`
|
||
- No adjustments when brightness is between 118-138
|
||
- Adjustments resume when brightness < 118 or > 138
|
||
|
||
**Important:** Higher deadband = more stability but less precision. Lower deadband = more precision but potential oscillation at fast update rates.
|
||
|
||
## Tips for Best Results
|
||
|
||
### Dawn/Dusk Time-Lapse (Recommended Configuration)
|
||
|
||
```
|
||
ramp-rate: vslow (5% steps - very gradual)
|
||
update-interval: 1000 (1 second between updates)
|
||
brightness-smoothing: 0.1 (filter moving objects)
|
||
brightness-deadband: 10.0 (prevent oscillation)
|
||
exposure-min: 0.85 (or camera minimum)
|
||
exposure-max: 1.24 (or 1/framerate)
|
||
gain-min: 0 (cleanest image)
|
||
gain-max: 52 (or camera limit)
|
||
target-brightness: 128
|
||
```
|
||
|
||
**Why these settings:**
|
||
- `vslow` ramp rate prevents visible exposure jumps
|
||
- 1000ms update interval allows camera hardware to settle
|
||
- Brightness smoothing filters transient changes (cars, people)
|
||
- Results in smooth, flicker-free time-lapse
|
||
|
||
### Fast Changing Conditions (with Fast Update Rates)
|
||
|
||
```
|
||
ramp-rate: fast or vfast
|
||
update-interval: 10-100 (very fast updates)
|
||
brightness-smoothing: 0.3-1.0 (more responsive)
|
||
brightness-deadband: 10.0-15.0 (ESSENTIAL to prevent oscillation)
|
||
compensation: Adjust to preference (-1.0 for darker, +1.0 for brighter)
|
||
```
|
||
|
||
**Critical:** When using fast update rates (10-100ms), `brightness-deadband` is ESSENTIAL to prevent oscillation. Without it, the algorithm will continuously overshoot and create flickering.
|
||
|
||
### Maximum Image Quality
|
||
|
||
```
|
||
gain-max: 20-30 (lower max gain = less noise)
|
||
ramp-rate: slow or vslow (smoother transitions)
|
||
update-interval: 1000-2000
|
||
```
|
||
|
||
### Avoiding Flickering and Oscillation
|
||
|
||
If you experience flickering or oscillation:
|
||
1. **Enable deadband (MOST IMPORTANT)**: Set `brightness-deadband=10.0` or higher
|
||
2. **Increase update-interval**: Start with 1000ms for slow changes, or keep at 10-100ms with deadband for fast response
|
||
3. **Decrease ramp-rate**: Use `vslow` or `slow`
|
||
4. **Enable brightness-smoothing**: Set to 0.1 or lower
|
||
|
||
**The New Solution:** With the `brightness-deadband` parameter, you can now use fast update rates (10ms) with fast ramp rates without oscillation! The deadband creates a stable zone that prevents continuous micro-adjustments.
|
||
|
||
## Troubleshooting
|
||
|
||
**Filter not adjusting exposure:**
|
||
- Verify `camera-element` property matches your camera source name
|
||
- Check that camera allows runtime exposure/gain changes
|
||
- Ensure `enabled=true` is set
|
||
|
||
**Flickering or oscillating exposure:**
|
||
- **Primary cause:** No deadband zone at fast update rates
|
||
- **Solution:** Set `brightness-deadband=10.0` (or higher)
|
||
- **Alternative:** Increase `update-interval` to 1000ms
|
||
- **Also try:** Set `ramp-rate=vslow` and `brightness-smoothing=0.1`
|
||
- **New capability:** With deadband enabled, you CAN use fast update intervals (10-100ms) for rapid response without oscillation!
|
||
|
||
**Changes too fast/slow:**
|
||
- Adjust `ramp-rate` property
|
||
- Modify `update-interval` (higher = slower convergence)
|
||
- Check `exposure-min`/`exposure-max` range is appropriate
|
||
|
||
**Brightness oscillates with moving objects:**
|
||
- Enable `brightness-smoothing=0.1` to filter transients
|
||
- Lower values (0.05) provide even more smoothing
|
||
- This filters cars, people, birds while tracking lighting trends
|
||
|
||
**Brightness not reaching target:**
|
||
- Increase `gain-max` to allow more gain
|
||
- Increase `exposure-max` if not motion-limited
|
||
- Adjust `target-brightness` or use `compensation`
|
||
|
||
**Log file not created:**
|
||
- Check file path is writable
|
||
- Verify `log-file` property is set before starting pipeline
|
||
|
||
## Comparison to YASS
|
||
|
||
| Feature | YASS (CHDK) | Intervalometer (GStreamer) |
|
||
|---------|-------------|---------------------------|
|
||
| Platform | Canon cameras with CHDK | IDS uEye cameras |
|
||
| Control | Shutter speed + ISO | Exposure time + Gain |
|
||
| Integration | Standalone Lua script | GStreamer pipeline element |
|
||
| Real-time | Script-based intervals | Frame-by-frame analysis |
|
||
| Logging | CSV to SD card | CSV to filesystem |
|
||
|
||
## Technical Notes
|
||
|
||
### Flickering Fix (2025)
|
||
|
||
The original implementation had a critical bug where exposure ramping was not actually implemented - the code would instantly jump to target values instead of gradually ramping. This caused visible flickering, especially with short update intervals.
|
||
|
||
**Fixed in [`gstintervalometer.c:688-716`](gst/intervalometer/gstintervalometer.c:688-716):**
|
||
- Implemented proper gradual ramping using the `ramp_step` variable
|
||
- Each update now applies a percentage of the delta (not instant jumps)
|
||
- Formula: `current_exposure += (target_exposure - current_exposure) × ramp_step`
|
||
|
||
### Exposure Range Query Fix
|
||
|
||
The original implementation used GObject property specs to query exposure limits, which returned incorrect values (0.0 min, DBL_MAX max). This has been fixed to use the IDS uEye SDK directly:
|
||
|
||
**Changes made:**
|
||
- Added IDS SDK header include and camera handle support
|
||
- Added `hcam` property to `idsueyesrc` to expose camera handle
|
||
- Use `is_Exposure(IS_EXPOSURE_CMD_GET_EXPOSURE_RANGE)` for proper hardware limits
|
||
- Result: Proper min/max values (e.g., [0.019 - 19.943] ms) from camera
|
||
|
||
### Brightness Smoothing
|
||
|
||
Added Exponential Moving Average (EMA) filtering to handle transient brightness changes from moving objects (cars, people, birds). This prevents exposure oscillation while maintaining responsiveness to actual lighting changes.
|
||
|
||
### Brightness Deadband (Anti-Oscillation)
|
||
|
||
Added deadband control to prevent continuous micro-adjustments that cause oscillation. When brightness is within the deadband zone (default ±10 units), no adjustments are made. This allows:
|
||
- Fast update rates (10-100ms) without oscillation
|
||
- Rapid response when changes exceed deadband
|
||
- Stable operation at any ramp rate
|
||
|
||
**Implementation in [`gstintervalometer.c:698-707`](gst/intervalometer/gstintervalometer.c:698-707):**
|
||
- Checks absolute error against deadband before making adjustments
|
||
- Skips exposure/gain changes when within tolerance
|
||
- Allows full-speed corrections when brightness significantly deviates
|
||
|
||
## License
|
||
|
||
This filter is part of gst-plugins-vision and released under the GNU Library General Public License (LGPL).
|
||
|
||
Inspired by YASS (Yet Another Sunset Script) by waterwingz, based on work by Fbonomi and soulf2, released under GPL.
|
||
|
||
## See Also
|
||
|
||
- [YASS Documentation](../../yass/README.md) - Original CHDK script that inspired this filter
|
||
- [idsueyesrc](../../sys/idsueye/gstidsueyesrc.c) - IDS uEye camera source element |