Skip to main content

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 %d for 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 options
  • bgr: Global BGR/RGB setting for all outputs
  • format: Global format override for all outputs
  • quality: Global JPEG quality for all outputs
  • compression: 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 output
  • bgr: BGR/RGB setting for this specific output
  • quality: JPEG quality for this specific output
  • compression: PNG compression for this specific output

Supported Image FormatsDirect link to Supported Image Formats

FormatExtensionQuality ControlCompressionNotes
JPEG.jpg, .jpeg✅ (1-100)Most common, good compression
PNG.png✅ (0-9)Lossless, supports transparency
BMP.bmpUncompressed, large files
TIFF.tiff, .tifHigh 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 %d is present: replaced with 6-digit frame count (e.g., 000001)
  • If %d is not present: topic and frame_id are automatically appended
  • Frame ID priority: meta.frame_idmeta.idmeta.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

  1. Check output directory exists and is writable
  2. Verify topic names match exactly
  3. Ensure frames contain image data
  4. Check file permissions

Wrong Image FormatDirect link to Wrong Image Format

  1. Verify file extension matches desired format
  2. Check format option syntax
  3. Ensure OpenCV supports the format
  4. Validate quality/compression parameters

Filename IssuesDirect link to Filename Issues

  1. Check strftime format codes
  2. Verify frame numbering syntax
  3. Ensure frame metadata is available
  4. Test filename pattern generation

Performance IssuesDirect link to Performance Issues

  1. Use faster formats (JPEG over PNG)
  2. Reduce image quality for smaller files
  3. Use SSD storage
  4. 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 setting
  • IMAGE_OUT_QUALITY: Default JPEG quality (1-100)
  • IMAGE_OUT_COMPRESSION: Default PNG compression (0-9)
  • FILTER_SOURCES: Input sources
  • FILTER_OUTPUTS: Output destinations