> For the complete documentation index, see [llms.txt](https://docs.degirum.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.degirum.com/hailo/intermediate-guides/model-properties/output-postprocessing.md).

# Output postprocessing

Understand how to fine-tune postprocessing parameters to control model output—filter predictions, apply suppression, and reduce clutter for more usable results.

*Estimated read time: 4 minutes*

Postprocessing turns raw model predictions into the final list you work with. The goal is simple: keep the predictions you care about, drop the rest, and do it in a way that’s stable and fast. This page focuses on runtime-adjustable knobs and why you’d change them.

## Model family notes

* **Detection/instance tasks** (e.g., object detection, instance segmentation): main knobs are `output_confidence_threshold`, `output_nms_threshold`, result caps, and `output_class_set`.
* **Classification**: main knob is `output_top_k` (how many labels to return). NMS doesn’t apply.
* **Pose/keypoints**: `output_pose_threshold` filters low‑confidence landmarks; other detection knobs may still apply if bounding boxes are present.

Compare postprocessing configurations using the tabs below.

{% tabs %}
{% tab title="Default" %}

<figure><img src="https://1657109811-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaQsuJ8iXkszyOgIpNy8w%2Fuploads%2Fgit-blob-86bdaeeb56f5d1d8975b227966d4da3f8da1f3de%2Fhailo-cookbook--output-postprocessing--default-settings.png?alt=media" alt="Detection overlay with default postprocessing thresholds showing several people and animals."><figcaption><p>Baseline settings: confidence 0.25 and NMS 0.45.</p></figcaption></figure>
{% endtab %}

{% tab title="High confidence" %}

<figure><img src="https://1657109811-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaQsuJ8iXkszyOgIpNy8w%2Fuploads%2Fgit-blob-8c0fa11c48ba1fe0fd2cd85cd8a7bafc88995356%2Fhailo-cookbook--output-postprocessing--high-confidence.png?alt=media" alt="Detection overlay after raising the confidence threshold to 0.60, leaving only the highest probability boxes."><figcaption><p>Higher confidence threshold (0.60) filters low-score detections.</p></figcaption></figure>
{% endtab %}

{% tab title="Looser NMS" %}

<figure><img src="https://1657109811-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaQsuJ8iXkszyOgIpNy8w%2Fuploads%2Fgit-blob-faee299f726a1a12d33dfc18a3f2ea62da7184d6%2Fhailo-cookbook--output-postprocessing--looser-nms.png?alt=media" alt="Detection overlay with looser non-maximum suppression at 0.65 showing overlapping boxes."><figcaption><p>Looser NMS (0.65) keeps more overlapping boxes.</p></figcaption></figure>
{% endtab %}

{% tab title="Tight NMS" %}

<figure><img src="https://1657109811-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaQsuJ8iXkszyOgIpNy8w%2Fuploads%2Fgit-blob-b7bdb6d047e5367660362c738fbdd0df5d75f1fa%2Fhailo-cookbook--output-postprocessing--tight-nms.png?alt=media" alt="Detection overlay with tight non-maximum suppression at 0.30 removing crowded boxes."><figcaption><p>Tighter NMS (0.30) suppresses overlapping detections.</p></figcaption></figure>
{% endtab %}

{% tab title="Person-only" %}

<figure><img src="https://1657109811-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaQsuJ8iXkszyOgIpNy8w%2Fuploads%2Fgit-blob-017adedd8d4fd1710d6706a73b2364aa0b264e09%2Fhailo-cookbook--output-postprocessing--person-only-filter.png?alt=media" alt="Detection overlay filtered to only show person detections."><figcaption><p>Class filter keeps only the `person` label.</p></figcaption></figure>
{% endtab %}

{% tab title="Detection cap" %}

<figure><img src="https://1657109811-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaQsuJ8iXkszyOgIpNy8w%2Fuploads%2Fgit-blob-c03734d4a6d8758f5edbb64ec6a70ade8e316082%2Fhailo-cookbook--output-postprocessing--five-detection-cap.png?alt=media" alt="Detection overlay limited to five detections due to output cap."><figcaption><p>Limiting detections to five returns only the most confident boxes.</p></figcaption></figure>
{% endtab %}
{% endtabs %}

## Basic Parameters

{% stepper %}
{% step %}
**Confidence threshold**: `output_confidence_threshold`

Minimum score to keep a prediction.

* Higher values → fewer boxes, more precision
* Lower values → more boxes, better recall (but more false positives)
* **Suggested values:** 0.25 for exploration, 0.4–0.6 for production (tune per model)
  {% endstep %}

{% step %}
**NMS overlap**: `output_nms_threshold`

IoU threshold for non‑maximum suppression—how much overlap is allowed before suppressing a box.

* Lower values (e.g., 0.4) → aggressive suppression (cleaner but may remove nearby objects)
* Higher values (e.g., 0.6) → keeps more overlapping boxes (better for crowded scenes)
  {% endstep %}

{% step %}
**Caps**: size and balance of the output list

* **Detection/instance tasks**:
  * `output_max_detections`: upper bound for total detections (global cap)
  * `output_max_detections_per_class`: per‑class limit (prevents one class from dominating)
  * `output_max_classes_per_detection`: max labels per box (for multi‑label outputs)
* **Classification**:
  * `output_top_k`: number of top labels to return (e.g., 1 for single‑label, 5–10 for exploratory UIs)
    {% endstep %}

{% step %}
**Focus by class**: `output_class_set`

Allowlist of classes you want to keep (use label strings).

* Example: `["person", "car", "truck"]`

{% hint style="info" %}
Inspect `label_dictionary` to avoid typos and confirm canonical names.
{% endhint %}
{% endstep %}
{% endstepper %}

## Advanced Parameters

* `output_use_regular_nms` **(bool)**: toggles NMS algorithm if supported. Use only if the default behaves poorly.
* `output_pose_threshold` **(float)**: filters low-confidence keypoints in pose models.
* `output_postprocess_type` **(info)**: reports model’s postprocessing type. Informational only (see advanced guide).
* `inference_results_type` **(info)**: indicates result format variant. Leave as default unless your integration requires changes.
* `custom_postprocessor` **(advanced)**: attach your own logic for decoding or filtering results (see advanced guide).

## Pitfalls to avoid

* **Too low confidence + low NMS** → too many overlapping boxes → UI lag, noisy metrics
* **Too high confidence** → misses small/faint objects → high precision, low recall
* **Small `output_max_detections`** → drops valid detections (especially long‑tail classes)
* **Wrong class names** → `output_class_set` must match `label_dictionary` exactly

## Minimal Inspection

Run this quick check to confirm the postprocessing settings applied by the model.

### Example

{% code overflow="wrap" %}

```python
from degirum_tools import ModelSpec, remote_assets

spec = ModelSpec(
    model_name="yolov8n_coco--640x640_quant_hailort_multidevice_1",
    zoo_url="degirum/hailo",
    inference_host_address="@local",
    model_properties={
        "device_type": ["HAILORT/HAILO8L", "HAILORT/HAILO8"],
    },
)
model = spec.load_model()
result = model(remote_assets.urban_picnic_elephants)

print("conf:", model.output_confidence_threshold)
print("nms:", model.output_nms_threshold)
print("max det:", model.output_max_detections)
print("per-class:", model.output_max_detections_per_class)
print("top-k:", model.output_top_k)
print("class set:", model.output_class_set)
print("pose thr:", getattr(model, "output_pose_threshold", None))
print("nms flavor:", getattr(model, "output_use_regular_nms", None))
print("results type:", model.inference_results_type)
print("custom postprocess:", getattr(result, "custom_postprocess_data", None))
```

{% endcode %}

Example output:

{% code overflow="wrap" %}

```bash
conf: 0.25
nms: 0.45
max det: 200
per-class: 200
top-k: None
class set: None
pose thr: None
nms flavor: None
results type: InferenceResults.DETECTION
custom postprocess: None
```

{% endcode %}
