# Math Support

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

## Math Support Module Overview <a href="#math-support-module-overview" id="math-support-module-overview"></a>

This module provides mathematical utilities for geometric operations and signal processing. It includes functions for bounding box manipulation, non-maximum suppression, image tiling, and a lightweight FIR low-pass filter implementation.

Key Features

* **Bounding Box Operations**: Area calculation, IoU computation, coordinate conversions
* **Non-maximum Suppression**: Multiple selection policies for detection filtering
* **Edge Box Fusion**: Handling overlapping detections with configurable thresholds
* **Image Tiling**: Utilities for fixed size or aspect ratio tiling
* **FIR Filter**: Lightweight low-pass filter implementation for signal smoothing

Typical Usage

1. Import required functions from the module
2. Use bounding box operations for detection processing
3. Apply NMS or box fusion for post-processing detections
4. Generate image tiles for processing large images
5. Use FIRFilterLP for smoothing numeric sequences

Integration Notes

* Built on NumPy for efficient array operations
* Compatible with various bounding box formats (xyxy, xywh)
* Provides consistent results across platforms
* Includes comprehensive error handling

Key Functions

* `area()`: Calculate bounding box areas
* `intersection()`: Compute intersection area of bounding boxes
* `nms()`: Apply non-maximum suppression
* `edge_box_fusion()`: Fuse overlapping edge detections
* `generate_tiles_fixed_size()`: Generate overlapping image tiles

Configuration Options

* NMS selection policies
* Box fusion thresholds
* Tile overlap parameters
* Filter coefficients

## Functions <a href="#functions" id="functions"></a>

#### area(box) <a href="#area" id="area"></a>

`area(box)`

Compute bounding box areas.

Parameters:

| Name  | Type      | Description                                                                  | Default    |
| ----- | --------- | ---------------------------------------------------------------------------- | ---------- |
| `box` | `ndarray` | Single box `(x1, y1, x2, y2)` or an array of such boxes with shape `(N, 4)`. | *required* |

Returns:

| Type      | Description             |
| --------- | ----------------------- |
| `ndarray` | Area of each input box. |

#### intersection(boxA, ...) <a href="#intersection" id="intersection"></a>

`intersection(boxA, boxB)`

Compute intersection area of bounding boxes.

Parameters:

| Name   | Type      | Description                             | Default    |
| ------ | --------- | --------------------------------------- | ---------- |
| `boxA` | `ndarray` | First set of boxes `(x1, y1, x2, y2)`.  | *required* |
| `boxB` | `ndarray` | Second set of boxes `(x1, y1, x2, y2)`. | *required* |

Returns:

| Type                    | Description                               |
| ----------------------- | ----------------------------------------- |
| `Union[float, ndarray]` | Intersection area for each pair of boxes. |

#### compute\_kmeans(embeddings, ...) <a href="#compute_kmeans" id="compute_kmeans"></a>

`compute_kmeans(embeddings, k=0)`

Compute k-means clustering on the given embeddings. Args: embeddings (List\[np.ndarray]): List of embedding vectors. k (int): Number of clusters. If 0, it will be deduced based on the number of embeddings. Returns: Tuple\[List\[np.ndarray], List\[int]]: Tuple containing:

* List of embeddings closest to cluster centroids
* List of their indices in the input embeddings list

#### xyxy2xywh(x) <a href="#xyxy2xywh" id="xyxy2xywh"></a>

`xyxy2xywh(x)`

Convert `(x1, y1, x2, y2)` boxes to `(x, y, w, h)` format.

#### tlbr2allcorners(x) <a href="#tlbr2allcorners" id="tlbr2allcorners"></a>

`tlbr2allcorners(x)`

Convert `(x1, y1, x2, y2)` boxes to all four corner points.

#### xywh2xyxy(x) <a href="#xywh2xyxy" id="xywh2xyxy"></a>

`xywh2xyxy(x)`

Convert `(x, y, w, h)` boxes to `(x1, y1, x2, y2)` format.

#### box\_iou\_batch(boxes\_true, ...) <a href="#box_iou_batch" id="box_iou_batch"></a>

`box_iou_batch(boxes_true, boxes_detection)`

Compute pairwise IoU between two sets of boxes.

Parameters:

| Name              | Type      | Description                  | Default    |
| ----------------- | --------- | ---------------------------- | ---------- |
| `boxes_true`      | `ndarray` | Ground-truth boxes `(N, 4)`. | *required* |
| `boxes_detection` | `ndarray` | Detection boxes `(M, 4)`.    | *required* |

Returns:

| Type      | Description                   |
| --------- | ----------------------------- |
| `ndarray` | IoU matrix of shape `(N, M)`. |

#### nms(detections, ...) <a href="#nms" id="nms"></a>

`nms(detections, iou_threshold=0.3, use_iou=True, box_select=NmsBoxSelectionPolicy.MOST_PROBABLE, max_wh=10000, class_agnostic=False)`

Apply non-maximum suppression to detection results.

Parameters:

| Name             | Type                                                                                                                             | Description                                                                       | Default         |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------- |
| `detections`     | [InferenceResults](https://docs.degirum.com/pysdk/user-guide-pysdk/api-ref/postprocessor#degirum.postprocessor.inferenceresults) | Iterable of detection dictionaries containing `bbox`, `score` and `class` fields. | *required*      |
| `iou_threshold`  | `float`                                                                                                                          | IoU/IoS threshold. Defaults to `0.3`.                                             | `0.3`           |
| `use_iou`        | `bool`                                                                                                                           | If `True` use IoU, otherwise IoS.                                                 | `True`          |
| `box_select`     | `NmsBoxSelectionPolicy`                                                                                                          | Box selection strategy.                                                           | `MOST_PROBABLE` |
| `max_wh`         | `int`                                                                                                                            | Maximum image dimension for class separation.                                     | `10000`         |
| `class_agnostic` | `bool`                                                                                                                           | If `True` perform class-agnostic NMS.                                             | `False`         |

Returns:

| Type   | Description                                                  |
| ------ | ------------------------------------------------------------ |
| `None` | `detections` is modified in place with the filtered results. |

#### edge\_box\_fusion(detections, ...) <a href="#edge_box_fusion" id="edge_box_fusion"></a>

`edge_box_fusion(detections, iou_threshold=0.55, skip_threshold=0.0, destructive=True)`

Perform box fusion on a set of edge detections. Edge detections are detections within a certain threshold of an edge.

Parameters:

| Name             | Type      | Description                                                                | Default    |
| ---------------- | --------- | -------------------------------------------------------------------------- | ---------- |
| `detections`     | `results` | A list of dictionaries that contain detection results as defined in PySDK. | *required* |
| `iou_threshold`  | `float`   | 1D-IoU threshold used for selecting boxes for fusion.                      | `0.55`     |
| `skip_threshold` | `float`   | Score threshold for which boxes to fuse.                                   | `0.0`      |
| `destructive`    | `bool`    | Keep skipped boxes (underneath the `score_threshold`) in the results.      | `True`     |

Returns:

| Type      | Description                                                                                                                                                         |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `results` | A list of dictionaries that contain detection results as defined in PySDK. Boxes that are not fused are kept if destructive is False, otherwise they are discarded. |

#### get\_anchor\_coordinates(xyxy, ...) <a href="#get_anchor_coordinates" id="get_anchor_coordinates"></a>

`get_anchor_coordinates(xyxy, anchor)`

Get coordinates of an anchor point inside bounding boxes.

Parameters:

| Name     | Type          | Description              | Default    |
| -------- | ------------- | ------------------------ | ---------- |
| `xyxy`   | `ndarray`     | Array of boxes `(N, 4)`. | *required* |
| `anchor` | `AnchorPoint` | Desired anchor location. | *required* |

Returns:

| Type      | Description                               |
| --------- | ----------------------------------------- |
| `ndarray` | Array `(N, 2)` with `[x, y]` coordinates. |

Raises:

| Type         | Description                 |
| ------------ | --------------------------- |
| `ValueError` | If `anchor` is unsupported. |

#### get\_image\_anchor\_point(w, ...) <a href="#get_image_anchor_point" id="get_image_anchor_point"></a>

`get_image_anchor_point(w, h, anchor)`

Return coordinates of an anchor point inside an image.

#### intersect(a, ...) <a href="#intersect" id="intersect"></a>

`intersect(a, b, c, d)`

Return `True` if two line segments intersect.

#### generate\_tiles\_fixed\_size(tile\_size, ...) <a href="#generate_tiles_fixed_size" id="generate_tiles_fixed_size"></a>

`generate_tiles_fixed_size(tile_size, image_size, min_overlap_percent)`

Generate overlapping tiles with fixed size.

Parameters:

| Name                  | Type                       | Description                 | Default    |
| --------------------- | -------------------------- | --------------------------- | ---------- |
| `tile_size`           | `Union[ndarray, Sequence]` | Tile size `(w, h)`.         | *required* |
| `image_size`          | `Union[ndarray, Sequence]` | Image size `(w, h)`.        | *required* |
| `min_overlap_percent` | `Union[ndarray, Sequence]` | Minimum overlap in percent. | *required* |

Returns:

| Type      | Description                                                                                                                                                                                                             |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ndarray` | Array of shape `(N, M, 4)` containing tile coordinates, where N is the number of rows in the tile grid, M is the number of columns in the tile grid, and 4 represents the coordinates `(x1, y1, x2, y2)` for each tile. |

#### generate\_tiles\_fixed\_ratio(tile\_aspect\_ratio, ...) <a href="#generate_tiles_fixed_ratio" id="generate_tiles_fixed_ratio"></a>

`generate_tiles_fixed_ratio(tile_aspect_ratio, grid_size, image_size, min_overlap_percent)`

Generate overlapping tiles with fixed aspect ratio.

Parameters:

| Name                  | Type                              | Description              | Default    |
| --------------------- | --------------------------------- | ------------------------ | ---------- |
| `tile_aspect_ratio`   | `Union[float, ndarray, Sequence]` | Desired aspect ratio.    | *required* |
| `grid_size`           | `Union[ndarray, Sequence]`        | Grid size `(x, y)`.      | *required* |
| `image_size`          | `Union[ndarray, Sequence]`        | Image size `(w, h)`.     | *required* |
| `min_overlap_percent` | `Union[ndarray, Sequence, float]` | Minimum overlap percent. | *required* |

Returns:

| Type      | Description                                                                                                                                                                                                             |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ndarray` | Array of shape `(N, M, 4)` containing tile coordinates, where N is the number of rows in the tile grid, M is the number of columns in the tile grid, and 4 represents the coordinates `(x1, y1, x2, y2)` for each tile. |

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

## NmsBoxSelectionPolicy <a href="#nmsboxselectionpolicy" id="nmsboxselectionpolicy"></a>

`NmsBoxSelectionPolicy`

Bases: `Enum`

Bounding box selection policy for non-maximum suppression.

This enum defines different strategies for selecting which bounding box to keep when multiple overlapping boxes are detected. Each policy has different use cases and trade-offs.

Attributes:

| Name            | Type  | Description                                                                                                                                      |
| --------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `MOST_PROBABLE` | `int` | Traditional NMS approach that keeps the box with highest confidence score. Best for high-confidence detections where false positives are costly. |
| `LARGEST_AREA`  | `int` | Keeps the box with the largest area. Useful when larger detections are more likely to be correct or when object size is important.               |
| `AVERAGE`       | `int` | Averages the coordinates of all overlapping boxes. Good for reducing jitter in tracking applications.                                            |
| `MERGE`         | `int` | Merges all overlapping boxes into a single box. Useful when multiple detections of the same object are expected.                                 |

## AnchorPoint <a href="#anchorpoint" id="anchorpoint"></a>

`AnchorPoint`

Bases: `Enum`

Position of a point of interest within the bounding box.

## FIRFilterLP <a href="#firfilterlp" id="firfilterlp"></a>

`FIRFilterLP`

Low-pass Finite Impulse Response (FIR) filter implementation.

This class implements a low-pass FIR filter for smoothing signals. It uses convolution with designed filter coefficients (FIR kernel) with configurable cutoff frequency and number of taps.

Attributes:

| Name                | Type    | Description                                  |
| ------------------- | ------- | -------------------------------------------- |
| `normalized_cutoff` | `float` | Normalized cutoff frequency (0 to 1).        |
| `taps_cnt`          | `int`   | Number of filter taps (order of the filter). |
| `dimension`         | `int`   | Number of dimensions in the input signal.    |

### FIRFilterLP Methods <a href="#firfilterlp-methods" id="firfilterlp-methods"></a>

#### \_\_call\_\_(sample) <a href="#call" id="call"></a>

`__call__(sample)`

Update the filter with a new sample and return the filtered value.

This is a convenience method that calls update().

Parameters:

| Name     | Type                    | Description                                                                              | Default    |
| -------- | ----------------------- | ---------------------------------------------------------------------------------------- | ---------- |
| `sample` | `Union[float, ndarray]` | New input sample. Can be a scalar or an array of length equal to the filter's dimension. | *required* |

Returns:

| Type      | Description                                                    |
| --------- | -------------------------------------------------------------- |
| `ndarray` | Filtered output value with the same shape as the input sample. |

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

`__init__(normalized_cutoff, taps_cnt, dimension=1)`

Initialize the FIR filter with specified parameters.

Parameters:

| Name                | Type    | Description                                                                                                                             | Default    |
| ------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `normalized_cutoff` | `float` | Normalized cutoff frequency between 0 and 1. A value of 1 corresponds to the Nyquist frequency.                                         | *required* |
| `taps_cnt`          | `int`   | Number of filter taps (order of the filter). Higher values provide better frequency response but increase computational cost and delay. | *required* |
| `dimension`         | `int`   | Number of dimensions in the input signal. Defaults to 1 for scalar signals.                                                             | `1`        |

Raises:

| Type         | Description                                   |
| ------------ | --------------------------------------------- |
| `ValueError` | If normalized\_cutoff is not between 0 and 1. |
| `ValueError` | If taps\_cnt is less than 1.                  |
| `ValueError` | If dimension is less than 1.                  |

#### get <a href="#get" id="get"></a>

`get()`

Get the current filtered value without updating the filter.

Returns:

| Type | Description                                                |
| ---- | ---------------------------------------------------------- |
|      | Current filtered value based on the samples in the buffer. |

#### update(sample) <a href="#update" id="update"></a>

`update(sample)`

Update the filter with a new sample and return the filtered value.

This method adds a new sample to the filter's buffer and computes the filtered output by convolving the input samples with the FIR filter coefficients.

Parameters:

| Name     | Type                    | Description                                                                              | Default    |
| -------- | ----------------------- | ---------------------------------------------------------------------------------------- | ---------- |
| `sample` | `Union[float, ndarray]` | New input sample. Can be a scalar or an array of length equal to the filter's dimension. | *required* |

Returns:

| Type      | Description                                                    |
| --------- | -------------------------------------------------------------- |
| `ndarray` | Filtered output value with the same shape as the input sample. |

Raises:

| Type         | Description                                                       |
| ------------ | ----------------------------------------------------------------- |
| `ValueError` | If the input sample's shape doesn't match the filter's dimension. |


---

# 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/support/math_support.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.
