# Tile Compound Models

{% hint style="info" %}
This API Reference is based on DeGirum Tools version 1.2.0.
{% endhint %}

## Tile Compound Models Module Overview <a href="#tile-compound-models-module-overview" id="tile-compound-models-module-overview"></a>

This module implements tiling-based compound models for object detection. It provides pseudo-models that extract image tiles and combine results from real detection models to efficiently process large images.

Key Features

* **Tile Extraction**: Generate local and global tiles with configurable overlap
* **Two-Stage Processing**: Run detection on each tile then merge results
* **Edge-Aware Fusion**: Optional fusion of detections near tile boundaries
* **Motion Filtering**: Skip tiles without motion to reduce computation
* **Result Management**: Translate box coordinates and apply NMS

Typical Usage

1. Create a `TileExtractorPseudoModel` with grid parameters
2. Wrap it in `TileModel` or a derived class along with a detection model
3. Iterate over `predict_batch` to obtain merged detection results

Integration Notes

* Designed for DeGirum PySDK models
* Works with compound model utilities such as cropping and NMS
* Supports customization of crop extent and overlap thresholds
* Compatible with local and cloud inference backends

Key Classes

* `TileExtractorPseudoModel`: Produces image tiles for downstream models
* `TileModel`: Runs detection on each tile and merges results
* `LocalGlobalTileModel`: Combines global and local tiles with size-based filtering
* `BoxFusionTileModel`: Fuses edge detections across tiles

Configuration Options

* Tile grid size and overlap
* Motion detection thresholds
* Edge fusion parameters
* NMS settings for final results

## Classes <a href="#classes" id="classes"></a>

## TileExtractorPseudoModel <a href="#tileextractorpseudomodel" id="tileextractorpseudomodel"></a>

`TileExtractorPseudoModel`

Bases: `ModelLike`

Extracts a grid of (optionally-overlapping) image tiles.

The class behaves like a DeGirum pseudo-model: instead of running inference it produces synthetic detection results whose bounding boxes correspond to tile coordinates. These results are then consumed by a second, real model in a two-stage compound pipeline.

Parameters:

| Name              | Type                          | Description                                                                                                                                                                     | Default    |
| ----------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `cols`            | `int`                         | Number of columns in the tile grid.                                                                                                                                             | *required* |
| `rows`            | `int`                         | Number of rows in the tile grid.                                                                                                                                                | *required* |
| `overlap_percent` | `float`                       | Desired overlap between neighbouring tiles, expressed as a fraction in \[0, 1].                                                                                                 | *required* |
| `model2`          | `Model`                       | The downstream model that will receive each tile.                                                                                                                               | *required* |
| `global_tile`     | `bool`                        | If True, emit an additional tile that represents the entire image (label "GLOBAL"). Mutually exclusive with tile\_mask and motion\_detect. Defaults to False.                   | `False`    |
| `tile_mask`       | `list[int] \| None`           | Indices of tiles (0-based, row-major) to keep. Tiles not listed are skipped. Ignored when global\_tile is True.                                                                 | `None`     |
| `motion_detect`   | `MotionDetectOptions \| None` | Enable per-tile motion filtering. Tiles in which less than threshold x area pixels changed during the last look\_back frames are suppressed. Ignored when global\_tile is True. | `None`     |

Raises:

| Type             | Description                                   |
| ---------------- | --------------------------------------------- |
| `AssertionError` | If mutually-exclusive arguments are supplied. |

### TileExtractorPseudoModel Methods <a href="#tileextractorpseudomodel-methods" id="tileextractorpseudomodel-methods"></a>

#### \_\_init\_\_(cols, ...) <a href="#init" id="init"></a>

`__init__(cols, rows, overlap_percent, model2, *, global_tile=False, tile_mask=None, motion_detect=None)`

Constructor.

Parameters:

| Name              | Type                          | Description                                                                                                                                   | Default    |
| ----------------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `cols`            | `int`                         | Number of columns to divide the image into.                                                                                                   | *required* |
| `rows`            | `int`                         | Number of rows to divide the image into.                                                                                                      | *required* |
| `overlap_percent` | `float`                       | Desired overlap between neighbouring tiles.                                                                                                   | *required* |
| `model2`          | `Model`                       | Model which will be used as a second step of the compound model pipeline.                                                                     | *required* |
| `global_tile`     | `bool`                        | Indicates whether the global (whole) image should also be sent to model2.                                                                     | `False`    |
| `tile_mask`       | `list[int] \| None`           | Optional list of indices to keep during tile generation. Tile indices are counted starting from the top row to the bottom row, left to right. | `None`     |
| `motion_detect`   | `MotionDetectOptions \| None` | Motion detection options. When None, motion detection is disabled. When enabled, ROI boxes where motion is not detected will be skipped.      | `None`     |

#### predict\_batch(data) <a href="#predict_batch" id="predict_batch"></a>

`predict_batch(data)`

Perform whole inference lifecycle for all objects in given iterator object (for example, `list`).

Parameters:

| Name   | Type       | Description                                                                                                                                                               | Default    |
| ------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `data` | `Iterable` | Inference input data iterator object such as list or generator function. Each element returned by this iterator should be compatible to that regular PySDK model accepts. | *required* |

Yields:

| Type               | Description                                                                                  |
| ------------------ | -------------------------------------------------------------------------------------------- |
| `DetectionResults` | Combined inference result objects. This allows you directly using the result in `for` loops. |

## TileModel <a href="#tilemodel" id="tilemodel"></a>

`TileModel`

Bases: `CroppingAndDetectingCompoundModel`

Tiling wrapper that runs detection on every tile.

This compound model wires a TileExtractorPseudoModel (model 1) to a normal detection model (model 2). Each tile is cropped, passed to model 2, and the resulting boxes are translated back to the original image coordinates. Optionally, detections from model 1 can be merged or deduplicated via NMS.

Parameters:

| Name                 | Type                       | Description                                                                                    | Default                      |
| -------------------- | -------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------- |
| `model1`             | `TileExtractorPseudoModel` | The tile generator.                                                                            | *required*                   |
| `model2`             | `Model`                    | A detection model compatible with model1's image backend.                                      | *required*                   |
| `crop_extent`        | `float`                    | Extra context (percent of box size) to include around every tile before passing it to model 2. | `0`                          |
| `crop_extent_option` | `CropExtentOptions`        | How the extra context is applied.                                                              | `ASPECT_RATIO_NO_ADJUSTMENT` |
| `add_model1_results` | `bool`                     | If True, detections produced by model 1 are appended to the final result.                      | `False`                      |
| `nms_options`        | `NmsOptions \| None`       | Non-maximum suppression settings performed on the merged result.                               | `None`                       |

Attributes:

| Name                      | Type  | Description                                                                                          |
| ------------------------- | ----- | ---------------------------------------------------------------------------------------------------- |
| `output_postprocess_type` | `str` | Mirrors model2.output\_postprocess\_type so downstream tooling recognises this as a detection model. |

Raises:

| Type        | Description                                      |
| ----------- | ------------------------------------------------ |
| `Exception` | If the two models use different image back-ends. |

### TileModel Methods <a href="#tilemodel-methods" id="tilemodel-methods"></a>

#### \_\_init\_\_(model1, ...) <a href="#init" id="init"></a>

`__init__(model1, model2, *, crop_extent=0, crop_extent_option=CropExtentOptions.ASPECT_RATIO_NO_ADJUSTMENT, add_model1_results=False, nms_options=None)`

Constructor.

Parameters:

| Name                 | Type                       | Description                                                      | Default                      |
| -------------------- | -------------------------- | ---------------------------------------------------------------- | ---------------------------- |
| `model1`             | `TileExtractorPseudoModel` | Tile extractor pseudo-model.                                     | *required*                   |
| `model2`             | `Model`                    | PySDK object detection model.                                    | *required*                   |
| `crop_extent`        | `float`                    | Extent of cropping in percent of bbox size.                      | `0`                          |
| `crop_extent_option` | `CropExtentOptions`        | Method of applying extending crop to the input image for model2. | `ASPECT_RATIO_NO_ADJUSTMENT` |
| `add_model1_results` | `bool`                     | True to add detections of model1 to the combined result.         | `False`                      |
| `nms_options`        | `NmsOptions \| None`       | Non-maximum suppression (NMS) options.                           | `None`                       |

## LocalGlobalTileModel <a href="#localglobaltilemodel" id="localglobaltilemodel"></a>

`LocalGlobalTileModel`

Bases: `TileModel`

Runs a fine-/coarse tiling strategy with size-based result fusion.

Two kinds of tiles are produced:

* Local: the regular grid (fine resolution)
* Global: a single full-frame tile

After detection:

* Large objects (area >= large\_object\_threshold x image\_area) are kept only from the global tile.
* Small objects are kept only from the local tiles.

Parameters:

| Name                     | Type                       | Description                                                                                    | Default                      |
| ------------------------ | -------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------- |
| `model1`                 | `TileExtractorPseudoModel` | Must be configured with global\_tile=True.                                                     | *required*                   |
| `model2`                 | `Model`                    | Detection model run on each tile.                                                              | *required*                   |
| `large_object_threshold` | `float`                    | Area ratio separating "large" from "small" objects. Defaults to 0.01.                          | `0.01`                       |
| `crop_extent`            | `float`                    | Extra context (percent of box size) to include around every tile before passing it to model 2. | `0`                          |
| `crop_extent_option`     | `CropExtentOptions`        | How the extra context is applied.                                                              | `ASPECT_RATIO_NO_ADJUSTMENT` |
| `add_model1_results`     | `bool`                     | If True, detections produced by model 1 are appended to the final result.                      | `False`                      |
| `nms_options`            | `NmsOptions \| None`       | Non-maximum suppression settings performed on the merged result.                               | `None`                       |

Note

Unlike BoxFusionLocalGlobalTileModel, no edge fusion is applied; objects that overlap tile borders may be duplicated.

### LocalGlobalTileModel Methods <a href="#localglobaltilemodel-methods" id="localglobaltilemodel-methods"></a>

#### \_\_init\_\_(model1, ...) <a href="#init" id="init"></a>

`__init__(model1, model2, large_object_threshold=0.01, *, crop_extent=0, crop_extent_option=CropExtentOptions.ASPECT_RATIO_NO_ADJUSTMENT, add_model1_results=False, nms_options=None)`

Constructor.

Parameters:

| Name                     | Type                       | Description                                                                                                           | Default                      |
| ------------------------ | -------------------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
| `model1`                 | `TileExtractorPseudoModel` | Tile extractor pseudo-model.                                                                                          | *required*                   |
| `model2`                 | `Model`                    | PySDK object detection model.                                                                                         | *required*                   |
| `large_object_threshold` | `float`                    | A threshold to determine if an object is considered large or not. This is relative to the area of the original image. | `0.01`                       |
| `crop_extent`            | `float`                    | Extent of cropping in percent of bbox size.                                                                           | `0`                          |
| `crop_extent_option`     | `CropExtentOptions`        | Method of applying extending crop to the input image for model2.                                                      | `ASPECT_RATIO_NO_ADJUSTMENT` |
| `add_model1_results`     | `bool`                     | True to add detections of model1 to the combined result.                                                              | `False`                      |
| `nms_options`            | `NmsOptions \| None`       | Non-maximum suppression (NMS) options.                                                                                | `None`                       |

#### transform\_result2(result2) <a href="#transform_result2" id="transform_result2"></a>

`transform_result2(result2)`

Transform result of the **second model**.

This implementation combines results of the **second model** over all bboxes detected by the first model, translating bbox coordinates to original image coordinates.

Parameters:

| Name      | Type               | Description                               | Default    |
| --------- | ------------------ | ----------------------------------------- | ---------- |
| `result2` | `DetectionResults` | Detection result of the **second model**. | *required* |

Returns:

| Type                       | Description                                                                                                                                                                                           |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DetectionResults or None` | Combined results of the **second model** over all bboxes detected by the first model, where bbox coordinates are translated to original image coordinates. Returns None if no new frame is available. |

## BoxFusionTileModel <a href="#boxfusiontilemodel" id="boxfusiontilemodel"></a>

`BoxFusionTileModel`

Bases: `_EdgeMixin`, `TileModel`

TileModel with edge/overlap-aware bounding-box fusion.

After model 2 has produced detections for every tile, boxes whose centres fall within the user-defined edge band are compared with neighbours. If the 1-D IoU in either axis exceeds fusion\_threshold the boxes are merged (weighted-box fusion).

Parameters:

| Name                 | Type                       | Description                                                                                    | Default                      |
| -------------------- | -------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------- |
| `model1`             | `TileExtractorPseudoModel` | Tile generator.                                                                                | *required*                   |
| `model2`             | `Model`                    | Detection model.                                                                               | *required*                   |
| `edge_threshold`     | `float`                    | Size of the edge band expressed as a fraction of tile width/height. Defaults to 0.02.          | `0.02`                       |
| `fusion_threshold`   | `float`                    | 1-D IoU needed to fuse two edge boxes. Defaults to 0.8.                                        | `0.8`                        |
| `crop_extent`        | `float`                    | Extra context (percent of box size) to include around every tile before passing it to model 2. | `0`                          |
| `crop_extent_option` | `CropExtentOptions`        | How the extra context is applied.                                                              | `ASPECT_RATIO_NO_ADJUSTMENT` |
| `add_model1_results` | `bool`                     | If True, detections produced by model 1 are appended to the final result.                      | `False`                      |
| `nms_options`        | `NmsOptions \| None`       | Non-maximum suppression settings performed on the merged result.                               | `None`                       |

### BoxFusionTileModel Methods <a href="#boxfusiontilemodel-methods" id="boxfusiontilemodel-methods"></a>

#### \_\_init\_\_(model1, ...) <a href="#init" id="init"></a>

`__init__(model1, model2, edge_threshold=0.02, fusion_threshold=0.8, *, crop_extent=0, crop_extent_option=CropExtentOptions.ASPECT_RATIO_NO_ADJUSTMENT, add_model1_results=False, nms_options=None)`

Constructor.

Parameters:

| Name                 | Type                       | Description                                                                                                                                                                                                                                                                                                  | Default                      |
| -------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------- |
| `model1`             | `TileExtractorPseudoModel` | Tile extractor pseudo-model.                                                                                                                                                                                                                                                                                 | *required*                   |
| `model2`             | `Model`                    | PySDK object detection model.                                                                                                                                                                                                                                                                                | *required*                   |
| `edge_threshold`     | `float`                    | A threshold to determine if an object is considered an edge detection or not. The edge\_threshold determines the amount of space next to the tiles edges where if a detection overlaps this space it is considered an edge detection. This edge space is relative (a percent) of the width/height of a tile. | `0.02`                       |
| `fusion_threshold`   | `float`                    | A threshold to determine whether or not to fuse two edge detections. This corresponds to the 1D-IoU of two boxes, of either dimension. If the boxes overlap in both dimensions and one of the dimension's 1D-IoU is greater than the fusion\_threshold, the boxes are fused.                                 | `0.8`                        |
| `crop_extent`        | `float`                    | Extent of cropping in percent of bbox size.                                                                                                                                                                                                                                                                  | `0`                          |
| `crop_extent_option` | `CropExtentOptions`        | Method of applying extending crop to the input image for model2.                                                                                                                                                                                                                                             | `ASPECT_RATIO_NO_ADJUSTMENT` |
| `add_model1_results` | `bool`                     | True to add detections of model1 to the combined result.                                                                                                                                                                                                                                                     | `False`                      |
| `nms_options`        | `NmsOptions \| None`       | Non-maximum suppression (NMS) options.                                                                                                                                                                                                                                                                       | `None`                       |

#### transform\_result2(result2) <a href="#transform_result2" id="transform_result2"></a>

`transform_result2(result2)`

Transform result of the **second model**.

This implementation combines results of the **second model** over all bboxes detected by the first model, translating bbox coordinates to original image coordinates.

Parameters:

| Name      | Type               | Description                               | Default    |
| --------- | ------------------ | ----------------------------------------- | ---------- |
| `result2` | `DetectionResults` | Detection result of the **second model**. | *required* |

Returns:

| Type                       | Description                                                                                                                                                                                           |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DetectionResults or None` | Combined results of the **second model** over all bboxes detected by the first model, where bbox coordinates are translated to original image coordinates. Returns None if no new frame is available. |

## BoxFusionLocalGlobalTileModel <a href="#boxfusionlocalglobaltilemodel" id="boxfusionlocalglobaltilemodel"></a>

`BoxFusionLocalGlobalTileModel`

Bases: `BoxFusionTileModel`

Local-/global-tiling plus edge fusion.

Combines the size-based filtering of LocalGlobalTileModel with the edge-aware fusion of BoxFusionTileModel.

Parameters:

| Name                     | Type                       | Description                                                                                    | Default                      |
| ------------------------ | -------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------- |
| `model1`                 | `TileExtractorPseudoModel` | Must output a global tile.                                                                     | *required*                   |
| `model2`                 | `Model`                    | Detection model.                                                                               | *required*                   |
| `large_object_threshold` | `float`                    | Area ratio that classifies a detection as "large". Defaults to 0.01.                           | `0.01`                       |
| `edge_threshold`         | `float`                    | Width of the edge band as a fraction of tile dimensions. Defaults to 0.02.                     | `0.02`                       |
| `fusion_threshold`       | `float`                    | 1-D IoU used by the fusion logic. Defaults to 0.8.                                             | `0.8`                        |
| `crop_extent`            | `float`                    | Extra context (percent of box size) to include around every tile before passing it to model 2. | `0`                          |
| `crop_extent_option`     | `CropExtentOptions`        | How the extra context is applied.                                                              | `ASPECT_RATIO_NO_ADJUSTMENT` |
| `add_model1_results`     | `bool`                     | If True, detections produced by model 1 are appended to the final result.                      | `False`                      |
| `nms_options`            | `NmsOptions \| None`       | Non-maximum suppression settings performed on the merged result.                               | `None`                       |

### BoxFusionLocalGlobalTileModel Methods <a href="#boxfusionlocalglobaltilemodel-methods" id="boxfusionlocalglobaltilemodel-methods"></a>

#### \_\_init\_\_(model1, ...) <a href="#init" id="init"></a>

`__init__(model1, model2, large_object_threshold=0.01, edge_threshold=0.02, fusion_threshold=0.8, *, crop_extent=0, crop_extent_option=CropExtentOptions.ASPECT_RATIO_NO_ADJUSTMENT, add_model1_results=False, nms_options=None)`

Constructor.

Parameters:

| Name                     | Type                       | Description                                                                                                                                                                                                                                                                                                  | Default                      |
| ------------------------ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------- |
| `model1`                 | `TileExtractorPseudoModel` | Tile extractor pseudo-model.                                                                                                                                                                                                                                                                                 | *required*                   |
| `model2`                 | `Model`                    | PySDK object detection model.                                                                                                                                                                                                                                                                                | *required*                   |
| `large_object_threshold` | `float`                    | A threshold to determine if an object is considered large or not. This is relative to the area of the original image.                                                                                                                                                                                        | `0.01`                       |
| `edge_threshold`         | `float`                    | A threshold to determine if an object is considered an edge detection or not. The edge\_threshold determines the amount of space next to the tiles edges where if a detection overlaps this space it is considered an edge detection. This edge space is relative (a percent) of the width/height of a tile. | `0.02`                       |
| `fusion_threshold`       | `float`                    | A threshold to determine whether or not to fuse two edge detections. This corresponds to the 1D-IoU of two boxes, of either dimension. If the boxes overlap in both dimensions and one of the dimension's 1D-IoU is greater than the fusion\_threshold, the boxes are fused.                                 | `0.8`                        |
| `crop_extent`            | `float`                    | Extent of cropping in percent of bbox size.                                                                                                                                                                                                                                                                  | `0`                          |
| `crop_extent_option`     | `CropExtentOptions`        | Method of applying extending crop to the input image for model2.                                                                                                                                                                                                                                             | `ASPECT_RATIO_NO_ADJUSTMENT` |
| `add_model1_results`     | `bool`                     | True to add detections of model1 to the combined result.                                                                                                                                                                                                                                                     | `False`                      |
| `nms_options`            | `NmsOptions \| None`       | Non-maximum suppression (NMS) options.                                                                                                                                                                                                                                                                       | `None`                       |

#### transform\_result2(result2) <a href="#transform_result2" id="transform_result2"></a>

`transform_result2(result2)`

Transform result of the **second model**.

This implementation combines results of the **second model** over all bboxes detected by the first model, translating bbox coordinates to original image coordinates.

Parameters:

| Name      | Type               | Description                               | Default    |
| --------- | ------------------ | ----------------------------------------- | ---------- |
| `result2` | `DetectionResults` | Detection result of the **second model**. | *required* |

Returns:

| Type                       | Description                                                                                                                                                                                           |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DetectionResults or None` | Combined results of the **second model** over all bboxes detected by the first model, where bbox coordinates are translated to original image coordinates. Returns None if no new frame is available. |


---

# 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/tile_compound_models.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.
