Image Streamer
The Image Streamer filter is an output filter for OpenFilter that writes images from incoming frames to local files. It supports multiple image formats, topic-based routing, wildcard topic matching, and flexible filename formatting with timestamps and frame numbering.
OverviewDirect link to Overview
The Image Streamer filter is designed to handle image output scenarios where you need to:
- Save processed images to local filesystem
- Write images in multiple formats (JPEG, PNG, BMP, TIFF, WebP)
- Route different topics to different output locations
- Use wildcard patterns to match multiple topics
- Generate timestamped and numbered filenames
- Control image quality and compression settings
- Handle multiple concurrent outputs
Key FeatureDirect link to Key Feature
- Multiple Image Formats: JPEG, PNG, BMP, TIFF, WebP with format-specific options
- Topic Routing: Route different topics to different output files/locations
- Wildcard Matching: Use
*patterns to match multiple topics (e.g.,face_*) - Flexible Filenames: Support for strftime formatting and frame numbering
- Quality Control: Configurable JPEG quality and PNG compression
- Multiple Outputs: Write the same topic to multiple locations
- Format Detection: Automatic format detection from file extensions
- Directory Creation: Automatically creates output directories
ConfigurationDirect link to Configuration
Basic ConfigurationDirect link to Basic Configuration
from openfilter.filter_runtime.filter import Filter
from openfilter.filter_runtime.filters.image_out import ImageOut
# Simple single output
Filter.run_multi([
# ... other filters above
(ImageOut, dict(
sources='tcp://localhost:5550',
outputs='file:///path/to/output_%Y%m%d_%H%M%S_%d.png',
)),
])
Advanced Configuration with Multiple OutputsDirect link to Advanced Configuration with Multiple Outputs
# Multiple outputs with different topics and options
Filter.run_multi([
# ... other filters above
(ImageOut, dict(
sources='tcp://localhost:5550',
outputs=[
'file:///path/to/main_images_%Y%m%d_%H%M%S_%d.jpg;main!quality=95',
'file:///path/to/face_images_%d.png;face_*!compression=9',
'file:///path/to/detections_%d.bmp;detection!no-bgr',
],
format='jpg', # Default format for all outputs
quality=90, # Default quality for JPEG outputs
)),
])
Environment VariablesDirect link to Environment Variables
You can configure via environment variables:
export FILTER_SOURCES="tcp://localhost:5550"
export FILTER_OUTPUTS="file:///path/to/images_%d.jpg"
export IMAGE_OUT_BGR="true"
export IMAGE_OUT_QUALITY="95"
export IMAGE_OUT_COMPRESSION="6"
Output URI FormatsDirect link to Output URI Formats
File OutputsDirect link to File Outputs
file:///absolute/path/to/image_%Y%m%d_%H%M%S_%d.png
file://relative/path/to/image_%d.jpg
file:///path/to/folder/image.png
Filename FormattingDirect link to Filename Formatting
- strftime formatting: Use standard Python strftime codes
%Y- 4-digit year%m- Month (01-12)%d- Day of month (01-31)%H- Hour (00-23)%M- Minute (00-59)%S- Second (00-59)
- Frame numbering: Use
%dfor 6-digit zero-padded frame numbers - Frame ID: Frame data metadata is used for unique identifiers
Topic MappingDirect link to Topic Mapping
Basic Topic MappingDirect link to Basic Topic Mapping
'file:///path/to/image.jpg;main' # Route 'main' topic to this file
'file:///path/to/image.jpg;camera1' # Route 'camera1' topic to this file
'file:///path/to/image.jpg' # Default to 'main' topic
Wildcard Topic MatchingDirect link to Wildcard Topic Matching
'file:///path/to/faces_%d.png;face_*' # Match all topics starting with 'face_'
'file:///path/to/detections_%d.jpg;*' # Match all topics (not recommended)
'file:///path/to/cameras_%d.jpg;camera_*' # Match all topics starting with 'camera_'
Multiple Outputs per TopicDirect link to Multiple Outputs per Topic
# Same topic can be written to multiple locations
'file:///backup/images_%d.jpg;main',
'file:///archive/images_%d.png;main',
'file:///processed/images_%d.jpg;main',
Output OptionsDirect link to Output Options
You can append options to output URIs using the ! syntax:
Format OptionsDirect link to Format Options
!format=jpg- Force JPEG format!format=png- Force PNG format!format=bmp- Force BMP format!format=tiff- Force TIFF format!format=webp- Force WebP format
Color Space OptionsDirect link to Color Space Options
!bgr- Images are in BGR format (default)!no-bgr- Images are in RGB format
Quality Options (JPEG/WebP only)Direct link to Quality Options (JPEG/WebP only)
!quality=95- JPEG quality 1-100 (higher = better quality)!quality=80- Lower quality, smaller file size
Compression Options (PNG only)Direct link to Compression Options (PNG only)
!compression=6- PNG compression level 0-9 (higher = better compression)
Configuration OptionsDirect link to Configuration Options
Global OptionsDirect link to Global Options
These apply to all outputs unless overridden:
outputs: List of output URIs with optional topic mapping and optionsbgr: Global BGR/RGB setting for all outputsformat: Global format override for all outputsquality: Global JPEG quality for all outputscompression: Global PNG compression for all outputs
Per-Output OptionsDirect link to Per-Output Options
These can be set per output using the ! syntax:
format: Image format for this specific outputbgr: BGR/RGB setting for this specific outputquality: JPEG quality for this specific outputcompression: PNG compression for this specific output
Supported Image FormatsDirect link to Supported Image Formats
| Format | Extension | Quality Control | Compression | Notes |
|---|---|---|---|---|
| JPEG | .jpg, .jpeg | ✅ (1-100) | ❌ | Most common, good compression |
| PNG | .png | ❌ | ✅ (0-9) | Lossless, supports transparency |
| BMP | .bmp | ❌ | ❌ | Uncompressed, large files |
| TIFF | .tiff, .tif | ❌ | ❌ | High quality, large files |
| WebP | .webp | ✅ (1-100) | ❌ | Modern format, good compression |
Filename GenerationDirect link to Filename Generation
The ImageOut filter generates unique filenames using multiple strategies:
Frame Numbering (%d)Direct link to frame-numbering-d
# Output pattern: file:///path/image_%d.jpg
# Generated files:
# image_000001.jpg
# image_000002.jpg
# image_000003.jpg
Timestamp FormattingDirect link to Timestamp Formatting
# Output pattern: file:///path/image_%Y%m%d_%H%M%S_%d.png
# Generated files:
# image_20241201_143052_000001.png
# image_20241201_143052_000002.png
Frame ID IntegrationDirect link to Frame ID Integration
The Image Streamer filter supports two filename generation modes:
Mode 1: Using %d for frame counting
outputs='file:///path/image_%d.jpg'
# Results in: image_000001.jpg, image_000002.jpg, etc.
# %d is replaced with 6-digit frame count
Mode 2: Using topic and frame metadata (when %d is not used)
outputs='file:///path/image.jpg'
# Results in: image_topic_frameid.jpg
# Frame ID extracted from frame.data.meta.frame_id, meta.id, or meta.timestamp
# If no metadata available, topic name is used as frame_id
Filename Generation Rules:
- If
%dis present: replaced with 6-digit frame count (e.g.,000001) - If
%dis not present: topic and frame_id are automatically appended - Frame ID priority:
meta.frame_id→meta.id→meta.timestamp→ topic name - Multiple outputs with same topic will have unique filenames via frame_id
Usage ExamplesDirect link to Usage Examples
Example 1: Basic Image SavingDirect link to Example 1: Basic Image Saving
Filter.run_multi([
# ... other filters above
(ImageOut, dict(
sources='tcp://localhost:5550',
outputs='file:///output/images_%d.jpg',
)),
])
Behavior: Saves all incoming images as JPEG files with sequential numbering.
Example 2: Multiple Topics with Different FormatsDirect link to Example 2: Multiple Topics with Different Formats
Filter.run_multi([
# ... other filters above
(ImageOut, dict(
sources='tcp://localhost:5550',
outputs=[
'file:///output/main_%Y%m%d_%d.jpg;main!quality=95',
'file:///output/faces_%d.png;face_*!compression=9',
'file:///output/detections_%d.bmp;detection!no-bgr',
],
)),
])
Behavior: Routes different topics to different formats and locations.
Example 3: Wildcard Topic MatchingDirect link to Example 3: Wildcard Topic Matching
Filter.run_multi([
# ... other filters above
(ImageOut, dict(
sources='tcp://localhost:5550',
outputs='file:///output/cameras_%d.jpg;camera_*!quality=90',
)),
])
Behavior: Matches all topics starting with 'camera_' and saves them with quality 90.
Example 4: Timestamped OutputsDirect link to Example 4: Timestamped Outputs
Filter.run_multi([
# ... other filters above
(ImageOut, dict(
sources='tcp://localhost:5550',
outputs='file:///output/images_%Y%m%d_%H%M%S_%d.png',
format='png',
compression=6,
)),
])
Behavior: Creates timestamped PNG files with compression level 6.
Example 5: Backup StrategyDirect link to Example 5: Backup Strategy
Filter.run_multi([
# ... other filters above
(ImageOut, dict(
sources='tcp://localhost:5550',
outputs=[
'file:///primary/images_%d.jpg;main!quality=95',
'file:///backup/images_%d.jpg;main!quality=80',
'file:///archive/images_%d.png;main!compression=9',
],
)),
])
Behavior: Saves the same images to multiple locations with different quality settings.
Example 6: Frame Processing PipelineDirect link to Example 6: Frame Processing Pipeline
Filter.run_multi([
# ... other filters above
(VideoIn, dict(
sources='file://input.mp4',
outputs='tcp://*:5550',
)),
(Util, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5552',
xforms='resize 1280x720',
)),
(ImageOut, dict(
sources='tcp://localhost:5552',
outputs='file:///processed/frame_%06d.jpg!quality=90',
)),
])
Behavior: Processes video frames, resizes them, and saves as high-quality JPEG files.
Error HandlingDirect link to Error Handling
The Image Streamer filter handles various error conditions gracefully:
Missing ImagesDirect link to Missing Images
- Logs warning for frames without image data
- Continues processing other frames
- Skips invalid frames without crashing
File System IssuesDirect link to File System Issues
- Automatically creates output directories
- Handles permission errors gracefully
- Logs detailed error messages
Invalid FormatsDirect link to Invalid Formats
- Validates format parameters
- Falls back to extension-based format detection
- Logs warnings for unsupported formats
Topic Matching IssuesDirect link to Topic Matching Issues
- Warns when expected topics are not found
- Continues processing available topics
- Handles wildcard matching errors gracefully
Performance ConsiderationsDirect link to Performance Considerations
File I/ODirect link to File I/O
- Images are written synchronously (blocking)
- Consider using multiple outputs for parallel writing
- SSD storage recommended for high-throughput scenarios
Memory UsageDirect link to Memory Usage
- Only image data is held in memory during write
- No image caching or buffering
- Memory usage scales with image size
Concurrent OutputsDirect link to Concurrent Outputs
- Each output is independent
- No synchronization between outputs
- Thread-safe for multiple concurrent writes
Format SelectionDirect link to Format Selection
- JPEG: Fastest encoding, good compression
- PNG: Slower encoding, lossless quality
- BMP: Fastest encoding, no compression
- TIFF: Slower encoding, large files
- WebP: Good compression, modern format
TroubleshootingDirect link to Troubleshooting
Common IssuesDirect link to Common Issues
Images Not Being SavedDirect link to Images Not Being Saved
- Check output directory exists and is writable
- Verify topic names match exactly
- Ensure frames contain image data
- Check file permissions
Wrong Image FormatDirect link to Wrong Image Format
- Verify file extension matches desired format
- Check format option syntax
- Ensure OpenCV supports the format
- Validate quality/compression parameters
Filename IssuesDirect link to Filename Issues
- Check strftime format codes
- Verify frame numbering syntax
- Ensure frame metadata is available
- Test filename pattern generation
Performance IssuesDirect link to Performance Issues
- Use faster formats (JPEG over PNG)
- Reduce image quality for smaller files
- Use SSD storage
- Consider multiple outputs for parallel writing
Debug LoggingDirect link to Debug Logging
import logging
logging.basicConfig(level=logging.DEBUG)
This will show detailed information about:
- Image writing operations
- Topic matching
- Filename generation
- Error conditions
- Format detection
Advanced UsageDirect link to Advanced Usage
Quality-Based RoutingDirect link to Quality-Based Routing
Filter.run_multi([
# ... other filters above
(ImageOut, dict(
sources='tcp://localhost:5550',
outputs=[
'file:///high_quality/images_%d.jpg;main!quality=95',
'file:///low_quality/images_%d.jpg;main!quality=60',
],
)),
])
Format Conversion PipelineDirect link to Format Conversion Pipeline
Filter.run_multi([
# ... other filters above
(ImageOut, dict(
sources='tcp://localhost:5550',
outputs=[
'file:///converted/images_%d.jpg!format=jpg!quality=90',
'file:///converted/images_%d.png!format=png!compression=6',
],
)),
])
API ReferenceDirect link to API Reference
ImageOutConfigDirect link to ImageOutConfig
class ImageOutConfig(FilterConfig):
class Output(adict):
class Options(adict):
bgr: bool | None
format: str | None
quality: int | None
compression: int | None
output: str
topic: str | None
options: Options | None
outputs: str | list[str | Output]
bgr: bool | None
format: str | None
quality: int | None
compression: int | None
ImageOutDirect link to ImageOut
class ImageOut(Filter):
FILTER_TYPE = 'Output'
@classmethod
def normalize_config(cls, config)
def init(self, config)
def create_writers(self)
def setup(self, config)
def shutdown(self)
def process(self, frames)
Environment VariablesDirect link to Environment Variables
IMAGE_OUT_BGR: Default BGR/RGB settingIMAGE_OUT_QUALITY: Default JPEG quality (1-100)IMAGE_OUT_COMPRESSION: Default PNG compression (0-9)FILTER_SOURCES: Input sourcesFILTER_OUTPUTS: Output destinations