# 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()`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.degirum.com/degirum-tools/readme.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
