Files
gst-plugin-linescan/gst/intervalometer/README.md
2025-11-18 01:12:52 +02:00

371 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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) |
### 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 \
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)
### 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:
1. **Brightness Analysis**: Calculates average brightness of each frame
2. **Error Calculation**: Compares to target brightness (with compensation)
3. **Ramping Priority**:
- When too bright: Decreases exposure first, then gain
- When too dark: Increases exposure first (up to max), then gain
4. **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.
## 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)
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
```
ramp-rate: fast or vfast
update-interval: 100-500
brightness-smoothing: 0.3-1.0 (more responsive)
compensation: Adjust to preference (-1.0 for darker, +1.0 for brighter)
```
### 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
If you experience flickering or oscillation:
1. **Increase update-interval**: Start with 1000ms
2. **Decrease ramp-rate**: Use `vslow` or `slow`
3. **Enable brightness-smoothing**: Set to 0.1 or lower
4. **Check your settings**: At 50fps, 100ms updates = every 5 frames (too fast!)
## 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:** Update interval too fast for your frame rate
- **Solution:** Increase `update-interval` to 1000ms
- **Also try:** Set `ramp-rate=vslow` and `brightness-smoothing=0.1`
- **At 50fps:** Never use update intervals < 500ms
**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.
## 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