Key Concepts
Core abstractions and design patterns
seekcamera-python is built around a small set of core abstractions that work together to let you discover cameras, capture thermal frames, and react to camera lifecycle events. Understanding how the camera manager, camera, frame, and event system relate to each other will help you write correct, responsive applications and avoid common pitfalls when working with one or more Seek Thermal OEM cores.
The camera manager
SeekCameraManager is the entry point for every seekcamera-python application. It owns the connection to the Seek Thermal SDK, handles device discovery, and dispatches lifecycle events to your code. You always create a manager first, and everything else flows from it.
The manager accepts an IO type argument that tells it which transport protocol to watch:
SeekCameraIOType.USB— for cameras connected over USBSeekCameraIOType.SPI— for cameras connected over SPI
Multiple cameras can be managed by a single SeekCameraManager instance. The library handles the bookkeeping; your callback receives a distinct SeekCamera object for each device.
Event-driven lifecycle
seekamera-python uses an asynchronous, event-driven model. Rather than polling for camera state, you register a callback with the manager. The SDK calls that callback whenever the state of any connected camera changes. This keeps your application responsive and avoids busy-waiting.
Each callback invocation receives a SeekCameraManagerEvent that describes what happened:
| Event | Meaning |
|---|---|
CONNECT | A camera connected and is paired — ready to stream |
DISCONNECT | A previously connected camera has been removed |
ERROR | A connected camera has reported an error |
READY_TO_PAIR | A new, unpaired camera has connected |
Your callback signature receives the SeekCamera instance, the event type, the error status (if any), and an optional user-data object you pass when registering the callback. This lets you share application state with the callback without relying on global variables.
Camera objects
SeekCamera represents a single physical camera core. You never construct one directly — the manager creates and passes camera objects to your event callback. A camera object exposes:
- Capture control — start and stop frame streaming
- Image pipeline settings — color palette, AGC mode, shutter mode, temperature units, filters, and pipeline mode
- Device identity — firmware version, IO properties (bus number, port numbers, or chip-select)
- App resource regions — three reserved memory regions on the device for customer data
All camera settings are applied per-device, so when you work with multiple cameras you configure each SeekCamera object independently.
IO properties
Each camera carries an SeekCameraIOProperties object that describes its physical connection. You can inspect camera.io_properties.type to determine whether a camera is USB or SPI, then read the relevant sub-object (usb or spi) for bus and port information. This is useful when you need to distinguish between cameras of the same model.
Frame capture and the frame callback
Once a camera is connected, you start streaming by calling the capture session method on the SeekCamera object and providing a frame callback. The SDK calls this callback every time a new frame is available.
Each frame callback invocation receives a SeekCameraFrame object. You lock the frame to access its data safely, then request the specific format you need.
Frame formats
SeekCameraFrameFormat controls what kind of data a frame contains. Common formats include colorized ARGB images (ready for display) and thermography data (floating-point temperatures per pixel). You specify the format(s) you want when you start the capture session, and the SDK processes only the requested formats — avoiding unnecessary computation.
SeekFrame and numpy integration
Calling the appropriate accessor on a locked SeekCameraFrame returns a SeekFrame object. Its .data property exposes the frame pixel data as a numpy array, which makes it straightforward to pass frames to libraries like OpenCV, run numerical analysis, or write values to disk. Frame metadata (width, height, timestamps, etc.) is available via SeekCameraFrameHeader.
Image processing pipeline
The SDK processes raw sensor data through a configurable pipeline before delivering frames to your callback. Key pipeline concepts:
- Pipeline mode (
SeekCameraPipelineMode) — selects the overall processing profile:LITE,LEGACY, orSEEKVISION. - AGC (Automated Gain Control) — maps raw thermal data to the 8-bit display range.
SeekCameraAGCModeselects between linear min/max (LINEAR) and histogram equalization (HISTEQ).SeekCameraLinearAGCLockModelets you fix the min, max, or both bounds manually. - Color palette (
SeekCameraColorPalette) — controls colorization of display-ready frames. Built-in palettes includeWHITE_HOT,BLACK_HOT,IRON,SPECTRA, and others. You can also define custom palettes withSeekCameraColorPaletteData, which holds 256 BGRA entries going from coldest to hottest. - Filters (
SeekCameraFilter) — optional per-frame processing steps such as gradient correction, flat scene correction, and sharpening. Each filter can be independently enabled or disabled viaSeekCameraFilterState. - Shutter mode (
SeekCameraShutterMode) — applicable to Mosaic cores only; controls whether calibration shuttering is automatic or manually triggered. - Temperature unit (
SeekCameraTemperatureUnit) — selects Celsius, Fahrenheit, or Kelvin for thermography frames.
Error handling
The library represents errors as Python exceptions that all inherit from SeekCameraError. Each error condition has a specific subclass (for example, SeekCameraDeviceCommunicationError, SeekCameraNotPairedError, SeekCameraTimeoutError), so you can handle them selectively with standard try/except blocks. Errors delivered through the event callback carry a status code you can inspect to determine the cause.
Using multiple cameras
Because the event-driven model delivers a distinct SeekCamera object per device, supporting multiple cameras requires no special setup. A single SeekCameraManager instance and a single callback function handle all connected devices. Your callback receives the specific camera that triggered the event, so you can maintain per-camera state in a dictionary or similar structure, keyed by camera identity.
Context manager support
SeekCameraManager supports Python's context manager protocol (with statement), which ensures the SDK is properly shut down and resources are released even if an exception occurs. Using it as a context manager is strongly recommended over manual lifecycle management.
Minimal event-driven skeleton
This example shows the relationship between the manager, the event callback, and a camera object. It prints each lifecycle event as it arrives.
from seekcamera import SeekCameraManager, SeekCameraIOType, SeekCameraManagerEvent
def on_event(camera, event_type, error, user_data):
if event_type == SeekCameraManagerEvent.CONNECT:
print(f"Camera connected: {camera}")
elif event_type == SeekCameraManagerEvent.DISCONNECT:
print(f"Camera disconnected: {camera}")
elif event_type == SeekCameraManagerEvent.ERROR:
print(f"Camera error: {error}")
elif event_type == SeekCameraManagerEvent.READY_TO_PAIR:
print(f"Camera ready to pair: {camera}")
with SeekCameraManager(SeekCameraIOType.USB) as manager:
manager.register_event_callback(on_event)
input("Press Enter to exit...\n")
Expected output (with one USB camera attached):
Camera connected: <SeekCamera ...>
Press Enter to exit...
Capturing frames and accessing pixel data
Once a camera connects, start a capture session and supply a frame callback. This example requests a thermography frame and prints the mean temperature across the scene.
from seekcamera import (
SeekCameraManager,
SeekCameraIOType,
SeekCameraManagerEvent,
SeekCameraFrameFormat,
)
def on_frame(camera, camera_frame, user_data):
with camera_frame as frame:
thermography = frame.get_thermography_float()
mean_temp = thermography.data.mean()
print(f"Mean scene temperature: {mean_temp:.2f} °C")
def on_event(camera, event_type, error, user_data):
if event_type == SeekCameraManagerEvent.CONNECT:
camera.register_frame_available_callback(on_frame)
camera.capture_session_start(SeekCameraFrameFormat.THERMOGRAPHY_FLOAT)
elif event_type == SeekCameraManagerEvent.DISCONNECT:
camera.capture_session_stop()
with SeekCameraManager(SeekCameraIOType.USB) as manager:
manager.register_event_callback(on_event)
input("Press Enter to exit...\n")
Expected output (values depend on scene temperature):
Mean scene temperature: 24.73 °C
Mean scene temperature: 24.71 °C
...
Configuring the image pipeline
This snippet shows how to set a color palette and AGC mode on a connected camera before starting capture. Apply settings inside the CONNECT handler so they take effect before the first frame arrives.
from seekcamera import (
SeekCameraManagerEvent,
SeekCameraColorPalette,
SeekCameraAGCMode,
SeekCameraFrameFormat,
)
def on_event(camera, event_type, error, user_data):
if event_type == SeekCameraManagerEvent.CONNECT:
camera.color_palette = SeekCameraColorPalette.TYRIAN
camera.agc_mode = SeekCameraAGCMode.HISTEQ
camera.register_frame_available_callback(on_frame)
camera.capture_session_start(SeekCameraFrameFormat.COLOR_ARGB8888)
Distinguishing multiple cameras by IO properties
When more than one camera is attached, use IO properties to tell them apart.
from seekcamera import SeekCameraIOType, SeekCameraManagerEvent
def on_event(camera, event_type, error, user_data):
if event_type == SeekCameraManagerEvent.CONNECT:
props = camera.io_properties
if props.type == SeekCameraIOType.USB:
bus = props.usb.bus_number
ports = [p for p in props.usb.port_numbers if p > 0]
print(f"USB camera on bus {bus}, ports {ports}")
Expected output (with two cameras on different buses):
USB camera on bus 1, ports [2]
USB camera on bus 3, ports [1, 4]
Handling errors selectively
from seekcamera import (
SeekCameraManagerEvent,
SeekCameraDeviceCommunicationError,
SeekCameraTimeoutError,
)
def on_event(camera, event_type, error, user_data):
if event_type == SeekCameraManagerEvent.ERROR:
try:
raise error
except SeekCameraDeviceCommunicationError:
print("Communication lost — check the physical connection.")
except SeekCameraTimeoutError:
print("Operation timed out — the camera may be busy.")
except Exception as e:
print(f"Unexpected error: {e}")
- Installation — Set up the Seek Thermal SDK and install seekcamera-python before working with these abstractions.
- Sample applications — The
seekcamera-opencvandseekcamera-simpleexamples demonstrate a complete, working integration of the manager, event callback, and frame callback patterns described here. - Error reference — Full list of
SeekCameraErrorsubclasses and the conditions that raise them. - Frame formats reference — Details on every
SeekCameraFrameFormatvalue and the numpy array shape and dtype each one produces. - Working with multiple cameras — Patterns for managing per-camera state and coordinating capture sessions across several devices simultaneously.