# Overview

{% hint style="info" %}
This overview was written for DeGirum Tools version 0.24.1.
{% endhint %}

## Core Concepts

DeGirum Tools extends PySDK with a kit for building multi-threaded, low-latency media pipelines.\
Where PySDK focuses on running a single model well, DeGirum Tools focuses on everything around it: video ingest, pre- and post-processing, multi-model fusion, result annotation, stream routing, and more.

In one sentence:

> DeGirum Tools is a flow-based mini-framework that lets you prototype complex AI applications in a few dozen lines of Python.

### Model Registry

Use the [Model Registry](https://docs.degirum.com/degirum-tools/model_registry) when you need reproducible model picks across hardware. Describe each model once in YAML, filter by `task`, `hardware`, or metadata, and load it through the generated `ModelSpec` helpers. Registry entries can also capture connection defaults so you can keep reusing the same `inference_manager` created via `degirum.connect`.

### Inference Support Utilities

The [inference\_support](https://docs.degirum.com/degirum-tools/inference_support) helpers smooth the edges between PySDK and your application. Inference Support utilities include:

* [attach\_analyzers()](https://docs.degirum.com/degirum-tools/inference_support#attach_analyzers) – layer result analyzers without wrapping your model manually.
* [predict\_stream()](https://docs.degirum.com/degirum-tools/inference_support#predict_stream) / [annotate\_video()](https://docs.degirum.com/degirum-tools/inference_support#annotate_video) – quick video loops when a full gizmo graph is overkill.
* [model\_time\_profile()](https://docs.degirum.com/degirum-tools/inference_support#model_time_profile) – benchmark a model in fewer than 10 lines of code.
* [warmup\_device()](https://docs.degirum.com/degirum-tools/inference_support#warmup_device) / [warmup\_model()](https://docs.degirum.com/degirum-tools/inference_support#warmup_model) – preheat hardware so the first real inference arrives at full speed.

### Compound Models

[Compound models](https://docs.degirum.com/degirum-tools/compound_models) wrap two PySDK models into a single `predict()` / `predict_batch()` interface. Some of the compound model classes provided by DeGirum Tools include:

| Class                                                                                                                             | What it Does                                                            |
| --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| [CombiningCompoundModel](https://docs.degirum.com/degirum-tools/compound_models#combiningcompoundmodel)                           | Runs two models in parallel on the same image and concatenates results. |
| [CroppingAndClassifyingCompoundModel](https://docs.degirum.com/degirum-tools/compound_models#croppingandclassifyingcompoundmodel) | Detector → crops → classifier (adds labels back).                       |
| [CroppingAndDetectingCompoundModel](https://docs.degirum.com/degirum-tools/compound_models#croppinganddetectingcompoundmodel)     | Detector → crops → refined detector (with optional NMS).                |

Use compound models exactly how you would use normal models:

```python
compound = CroppingAndClassifyingCompoundModel(detector, classifier)
for res in compound.predict_batch(my_images):
    ...
```

In addition to compound models, you may encounter PseudoModels.

A PseudoModel is a ModelLike object that behaves like a PySDK model but does not actually run inference. Instead, it generates bounding-box results according to predefined rules, such as dividing an image into a grid (TileExtractorPseudoModel) or returning fixed ROIs with optional motion filtering (RegionExtractionPseudoModel).

These pseudo‑models serve as drop‑in “detectors” within compound-model pipelines, allowing ROI extraction and tiling without relying on a real detection network, while still following the standard predict()/predict\_batch() interface.

### Streams

The flow behind DeGirum Tools is supported by the Streams subsystem. There are three constituent Python submodules: [streams.py](#streams), [streams\_base.py](https://docs.degirum.com/degirum-tools/streams/streams_base), and [streams\_gizmos.py](https://docs.degirum.com/degirum-tools/streams/streams_gizmos). In this subsystem, the two most important concepts in streams are gizmos and compositions.

#### Gizmos

A [Gizmo](https://docs.degirum.com/degirum-tools/streams/streams_gizmos) is a worker that:

{% stepper %}
{% step %}
Consumes from one or more input streams.
{% endstep %}

{% step %}
Runs its custom `run()` loop (decode, resize, infer, etc.).
{% endstep %}

{% step %}
Pushes new `StreamData` to any number of output streams. `StreamData` is described in more detail in [streams.py](#streams).
{% endstep %}
{% endstepper %}

Because every gizmo lives in its own thread, pipelines scale across CPU cores with minimal user code.

Gizmo families built into DeGirum Tools include:

| Family       | Example Classes                                                                                                                                                                                                                                                                                                               | Typical Use                                                                       |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| Video IO     | <p><a href="../streams/streams_gizmos#videosourcegizmo">VideoSourceGizmo</a>,</p><p><a href="../streams/streams_gizmos#iteratorsourcegizmo">IteratorSourceGizmo</a>, <a href="../streams/streams_gizmos#videodisplaygizmo">VideoDisplayGizmo</a>, <a href="../streams/streams_gizmos#videosavergizmo">VideoSaverGizmo</a></p> | Camera/file capture; iterate images from paths/arrays/PIL; live preview; archival |
| Transform    | [ResizingGizmo](https://docs.degirum.com/degirum-tools/streams/streams_gizmos#resizinggizmo)                                                                                                                                                                                                                                  | Pre-process frames (letterbox, crop, pad)                                         |
| AI Inference | [AiSimpleGizmo](https://docs.degirum.com/degirum-tools/streams/streams_gizmos#aisimplegizmo), [AiObjectDetectionCroppingGizmo](https://docs.degirum.com/degirum-tools/streams/streams_gizmos#aiobjectdetectioncroppinggizmo)                                                                                                  | Run models, cascade detectors & classifiers                                       |
| Post-fusion  | [CropCombiningGizmo](https://docs.degirum.com/degirum-tools/streams/streams_gizmos#cropcombininggizmo), [AiResultCombiningGizmo](https://docs.degirum.com/degirum-tools/streams/streams_gizmos#airesultcombininggizmo)                                                                                                        | Merge multi-crop or multi-model outputs                                           |
| Utility      | [SinkGizmo](https://docs.degirum.com/degirum-tools/streams/streams_gizmos#sinkgizmo), [FPSStabilizingGizmo](https://docs.degirum.com/degirum-tools/streams/streams_gizmos#fpsstabilizinggizmo)                                                                                                                                | Collect results in the main thread; stabilize frame rate                          |

Gizmos pass data around by using the [Stream](https://docs.degirum.com/degirum-tools/streams/streams_base#stream) class. A stream is an iterable queue that moves `StreamData` objects between threads. Each queue may be bounded (with optional drop policy) to prevent bottlenecks, and it automatically propagates a poison pill sentinel to shut the pipeline down cleanly.

#### Stream Validation and Tag Requirements

Starting with DeGirum Tools 0.20.0, gizmos declare upstream metadata requirements via a `require_tags(inp)` method. When you build a `Composition`, it validates that each gizmo’s requirements are satisfied by the connected upstream stages and raises an error when they are not.

Examples:

* Cropping/combining and analyzer gizmos require inference-related tags from upstream inference stages.
* FPS stabilizing gizmos require video tags from upstream sources.

This check helps catch wiring mistakes early when you assemble larger graphs.

#### Compositions

A [Composition](https://docs.degirum.com/degirum-tools/streams/streams_base#composition) collects any connected gizmos and controls their life-cycle:

* `start()` – spawn threads
* `stop()` – signal abort & join
* `wait()` – block until completion
* `get_bottlenecks()` – diagnose dropped-frame hotspots

Use it as a context-manager so everything shuts down even on exceptions.

For activity monitoring, see [Watchdog](https://docs.degirum.com/degirum-tools/streams/streams_base#watchdog), which tracks tick frequency and timing to detect stalls.

### Analyzers

Analyzers provide advanced processing of inference results with specialized functionality. The available analyzers include:

| Analyzer                                                                            | Description                                                        |
| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| [Zone Counter](https://docs.degirum.com/degirum-tools/analyzers/zone_count)         | Tracks objects entering and exiting defined zones                  |
| [Object Selector](https://docs.degirum.com/degirum-tools/analyzers/object_selector) | Filters and selects specific objects based on criteria             |
| [Object Tracker](https://docs.degirum.com/degirum-tools/analyzers/object_tracker)   | Tracks objects across frames with customizable tracking parameters |
| [Line Counter](https://docs.degirum.com/degirum-tools/analyzers/line_count)         | Counts objects crossing defined lines in the scene                 |
| [Event Detector](https://docs.degirum.com/degirum-tools/analyzers/event_detector)   | Detects and processes specific events in the video stream          |
| [Notifier](https://docs.degirum.com/degirum-tools/analyzers/notifier)               | Sends notifications for detected events and conditions             |
| [Clip Saver](https://docs.degirum.com/degirum-tools/analyzers/clip_saver)           | Saves video clips of detected events                               |

An [Analyzer](https://docs.degirum.com/degirum-tools/analyzers) subclass provides two key capabilities:

* `analyze(result)` – Process and modify inference results by adding custom fields or performing calculations
* `annotate(result, image)` – Draw overlays on the image (bounding boxes, text labels, etc.)

Analyzers can be attached to any model or compound model:

```python
import degirum_tools
import numpy as np

# Create a line counter that counts people crossing a line

LINES: List[Tuple[int, int, int, int]] = [
    (634, 539, 950, 539),
]
window_name = "Line Counter"

# Create an ObjectTracker to track people
tracker = degirum_tools.ObjectTracker(
    trail_depth=20, anchor_point=degirum_tools.AnchorPoint.BOTTOM_CENTER
)

# Create a LineCounter to detect when people cross pre-defined lines
counter = degirum_tools.LineCounter(lines)

# Attach ObjectTracker and LineCounter to the model
degirum_tools.attach_analyzers(model, [tracker, counter])

# Run predictions and print the line counts
for result in degirum_tools.predict_stream(model, video_source):
    if hasattr(result, "line_counts"):
        print([lc.to_dict() for lc in result.line_counts])

```

When used inside a gizmo pipeline, analyzers can filter or decorate results in-flight. They can also accumulate state across frames for multi-frame analysis, with cleanup handled in the `finalize()` method.

### Support Modules

DeGirum Tools includes other [Support Modules](https://docs.degirum.com/degirum-tools/support):

* [Math Support](https://docs.degirum.com/degirum-tools/support/math_support): geometry, NMS, tiling, and k-means helpers.
* [UI Support](https://docs.degirum.com/degirum-tools/support/ui_support): display, FPS meter, timers, and image stacks.
* [Video Support](https://docs.degirum.com/degirum-tools/support/video_support): open or create streams (e.g., `create_video_stream`), detect devices/RTSP sources (`detect_rtsp_cameras`).
* Additional modules: audio I/O, evaluation framework, object storage helpers.

### Environment Variables

See [Environment Variables](https://docs.degirum.com/degirum-tools/environment-variables) for configuration keys used by DeGirum Tools and helpers.

### Remote Assets

Use the lightweight [Remote Assets](https://docs.degirum.com/degirum-tools/remote-assets) catalog to reference sample images and videos from PySDK Examples without downloading files. Access them via module attributes (for example, `remote_assets.cat`) or enumerate names with `list_images()` and `list_videos()`.
