# Celantur Documentation

Welcome to Celantur Documentation, have fun working with our solutions!

## Overview

Celantur software automatically removes personal data from images and videos.

## Products

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="image">Cover image</th></tr></thead><tbody><tr><td>Celantur Container</td><td></td><td><a href="/pages/A6MsuSQ0dlpM8lkLwUmZ">/pages/A6MsuSQ0dlpM8lkLwUmZ</a></td><td data-object-fit="contain"><a href="/files/UXBr8mnWSKyUqOwC0SHj">/files/UXBr8mnWSKyUqOwC0SHj</a></td></tr><tr><td>Celantur SDK</td><td></td><td><a href="/pages/0xaiQUYXBimkjmZdf3U8">/pages/0xaiQUYXBimkjmZdf3U8</a></td><td data-object-fit="contain"><a href="/files/QDCqY3AafgaJgUwHy5Hn">/files/QDCqY3AafgaJgUwHy5Hn</a></td></tr><tr><td>Celantur Cloud API</td><td></td><td><a href="/pages/tndHg3PHSlSHiI7TtDou">/pages/tndHg3PHSlSHiI7TtDou</a></td><td data-object-fit="contain"><a href="/files/xMSavJpCJ94DIifDGMLT">/files/xMSavJpCJ94DIifDGMLT</a></td></tr></tbody></table>

## We're happy to help you 🤝

Our team of experts is ready for any of your questions or requests.

[Contact us now.](https://www.celantur.com/contact/)


# Getting Started

Start anonymizing images and videos with Celantur Container.

## Overview

**Celantur Container** is a [Docker](https://www.docker.com/)-based container image to automatically anonymize **faces, persons, license plates and vehicles** on images and videos.

It's built to deliver high-quality anonymization and high throughput (see [benchmarks](/container/benchmarks)).

{% embed url="<https://www.youtube.com/watch?v=eFwkK1XSoB0>" %}
How to run Celantur Container in Batch Mode.
{% endembed %}

## Requirements and Installation

* [System Requirements](/container/requirements-and-installation/requirements) and [Licensing](/container/requirements-and-installation/requirements#licensing)
* [Installation on Linux](/container/requirements-and-installation/installation-on-linux)
* [Installation on Windows](/container/requirements-and-installation/installation-on-windows)

## Modes and Features

* Celantur Container offers different data **input/output modes**:
  * [Batch and Stream Mode](/container/usage/batch-and-stream-mode) (read/write from file system)
  * [REST API Mode](/container/usage/rest-api-v1-mode) ([sync](/container/usage/rest-api-v1-mode#sychronous-processing) and [async](/container/usage/rest-api-v1-mode#asynchronous-processing))
  * [TCP Mode](/container/usage/tcp-mode)
* [Extract Segmentation Masks and Metadata](/container/usage/segmentation-masks-and-metadata)
* [Customize Blurring](/container/usage/customize-blurring) appearance
* [CPU mode](/container/usage/using-cpu-only)

## Anonymize Images and Videos

{% hint style="success" %}

* Install Celantur Container according to the [installation guide](/container/requirements-and-installation/installation-on-linux).
* `celantur.sh` script is used to start the Docker Container.
  {% endhint %}

### Quickstart

* Run `mkdir input`
* Copy some images into the `input` directory.
* Run `bash celantur.sh -a person -a license-plate`
* Check the anonymized in the `output` directory.

For different image types and resolutions, e.g. panoramas, drone images, check out [Recommended Parameters](/container/usage/recommended-parameters).

{% hint style="success" %}
When starting with a demo of Celantur Container, our team will send you a customized code sample.
{% endhint %}

## What's New

Celantur Container receives continuous improvements and new features. Read more about past and recent releases in the [Release Notes](/container/release-notes).


# Requirements and Installation

Check your system's requirements and install Celantur Container

{% content-ref url="/pages/EI1j9oaVaBMiMiibxYp0" %}
[Requirements](/container/requirements-and-installation/requirements)
{% endcontent-ref %}

{% content-ref url="/pages/RvDzLqN0o5C9bgkjinN8" %}
[Installation on Linux](/container/requirements-and-installation/installation-on-linux)
{% endcontent-ref %}

{% content-ref url="/pages/Fk2CoII3O7znQMDnBCME" %}
[Installation on Windows](/container/requirements-and-installation/installation-on-windows)
{% endcontent-ref %}


# Requirements

Software and hardware requirements for Celantur Container

## Hardware Requirements

* CPU: recommended > 8 cores
* Memory: recommended 32 GiB RAM
* NVIDIA GPU:
  * Recommended > 16 GiB VRAM (minimum 4 GiB)
  * [Compute capability](https://developer.nvidia.com/cuda-gpus) >= 7.5 (contact us for support for older GPUs)

{% hint style="success" %}
See [#reference-systems](#reference-systems "mention")for a list of hardware recommendations.
{% endhint %}

## Software Requirements

* [ ] Linux (Recommended: [Ubuntu](https://ubuntu.com/download/desktop) 22.04 LTS or 24.04 LTS)
* [ ] Windows 11 / Server 2022 with [Windows Subsystem for Linux (WSL2)](https://learn.microsoft.com/en-us/windows/wsl/install)
* [ ] [Docker](https://docs.docker.com/engine/install/) latest version.
* [ ] [NVIDIA driver](https://www.nvidia.com/Download/index.aspx) latest version.
* [ ] [NVIDIA Docker runtime](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#getting-started)

{% hint style="info" %}
Support for Windows 10 is experimental. [Read more.](/container/requirements-and-installation/installation-on-windows)
{% endhint %}

## Licensing

You will be provided a **license file** which is required to run Celantur container. To personalize your license, you need to provide us your GPU UUID. This is the unique identifier of your GPU.

### How do I find my GPU UUID

On **Linux** with NVIDIA driver installed, run in terminal:

```sh
nvidia-smi -L
```

On **Windows** (via Windows Subsystem for Linux), run in PowerShell:

```sh
nvidia-smi.exe -L
```

## Reference Systems

This is a list of reference systems used by the Celantur. All systems using Linux as the operating system.

Please ask your contact person for performance metrics.

<table data-card-size="large" data-column-title-hidden data-view="cards"><thead><tr><th></th><th data-type="rating" data-max="5"></th><th></th><th></th></tr></thead><tbody><tr><td><strong>Gamma</strong></td><td>5</td><td><mark style="color:green;"><strong>Recommend by Celantur</strong></mark></td><td><ul><li>Intel Core i7-13700</li><li>G.SKILL Flare X5 64 GB RAM (2x32)</li><li>MSI MAG B760 TOMAHAWK WIFI DDR5 Mainboard, Intel</li><li>Asus GeForce RTX 4090 24 GB</li><li>2 TB Samsung SSD 980 PRO, PCIe 4.0 NVMe M.2</li></ul></td></tr><tr><td><strong>Beta</strong></td><td>4</td><td><mark style="color:green;"><strong>Recommend by Celantur</strong></mark></td><td><ul><li>Intel Core i7-11700K</li><li>Corsair Vengeance LPX 64GB (2x32GB)</li><li>ASUS Prime Z590-P Gaming Mainboard, Intel LGA 1200 Socket</li><li>ASUS ROG Strix GeForce RTX 3090 24 GB OC Version</li><li>2 x Samsung SSD 870 QVO 1TB</li></ul></td></tr><tr><td><strong>Alpha</strong></td><td>3</td><td></td><td><ul><li>WORKSTATION HP Z440 SC</li><li>XEON E5-1650 v4</li><li>64GB RAM</li><li>NVIDIA QUADRO P5000 (16 GB Video Memory)</li><li>1 TB HDD</li><li>256 GB SDD</li></ul></td></tr></tbody></table>

## FAQ

#### Is Microsoft Windows supported?

Yes, Celantur Container runs on Windows 11. However, CUDA / GPU support on Windows is currently in an experimental stage.

Alternative, you can install Ubuntu on a separate partition:

1. Create a [bootable USB](https://ubuntu.com/tutorials/create-a-usb-stick-on-windows#1-overview) or [bootable DVD](https://ubuntu.com/tutorials/burn-a-dvd-on-windows#1-overview).
2. Follow the [official stept-by-step installation tutorial](https://ubuntu.com/tutorials/install-ubuntu-desktop#1-overview).

You can [install Windows and Ubuntu](https://opensource.com/article/18/5/dual-boot-linux) on the same machine.


# Installation on Linux

Installation of Celantur Container on Linux

{% hint style="info" %}
**Setup Support 🤝**

We are happy to help you with setting up Celantur Container. Please contact your sales representative.
{% endhint %}

## Prerequisites

### Check installed prerequisites

You can check whether dependencies are already installed:

* Docker: `docker version`
* NVIDIA driver: `nvidia-smi`
* NVIDIA Docker runtime: `nvidia-container-runtime --version`

If any of the above commands returns an error, proceed with the next section or parts of it.

### Set up host machine

#### Install Docker

[Install Docker](https://docs.docker.com/engine/install/ubuntu/#install-using-the-convenience-script)

```bash
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
```

Add your user to the `docker` group. It takes effect with the next login.

```bash
sudo groupadd docker
sudo usermod -aG docker $USER
```

If you don't add your user to the `docker` group, you'll receive the following error when running the `docker` command:

{% code overflow="wrap" %}

```
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http:///var%2Frun%2Fdocker.sock/v1.40/containers/json: dial unix /var/run/docker.sock: connect: permission denied
```

{% endcode %}

#### Install NVIDIA driver

Install NVIDIA driver with `sudo apt install nvidia-driver-580` (or a different version compatible with your GPU).

#### Install Nvidia Container Runtime

Install [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html): Required to access the GPUs within the Docker containers.

```bash
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit

sudo systemctl restart docker
```

#### Test the setup

```bash
docker run --gpus all nvidia/cuda:12.8.1-base-ubuntu22.04 nvidia-smi
```

## Deploy Celantur Container

You'll receive a time-limited **password** (provided by Celantur via email) to download the image from the Celantur Container Registry.

{% hint style="info" %}
If your password expired, please let us know. We're happy to send you a new one.
{% endhint %}

### Download the Container

1. Download [celantur.sh](https://celantur-web.s3.eu-central-1.amazonaws.com/scripts/celantur.sh) script.
2. Assign the **password** to a variable: `export PASSWD=.......`
3. Optional: Set `export VERSION=...` for a specific version. Default is `latest`. You can find version numbers in the [Release Notes](/container/release-notes).
4. Run `bash celantur.sh --update` to download the latest release.

### Preparation

You need a **license file** (provided by Celantur) to run Celantur Container.

The following folders and file are necessary:

```
Celantur (root folder)
├── input/
├── licensing/
├── log/
├── output/
└── celantur.sh
```

* **`input`**: Where the original files are stored (including subfolders)
  * See [#supported-image-formats](#supported-image-formats "mention")
  * See [#supported-video-codecs](#supported-video-codecs "mention")
* **`output`**: Folder for the anonymized images/videos. If a file exists with the same as in input folder, then processing of the file is skipped.
* **`log`**: Folder containing the logs.
* **`licensing`**: Folder containing the license key. Copy the license file `license` into this folder as `licensing/license`.

### Run the Container

1. Copy some images into the `input` directory.
2. Run `bash celantur.sh -a person -a vehicle`
3. Check the anonymized in the `output` directory.

#### Ensure that /tmp folder within the Container is read-writeable

If you run the Container with `--read-only` flag or use readonly filesystem in Kubernetes, you need to ensure that the `/tmp` folder within the Container can be both read and written with ca. 2 GiB space.

### Anonymize your first images

Follow instructions at [Getting Started](/container/getting-started#anonymize-images-and-videos).

Start to integrate Celantur Container into your workflow with the various data ingestion modes:

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td></td><td><strong>Batch and Stream mode</strong></td><td></td><td><a href="/pages/iiet2gwTQcsmzQHN5m7V">/pages/iiet2gwTQcsmzQHN5m7V</a></td></tr><tr><td></td><td><strong>REST API mode</strong></td><td></td><td><a href="/pages/1kDwd1vwz9Vsw3JrdLqP">/pages/1kDwd1vwz9Vsw3JrdLqP</a></td></tr><tr><td></td><td><strong>TCP mode</strong></td><td></td><td><a href="/pages/LwShShWOdjwgQLVtReAS">/pages/LwShShWOdjwgQLVtReAS</a></td></tr></tbody></table>


# Installation on Windows

{% hint style="warning" %}
Support for Windows 10 is experimental, due to limited CUDA/GPU support.
{% endhint %}

{% hint style="info" %}
**Setup Support 🤝**

We are happy to help you with setting up Celantur Container. Please contact your sales representative.
{% endhint %}

It is possible to run Celantur Container on Windows with WSL (Windows Subsystem for Linux). NVIDIA provides an [official documentation](https://docs.nvidia.com/cuda/wsl-user-guide/index.html#getting-started) to set up the software dependencies.

Please make sure your system fulfills the requirements:

{% content-ref url="/pages/EI1j9oaVaBMiMiibxYp0" %}
[Requirements](/container/requirements-and-installation/requirements)
{% endcontent-ref %}

**Alternatively**, you can [install Windows and Ubuntu](https://opensource.com/article/18/5/dual-boot-linux) on a separate partition on the same machine:

1. Create a [bootable USB](https://ubuntu.com/tutorials/create-a-usb-stick-on-windows#1-overview) or [bootable DVD](https://ubuntu.com/tutorials/burn-a-dvd-on-windows#1-overview)
2. Follow the [official step-by-step installation tutorial](https://ubuntu.com/tutorials/install-ubuntu-desktop#1-overview)

## Steps

### 1. Install Nvidia driver

Install the newest version of [Nvidia Driver](https://www.nvidia.com/Download/index.aspx) for your GPU.

### 2. Install Windows Subsystem for Linux

Install [Windows Subsystem for Linux (WSL 2)](https://docs.microsoft.com/en-us/windows/wsl/install) with `wsl --install -d Ubuntu`.

If you receive following error `Wsl/InstallDistro/Service/RegisterDistro/CreateVm/HCS/HCS_E_SERVICE_NOT_AVAILABLE`, you need to enable virtualisation in command line with:

```sh
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
dism.exe /online /enable-feature /featurename:Microsoft-Hyper-V-All /all /norestart
```

On Windows 10, you might need to [update the Linux kernel](https://learn.microsoft.com/en-us/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package).

Check that you can access the NVIDIA driver *from within WSL 2* by opening WSL and entering `nvidia-smi`. You should see detailled information about the GPU.

### 3. Install Docker Desktop

Install [Docker Desktop on Windows](https://docs.docker.com/desktop/setup/install/windows-install/).

**Activate** Docker WSL 2 integration, by checking "Use WSL 2 based engine" in the settings.

<figure><img src="/files/MiA2bwGWXvOYoiY4doFT" alt=""><figcaption><p><strong>Activate</strong> Docker WSL 2 integration, by checking "Use WSL 2 based engine" in the settings.</p></figcaption></figure>

### 4. Install Nvidia Container Runtime

Install [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) within WSL. (Start WSL with `wsl`)

```bash
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
```

### 5. Restart Docker

Click "Restart Docker..." in the context menu of the Docker icon in your taskbar's notification area.

### 6. Test CUDA container

Test that the setup is correct by running:

```bash
docker run --rm --gpus all nvidia/cuda:12.8.1-base-ubuntu22.04 nvidia-smi
```

## Deploy Celantur Container

Please refer to [Installation on Linux](/container/requirements-and-installation/installation-on-linux#deploy-celantur-container) in our Linux section. The Windows deployment process is the same for Linux.

### Troubleshooting: CUDA is not available.

If you receive "ERROR: CUDA ist not available!", upgrading the Docker engine might resolve it.


# Updates

How to update Celantur Container to the latest or a specific version.

{% hint style="info" %}
As a Celantur Container customer, you'll receive email notifications when a new release is available.
{% endhint %}

## Updating Celantur Container

By using the [celantur.sh](https://celantur-web.s3.eu-central-1.amazonaws.com/scripts/celantur.sh) script and a time-limited password (provided by Celantur via email), download the latest image from the Celantur Container Registry.

**Steps to update Celantur Container:**

1. Receive a password from Celantur. It expires after 12 hours.
2. Assign the password to a variable: `export PASSWD=eyJ...4fQ==`
3. Use the [celantur.sh](https://celantur-web.s3.eu-central-1.amazonaws.com/scripts/celantur.sh) script with `bash celantur.sh --update` to download the latest release.
4. Optional: Set `export VERSION=...` for a specific version. Default is `latest`. You can find version numbers in the [Release Notes](/container/release-notes).

{% hint style="info" %}
By purchasing the **Software Updates** package, you'll *always have access to the* [*latest releases*](/container/release-notes) of Celantur Container.

[We're happy to help you](https://www.celantur.com/contact/) with getting access to the newest features and improvements.
{% endhint %}

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th data-hidden></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>⭐ <strong>Release Notes</strong><br>Discover the newest features and improvements for Celantur Container.</td><td></td><td></td><td><a href="/pages/VSDnBH3L56bKpZEgXGOt">/pages/VSDnBH3L56bKpZEgXGOt</a></td></tr></tbody></table>


# Usage

For version 25.05.1 and earlier.


# General Parameters

{% hint style="info" %}
Use `bash celantur --help` to print all the parameters and exit.
{% endhint %}

## Anonymisation

<table><thead><tr><th width="324">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><p><code>-a OBJECT</code></p><p><code>--anonymise OBJECT</code></p></td><td><p><strong>REQUIRED.</strong></p><p>Select what you want to anonymise.</p><p>Options: <code>face</code>, <code>license-plate</code>, <code>person</code>, <code>vehicle</code></p></td></tr><tr><td><code>--method METHOD</code></td><td><p>Choose anonymisation method.</p><p>Options:</p><ul><li><code>blur</code> : (default) non-reversible blur.</li><li><code>blacken</code> : remove colour value from detection.</li><li><code>pixelate</code> : low-res rendering of detection.</li><li><code>detect</code> : no anonymation.</li></ul></td></tr><tr><td><code>--bbox</code></td><td>Anonymise whole bounding boxes instead of segmentation.</td></tr><tr><td><code>--debug</code></td><td>Visualise bounding boxes, anonymisation and <a href="#format-tiling">tiling</a>.</td></tr><tr><td><p><code>--score</code></p><p><code>--confidence</code></p></td><td>Print the confidence scores for the detected objects on images (only if <code>--debug</code> is enabled).</td></tr><tr><td><code>--save-mask TYPE</code></td><td><p>Save binary mask or instance mask or both (all).</p><p>See <a data-mention href="/pages/omGhPCeIYcpHVDD8Y0zg">/pages/omGhPCeIYcpHVDD8Y0zg</a>.<br>Options: <code>binary</code>, <code>instance</code>, <code>all</code></p></td></tr><tr><td><code>--mask-scale [0..100]</code></td><td>Downscale binary or segmentation mask (only if <code>--save-mask</code>).</td></tr><tr><td><code>--overwrite</code></td><td>Overwrite existing files in output folder. If not specified, files in input folder will be skipped if file with same name exists in output folder.</td></tr><tr><td><code>--quality [0..100]</code></td><td>Quality of output JPEG image.</td></tr><tr><td><p><code>-f FORMAT</code></p><p><code>--format FORMAT</code></p></td><td>See <a data-mention href="#format-tiling">#format-tiling</a></td></tr><tr><td><p><code>--file-type {image,video}</code></p><p><code>-t {image,video}</code></p></td><td>Select file type for processing. Default: only images selected. Since v26.01.1.</td></tr></tbody></table>

### Blurring gradients

For details see [Customize Blurring](/container/usage/customize-blurring)

<table><thead><tr><th width="397">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>--face-anonymization-gradient-start</code></td><td>Margin of gradual face blurring</td></tr><tr><td><code>--face-anonymization-gradient-stop</code></td><td>Padding of gradual face blurring</td></tr><tr><td><code>--license-plate-anonymization-gradient-start</code></td><td>Margin of gradual license plate blurring</td></tr><tr><td><code>--license-plate-anonymization-gradient-stop</code></td><td>Padding of gradual license plate blurring</td></tr><tr><td><code>--kernel-size-face</code></td><td>Kernel size for face blur.</td></tr><tr><td><code>--kernel-size-person</code></td><td>Kernel size for person blur.</td></tr><tr><td><code>--kernel-size-license-plate</code></td><td>Kernel size for license plate blur.</td></tr><tr><td><code>--kernel-size-vehicle</code></td><td>Kernel size for vehicle blur.</td></tr></tbody></table>

### Ignore areas

You can define one or multiple rectangular areas within an image that should not be anonymised with [input JSON](/container/usage/batch-and-stream-mode#ignore-areas-via-input-json) in Batch and stream mode and with the `ignores` attribute in [REST API mode](/container/usage/rest-api-v1-mode#upload-file).

## Inference

<table><thead><tr><th width="336">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><p><code>-e INFERENCE_ENGINE</code></p><p><code>--inference-engine INFERENCE_ENGINE</code></p><p><code>--model INFERENCE_ENGINE</code></p></td><td>Select inference model. Current default is <code>segmentatio-omnium</code></td></tr><tr><td><code>--face-threshold [0..1]</code></td><td>Threshold for face detection. Defaul: <code>0.2</code>.</td></tr><tr><td><code>--license-plate-threshold [0..1]</code></td><td>Threshold for license plate detection. Default: <code>0.2</code>.</td></tr><tr><td><code>--vehicle-threshold [0..1]</code></td><td>Threshold for vehicle detection. Default: <code>0.4</code>.</td></tr><tr><td><code>--person-threshold [0..1]</code></td><td>Threshold for person detection. Default: <code>0.4</code>.</td></tr><tr><td><code>--cpu-mode</code></td><td>Disable GPU support, <a data-mention href="/pages/Y5Qy2XKl1Dzb69Aei1vH">/pages/Y5Qy2XKl1Dzb69Aei1vH</a>.</td></tr></tbody></table>

## Video processing

<table><thead><tr><th width="265">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>--video</code></td><td>Anonymise videos, skip images. Alias for <code>-t video</code> and no <code>-t image</code></td></tr><tr><td><code>--no-object-tracking</code></td><td>Disables <a data-mention href="/pages/lJ3DUakQZ80cWR6DtRIr">/pages/lJ3DUakQZ80cWR6DtRIr</a> which reduces flickering of anonymized objects in videos.</td></tr><tr><td><code>--keep-bit-rate</code></td><td>Using this flag will encode the anonymised video with a bitrate close to the original video and ensure a nearly identically file size of the processed video, at the cost of 10% to 20% higher processing time.</td></tr><tr><td><code>--no-ffmpeg-merge</code></td><td><p>Usually after processing the frames, in the post-processing process,</p><ul><li>audio and data streams of the input video is merged into the output video, and</li><li>the bitrate of the output video is set to be close to the input video if <code>--keep-bit-rate</code> .</li></ul><p>With <code>--no-ffmpeg-merge</code>, you disable this step.<br>Since v26.01.1.</p></td></tr></tbody></table>

## Format / Tiling

By specifying image format settings with `--format FORMAT` , `-f FORMAT`, Celantur Container can achieve improved results and apply anonymization only to a specific region of an image.

{% hint style="info" %}
**Don't use spaces in the format string.**\
Otherwise Bash has problems interpreting it as one argument.
{% endhint %}

{% tabs %}
{% tab title="Pre-defined format" %}
You can use the option `--format` to choose the resolution of the input images, eg. `--format pano:8000` for an image resolution of 8000x4000.\
Use `--format whole` (default) for all formats not listed below, or if the input images have different resolutions.

<table><thead><tr><th width="201">Parameter</th><th>Resolution</th></tr></thead><tbody><tr><td><code>pano:4096</code></td><td>4096x2048</td></tr><tr><td><code>pano:5400</code></td><td>5400x2700</td></tr><tr><td><code>pano:5640</code></td><td>5640x2816</td></tr><tr><td><code>pano:7060</code></td><td>7060x3530</td></tr><tr><td><code>pano:7680</code></td><td>7680x3840</td></tr><tr><td><code>pano:8000</code></td><td>8000x4000</td></tr><tr><td><code>pano:7680</code></td><td>7680x3840</td></tr><tr><td><code>pano:8000</code></td><td>8000x4000</td></tr><tr><td><code>pano:8192</code></td><td>8192x4096</td></tr><tr><td><code>pano:11000</code></td><td>11000x5500</td></tr><tr><td><code>whole</code></td><td><strong>default</strong>, valid for all resolutions</td></tr></tbody></table>

{% hint style="info" %}
Ensure that the image resolution matches exactly the predefined resolution in the parameter to avoid processing errors.
{% endhint %}
{% endtab %}

{% tab title="Custom tiling" %}

### Custom tiling for improved results

In certain cases, its beneficial to process high-resolution imagery in tiles, instead of the whole image. Small, distant objects are more likely to be detected.

```bash
--format '{"number":[nx,ny],"overlap":[ox,oy]}'
```

<table><thead><tr><th width="137">Parameter</th><th>Description</th></tr></thead><tbody><tr><td>nx</td><td>Number of horizontal tiles</td></tr><tr><td>ny</td><td>Number of vertical tiles</td></tr><tr><td>ox</td><td>Horizontal overlap between tiles in pixels</td></tr><tr><td>oy</td><td>Vertical overlap between tiles in pixels</td></tr></tbody></table>

### Limit anonymization to a section of the image

Apply anonymization only to a specified rectangular section of the image. This can result in faster processing time.

<figure><img src="/files/9XFJTBNSyxNBz7UwDU5k" alt=""><figcaption></figcaption></figure>

<pre><code><strong>--format '{"number":[3,2],"overlap":[ox,oy],"section":[x1,y1,x2,y2]}'
</strong></code></pre>

{% hint style="info" %}
`number` and `overlap` attribute are required when specifying the section, as seen in the example above.
{% endhint %}

<table><thead><tr><th width="136">Parameter</th><th>Description</th></tr></thead><tbody><tr><td>x1, y1</td><td>Top left coordinate of the section</td></tr><tr><td>x2, y2</td><td>Bottom right coordinate of the section</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

## Configuration (under the hood)

<table><thead><tr><th width="268">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><p><code>-l FILE</code></p><p><code>--license FILE</code></p></td><td>Path of the license file.</td></tr><tr><td><p><code>-i PATH</code></p><p><code>--input PATH</code></p><p><code>--input-dir PATH</code></p></td><td>Input file or directory.</td></tr><tr><td><p><code>-o PATH</code></p><p><code>--output PATH</code></p><p><code>--output-dir PATH</code></p></td><td>Output directory.</td></tr><tr><td><code>--log-level LEVEL</code></td><td><p>Logging level.</p><p>Options: <code>DEBUG</code>, <code>DETAIL</code>, <code>INFO</code>, <code>WARNING</code>, <code>ERROR</code>, <code>CRITICAL</code></p></td></tr><tr><td><code>--log-dir FOLDER</code></td><td>Location of the log files.</td></tr><tr><td><code>--pid-file FILE</code></td><td>Path of PID file.</td></tr><tr><td><code>--monitor FILE.json</code></td><td>[EXPERIMENTAL] Gather hardware utilisation in <code>FILE.json</code></td></tr></tbody></table>


# Recommended Parameters

A list of recommended parameters for different camera systems to achieve best anonymization results with Celantur Container.

Go to: [#dji](#dji "mention") [#insta360](#insta360 "mention") [#ladybug](#ladybug "mention") [#mosaic](#mosaic "mention")

{% hint style="success" %}
When starting with a demo of Celantur Container, our team will send you a customised code sample.
{% endhint %}

## Anonymise Mobile Mapping Images

Due to large resolution, panorama images require special parametrisation to achieve the best anonymisation results.

If the panorama's resolution exactly matches an item in the list of [Predefined Formats](/container/usage/batch-and-stream-mode#predefined-formats) (e.g. `pano:8192`), you can use it as `--format` argument:

{% code overflow="wrap" %}

```bash
./celantur.sh -a face  -a license-plate --format pano:8192
```

{% endcode %}

If your panorama's resolution is not part of [Predefined Formats](/container/usage/batch-and-stream-mode#predefined-formats), you can specify [Custom Tiling](/container/usage/general-parameters#custom-tiling):

<pre class="language-bash" data-overflow="wrap"><code class="lang-bash"><strong>./celantur.sh -a face -a license-plate \
</strong>  --format '{"number":[4,1],"overlap":[300,0],"section":[0,1870,12288,4950]}'
</code></pre>

{% hint style="info" %}
For best anonymization results, tiles should roughly be square.
{% endhint %}

### Mosaic

#### Mosaic X

Panorama images (13504x6752, 91.2 MP)

{% code overflow="wrap" %}

```bash
./celantur.sh -a face -a license-plate --face-threshold 0.1 --license-plate-threshold 0.1 \
  -f '{"number":[5,1],"overlap":[400,0],"section":[0,2200,13504,5300]}'
```

{% endcode %}

{% hint style="info" %}
Adapt thresholds (lower = better detections, potentially more false positives; higher = less false positives).
{% endhint %}

#### Mosaic 51

Panorama images (12288x6144, 75.5 MP)

```sh
./celantur.sh -a face -a license-plate --face-threshold 0.1 --license-plate-threshold 0.1 \
  -f '{"number":[4,1],"overlap":[200,0],"section":[0,1870,12288,4950]}'
```

### Insta360

#### Insta360 X4

Panorama images (11904x5952):

{% code overflow="wrap" %}

```bash
./celantur.sh \
  -a face \
  -a license-plate \
  --model segmentatio-omnium \
  -f '{"number":[4,1],"overlap":[200,0],"section":[0,2000,11904,4900]}' 
```

{% endcode %}

### GoPro

#### GoPro MAX

Panorama images (5760x2880)

{% code overflow="wrap" %}

```bash
./celantur.sh -a face -a license-plate \
  -f '{"number":[4,1],"overlap":[100,0],"section":[0,1000,5760,2340]}'
  
```

{% endcode %}

### Ladybug

#### Ladybug 5+

Panorama images (8000x4000)

<pre class="language-bash" data-title="Batch mode, face / license-plate" data-overflow="wrap"><code class="lang-bash"><strong>./celantur.sh -a face -a license-plate -f pano:8000 
</strong></code></pre>

#### Ladybug 6

Panorama images (12288x6144)

{% code title="Batch mode, face / license-plate" overflow="wrap" %}

```bash
./celantur.sh -a face -a license-plate --quality 85 \
  -f '{"number":[4,1],"overlap":[300,0],"section":[0,1870,12288,4950]}'
```

{% endcode %}

Planar images (2992x4096)

{% code overflow="wrap" %}

```bash
./celantur.sh -a face -a license-plate --license-plate-threshold 0.1 \
  -f '{"number":[2,1],"overlap":[750,0],"section":[0,1500,2992,4096]}'
```

{% endcode %}

Comment to planar images: Upper part of image is ignored.

### NCTech

#### iStar Pulsar

Panorama images (11000x5500)

{% code overflow="wrap" %}

```bash
./celantur.sh -a face -a license-plate --face-threshold 0.1 --license-plate-threshold 0.1 \ 
  -f pano:11000
```

{% endcode %}

### Smart Delta

#### SmartPano Gen2

Panorama images (7680x3840)

{% code overflow="wrap" %}

```bash
./celantur.sh -a face -a license-plate --face-threshold 0.1 --license-plate-threshold 0.1 \
  -f '{"number":[4,1],"overlap":[200,0],"section":[0,1200,7680,2900]}'
```

{% endcode %}

{% code overflow="wrap" %}

```bash
./celantur.sh -a person -a vehicle -f '{"number":[4,1],"overlap":[200,0],"section":[0,1200,7680,2900]}'
```

{% endcode %}

### AVT

#### Prosilica GT4500

Planar images (5472x3084)

{% code overflow="wrap" %}

```bash
./celantur.sh -a face -a license-plate --license-plate-threshold 0.1 \
  -f '{"number":[2,1],"overlap":[750,0],"section":[0,1000,5328,4608]}'
```

{% endcode %}

Comment: Upper part of image is ignored.

## Anonymize Drone Images

For best anonymization results, the whole drone image should be split into roughly square tiles each of which is ca 4 to 10 times larger than the objects to be blurred, and with a general overlap.

More information in [General Parameters](/container/usage/general-parameters#custom-tiling)

```bash
./celantur.sh -a person --person-threshold 0.3 \
  -a vehicle --vehicle-threshold 0.4 \
  -f '{"number":[4,3],"overlap":[200,200]}'
```

#### DJI Mini 3 Pro

Images (4032x3024).

Persons and vehicles

{% code overflow="wrap" %}

```bash
./celantur.sh -a person --person-threshold 0.3 \
  -a vehicle --vehicle-threshold 0.4 \
  -f '{"number":[4,3],"overlap":[200,200]}'
```

{% endcode %}

Faces and license plates

{% code overflow="wrap" %}

```bash
./celantur.sh -a face --face-threshold 0.1 \
  -a license-plate --license-plate-threshold 0.1 \ 
  -f '{"number":[4,3],"overlap":[200,200]}'
```

{% endcode %}

## Anonymize FullHD Videos

{% hint style="success" %}
Check if your video's [codec](https://doc.celantur.com/container/usage/batch-and-stream-mode#supported-video-codecs) is supported.
{% endhint %}

{% code overflow="wrap" %}

```bash
./celantur.sh -a face -a license-plate --video --keep-bit-rate
```

{% endcode %}

### FullHD Dashcam Frames

{% code overflow="wrap" %}

```bash
./celantur.sh -a face -a license-plate
```

{% endcode %}


# Batch and Stream mode

Celantur Container batch and stream mode allow you to anonymize images and videos stored on the local file system.

{% embed url="<https://www.youtube.com/watch?v=eFwkK1XSoB0>" %}
How to use Celantur Container video
{% endembed %}

## Starting in Batch mode

{% hint style="info" %}
For setup, checkout the steps in [Installation on Linux](/container/requirements-and-installation/installation-on-linux)
{% endhint %}

Starting the Container in Batch mode triggers a processing of all files in the `input` folder. After files have been processed, the Container is shut down.

`bash celantur.sh -a face -a license-plate`

## Starting in Stream mode

Stream mode keeps the Container continuously checking the `input` folder for new files that have to be processed. The delay between checks can be specified in seconds. The Container needs to be shut down manually.

` bash celantur.sh`` `` `**`--stream 1`**` `` ``-a face -a license-plate `

{% hint style="warning" %}
In stream mode, files in input folder are automatically **deleted** after they are processed!
{% endhint %}

<table><thead><tr><th width="374">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><p><code>--stream [seconds]</code></p><p><br><br><code>--wait [seconds]</code></p></td><td>Streaming mode (Wait time in seconds).</td></tr></tbody></table>

## Image and video processing

By default, Celantur Container processes images. Video processing has to be specified by adding the `--video` parameter. You can also use the `--file-type` / `-t` parameter to specify both.

**Images:** `bash celantur.sh -a face -a license-plate`

**Videos:** `bash celantur.sh --video -a face -a license-plate`

**Both images and videos:** `bash celantur.sh -t video -t image -a face -a license-plate`

## Parameters

You can add `bash celantur.sh <parameters>` to control the behavior of Celantur Container. Check out [General Parameters](/container/usage/general-parameters) and [Recommended Parameters](/container/usage/recommended-parameters) for specific camera systems and resolutions. Experienced Linux user can also modify the script `celantur.sh`

### Ignore areas via input JSON

Customer can add JSON as input with the images to configure per-image anonymisation, e.g. ignore areas that should not be blurred.

#### Schema

JSON file has the same file name as the image with a different extension (`.json`), e.g.

* Image: image-file.jpeg
* JSON: image-file.json

You can define multiple areas with the `ignores` list.

```json
{ 
  "ignores": [
    {
      "topLeftX": 123, 
      "topLeftY": 566, 
      "width": 44,     
      "height": 12     
    }
  ]
}
```

## FAQ

### How do I use input/output folders on an external drive?

You can use symbolic links (see [ln](https://en.wikipedia.org/wiki/Ln_\(Unix\)) for reference) for the input and output folders, e.g. in the folder with the `celantur.sh` script:

```sh
# set "input" as a symbolic link to an external drive
ln -s /path/to/external/drive/input-images input

# set "output" as a symbolic link to an external drive
ln -s /path/to/external/drive/output-images output
```

### Can I start multiple container instances on one machine?

Yes, this is possible and can lead to a higher throughput when you process images, by having several container instances working in parallel. Please make sure that your system has enough resources available.

Run the following command as many times as how many container instances you want to start:

```bash
celantur.sh --detach
```

The `--detach` flag is supported starting from version 22.06.3.

Note that this will start container in the detached mode and you will not be able to observe the text output. To inspect which containers are currently running use `docker ps`, which will also print the container IDs. To inspect log outputs of a particular container, use `docker logs <container_id>`. Finally, to stop the container use `docker kill <container_id> && docker rm <container_id>`

{% hint style="info" %}
It's highly recommended to assign **dedicated input/output folders** to each container instance, when using the batch/stream mode.

To do that, either run celantur.sh from the corresponding processing folder, or use `export PROCESS_DIR=<processing_directory_for_this_container>` before executing`celantur.sh`.
{% endhint %}

### "Permission denied" error when writing files

**Problem**: `[Errno 13] Permission denied: '/path/to/file'`

In Docker, if you mount a directory to Docker that does not exist, Docker creates the folder as root. Inside Docker container, the user (with UID 1000) cannot write in the directory.

**Solution**: Create the folders `output` and `log` before you mount them and ensure that the file owner has UID 1000.

```bash
mkdir log output
sudo chown 1000:1000 log output  
```

Alternatively, give everyone write permission to `log` and `output`:

```bash
mkdir log output
chmod 777 log output
```

### **"Read-only file system" error when writing files**

**Problem**: `[Errno 30] Read-only file system: '/path/to/file'`

**Solution**: The folder is mounted in Docker as read-only. Remove the appendix `:ro` from the `-v` parameter.

### Will image EXIF, IPTC and XMP metadata be carried over to the anonymized image?

Yes, metadata (e.g. EXIF, IPTC and XMP information, ICC color profile) is retained when creating the anonymized version of an image.

### Will video metadata be carried over to the anonymized video?

Celantur Container attempts to copy over all stream/track and container metadata to the anonymized video.

### Supported image formats

The following image formats are supported:

* `.jpg` / `.jpeg`
* `.png`
* `.tif` / `.tiff`
* `.bmp`
* `.jfif`

### Supported video codecs

Codecs are essential for encoding and decoding audio, video, or other data streams.

Celantur Container provides support, among others, for these codecs:

* `h265`
* `h264`
* `mjpeg`
* `mpeg4`

Plese [contact us](https://www.celantur.com/contact/), if you want to know more about our support for other codes.

### Are ROS2 MCAP files supported?

Please see [Anonymization of ROS2 .mcap files](/tutorials/anonymisation-of-ros2-.mcap-files)

### Can multiple GPUs in one machine be utilized?

Yes, by starting multiple instances/processes of Celantur Container.

To specify the GPU which Celantur Container utilizes, you need to adapt the `celantur.sh` script. Instead of:

` [[ ${PARAMETERS} != *"--cpu-mode"* ]] && GPU="--gpus`` `` `**`all`**`"`

change it to

` [[ ${PARAMETERS} != *"--cpu-mode"* ]] && GPU="--gpus`` `` `**`device=<GPU-UUID>`**`"`\
\
You find the GPU UUID with `nvidia-smi -L`. Result is GPU-xxxx-xxx-xxx-xxxx-xxxxxxx

### Can a Basic/PRO license be used on a multi-GPU machine?

Yes, Celantur Container can be used on multi-GPU systems. Multiple-GPU UUIDs can be specified in a license file.

### Why is the file size of a JPEG different after anonymization?

Celantur applies anonymization on the raw pixel data. JPEG compression is applied when saving an anonymized image as a JPEG, resulting in a different file size. The resulting JPEG file size can be influenced by changing the `--quality` parameter (default: 90).


# REST API (v1) mode

REST API mode for Celantur Container

## Overview

You can start the Celantur Container in API mode and use the REST API to anonymize images and videos. There are two ways to process images and videos, via **synchronous** and **asynchronous** uploads.

When you upload files via synchronous upload, which is the default configuration, it takes some time for you to get the response. You can then immediately download the result.

When you upload files via the asynchronous upload, by adding the header parameter `x-is-async: true` (and optionally a webhook via the query parameter), you'll immediately receive the response, but the processing is not necessarily finished. If you added a webhook, you'll be notified once processing is finished. Otherwise, you can query the `GET /task/{id}` to check whether the processing is finished. See more information [below](#asynchronous-processing).

### Start the Container in REST API mode

Start the server with all object types (`-a face -a license-plate -a person -a vehicle`) that you want to anonymize by using the API. You can select specific objects for individual images using API calls.

{% code overflow="wrap" %}

```bash
bash celantur.sh --api --api-endpoint http://localhost:7000/ -a face -a license-plate -a person -a vehicle --format whole --save-mask all
```

{% endcode %}

#### CLI starting parameters

See [General Parameters](/container/usage/general-parameters) for other parameters.

<table><thead><tr><th width="324">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>--api</code></td><td>Start container in REST API mode.</td></tr><tr><td><code>--api-endpoint URL</code></td><td>Specify the API endpoint that is returned with the requests. URL for downloading the anonymised images, binary masks and metadata.</td></tr></tbody></table>

### Task and files

There are two classes of endpoints:

* `/file` endpoints where you can upload and download files. When you upload a file with `POST /file` you will receive a JSON response including `{ "id": "string", ... }`. You can use the **id** to query the status of processing via `GET /task/{id}` endpoint.
* `/task` endpoints where you can query the status of file processing and manage the tasks, especially important for asynchronous processing. For processing, the files are stored internally in the folders specified by the user with the `--input` and `--output` parameters.\
  Currently, you need to manage the storage manually by deleting the files associated with a task with the `DELETE /task/{id}` to free up stsorage.

{% hint style="info" %}
Metadata, binary and instance segmentation masks are not yet supported for videos.
{% endhint %}

### Webhook

If you specify a webhook URL in `POST /file` with the query parameter `webhook` (urlencoded). You can specify header authentication with `web-auth-header-name` and `web-auth-header-value`.

After the file has been processed, the Container will post a request to the he webhook URL with the following header and body (example):

```
POST {webhook}
{web-auth-header-name}: {web-auth-header-value}

{ 
  "ts": "2023-02-08T12:30:45.123456",
  "type": "notification.processing.status.changed",
  "event": {
    "id": "1693295888421318",
    "status": "done"
  }
} 
```

### Sychronous processing

<figure><img src="/files/yHt4gkz7cXNnHwSoQ6tC" alt=""><figcaption></figcaption></figure>

1. Upload image with POST request [#upload-file](#upload-file "mention").\
   Processing is ready once the request returns with a successful response.
2. Download image with GET request [#download-anonymized-image](#download-anonymized-image "mention")
3. Download segmentation masks and metadata:
   1. GET request [#download-binary-mask](#download-binary-mask "mention")
   2. GET request [#download-instance-mask](#download-instance-mask "mention")
   3. GET request [#download-image-metadata-json](#download-image-metadata-json "mention")

### Asynchronous processing

<figure><img src="/files/Zb7cReFAF1jLvKEMRgkn" alt=""><figcaption></figcaption></figure>

1. Upload image with POST request [#upload-file](#upload-file "mention") with the header parameter `x-is-async: true`.\
   Request returns immediately with a response. However processing runs asynchronously and is not necessary complete.
2. Wait until processing is done.
   1. Webhook: If you added webhook, you'll receive notification, once the processing is complete.
   2. Otherwise query the task status with [#list-all-processing-tasks](#list-all-processing-tasks "mention")
3. Download the assets as in [#aynchronous-processing](#aynchronous-processing "mention").
4. Delete the task with [#delete-a-specific-task](#delete-a-specific-task "mention")

{% hint style="warning" %}
In asynchronous mode, you need to pay attention to the storage management. So delete all tasks including files that you have downloaded and are not required anymore. You can delete single tasks `DELETE /tast/{id}` or all tasks `DELETE /task/lists` .
{% endhint %}

## Image and video anonymization

We currently support JPEG and PNG images, and MP3 video containers.

## Upload file

<mark style="color:green;">`POST`</mark> `https://localhost/v1/file`

Upload a file that is processed with the specified method. The container only holds data for one image at any time. A new POST request overwrites the old data.

#### Query Parameters

| Name                                     | Type    | Description                                                                                                                                                                                                                                                                                                               |
| ---------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| method<mark style="color:red;">\*</mark> | String  | <p>Enum: <code>blur</code>, <code>pixelate</code>, <code>blacken</code>, <code>detect</code></p><p>Default: <code>blur</code></p><p>Specifies processing method.</p><p>Method <code>detect</code> only returns segmentation and binary masks, not an anonymized image.</p>                                                |
| debug                                    | Boolean | Print bounding boxes and segmentation masks of detected objects on the image.                                                                                                                                                                                                                                             |
| score                                    | Boolean | Print the detection scores of objects on the image. Works only if debug is true.                                                                                                                                                                                                                                          |
| face                                     | Boolean | Specifies whether faces should be anonymized/detected.                                                                                                                                                                                                                                                                    |
| license-plate                            | Boolean | Specifies whether license plates should be anonymized/detected.                                                                                                                                                                                                                                                           |
| person                                   | Boolean | Specifies whether persons should be anonymized/detected.                                                                                                                                                                                                                                                                  |
| vehicle                                  | Boolean | Specifies whether vehicles should be anonymized/detected.                                                                                                                                                                                                                                                                 |
| bbox                                     | Boolean | Anonymize bounding boxes of objects (instead of segmentation)                                                                                                                                                                                                                                                             |
| format                                   | String  | <p>Default: <code>whole</code></p><p>Example:</p><p><code>format={"number": \[2,2], "overlap": \[0, 0]}</code></p><p>Tiling of the input image</p>                                                                                                                                                                        |
| ignores                                  | String  | <p>Default: ""<br>Example: <code>ignores=\[{"topLeftX": 182,"topLeftY": 154,"width":2000,"height":2000}]</code></p><p>Areas of the image that are not going to be anonymized</p>                                                                                                                                          |
| face-threshold                           | Number  | <p>Specifies detection threshold <code>0..1</code> for faces.</p><p>Default: <code>0.5</code></p>                                                                                                                                                                                                                         |
| segmentation-threshold                   | Number  | <p><strong>DEPRECATED</strong></p><p>Specifies detection threshold value for segmentation.</p><p>▶ Use <code>person-threshold</code> and <code>vehicle-threshold</code> instead.</p>                                                                                                                                      |
| vehicle-threshold                        | Number  | <p>Specifies detection threshold <code>0..1</code> for vehicles.</p><p>Default: <code>0.4</code></p>                                                                                                                                                                                                                      |
| person-threshold                         | Number  | <p>Specifies detection threshold <code>0..1</code> for persons.</p><p>Default: <code>0.4</code></p>                                                                                                                                                                                                                       |
| license-plate-threshold                  | Number  | <p>Specifies detection threshold <code>0..1</code> for license plates.</p><p>Default: <code>0.5</code></p>                                                                                                                                                                                                                |
| no-object-tracking                       | Boolean | Disables object tracking in videos, which is enabled by default. See [Object Tracking](/container/usage/object-tracking)                                                                                                                                                                                                  |
| keep-bit-rate                            | Boolean | <p>Specifies whether the bitrate of the anonymized video should remain very close to the one of the original video.</p><p>Enabling <code>keep-bit-rate</code> will ensure a nearly identically file size of the processed video, at the cost of 10% to 20% higher processing time.<br><br>Default: <code>false</code></p> |
| webhook                                  | String  | Webhook URL (urlencoded)                                                                                                                                                                                                                                                                                                  |
| webhook-auth-header-name                 | String  | Webhook header auth key/name                                                                                                                                                                                                                                                                                              |
| webhook-auth-header-value                | String  | Webhook header auth value                                                                                                                                                                                                                                                                                                 |

#### Headers

| Name       | Type   | Description                                                                                                              |
| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------ |
| x-is-async | String | <p>Enables async processing.</p><p>Values: <code>true</code> or <code>false</code></p><p>Default: <code>false</code></p> |

#### Request Body

| Name                                         | Type                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| -------------------------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| fileobject<mark style="color:red;">\*</mark> | string\<binary> (Fileobject) | <p><strong>Images:</strong></p><p><code>fileobject=@/path/to/input/image;</code></p><p>See <a data-mention href="/pages/iiet2gwTQcsmzQHN5m7V#supported-image-formats">/pages/iiet2gwTQcsmzQHN5m7V#supported-image-formats</a></p><p><strong>Videos:</strong></p><p>Specify the video type</p><p><code>fileobject=@/path/to/input/video;type=video/mp4</code></p><p>See <a data-mention href="/pages/iiet2gwTQcsmzQHN5m7V#supported-video-codecs">/pages/iiet2gwTQcsmzQHN5m7V#supported-video-codecs</a></p> |

{% tabs %}
{% tab title="200: OK JSON (image upload)" %}

```javascript
{
  "content_type": "image/jpeg",
  "id": "string (uuid)",
  "metadata_url": "string",
  "binary_mask_url": "string",
  "instance_mask_url": "string",
  "anonymised_url": "string"
}
```

{% endtab %}

{% tab title="422: Unprocessable Entity JSON" %}

```javascript
{
  "detail": "..."
}
```

{% endtab %}

{% tab title="500: Internal Server Error " %}

{% endtab %}

{% tab title="200: OK JSON (video upload)" %}

```json
{ 
  "content_type": "video/mp4",
  "id": "string (uuid)",
  "anonymized_video": "string",
  "metadata_url": "string"
}
```

{% endtab %}
{% endtabs %}

## Download anonymized image

<mark style="color:blue;">`GET`</mark> `https://localhost/v1/file/{id}/anonymised`

Download anonymized image

#### Path Parameters

| Name                                 | Type   | Description                                          |
| ------------------------------------ | ------ | ---------------------------------------------------- |
| id<mark style="color:red;">\*</mark> | String | The `id` (UUID) of the file that will be downloaded. |

#### Query Parameters

| Name           | Type   | Description                                                                                                       |
| -------------- | ------ | ----------------------------------------------------------------------------------------------------------------- |
| download       | String | <p>Enum: <code>JPEG</code> or <code>PNG</code></p><p>Whether the image should be downloaded as a JPEG or PNG.</p> |
| quality        | Number | <p>Specifies quality level for JPEG images ranging from <code>1 .. 100</code>.</p><p>Default: <code>90</code></p> |
| compress-level | Number | <p>Specifies compression level for PNG images ranging from <code>0 .. 9</code>.</p><p>Default: <code>5</code></p> |

{% tabs %}
{% tab title="200: OK JPEG or PNG" %}

```javascript
Media type: image/png or image/jpeg
```

{% endtab %}

{% tab title="422: Unprocessable Entity JSON" %}

```javascript
{
    "detail": "..."
}
```

{% endtab %}

{% tab title="500: Internal Server Error " %}

{% endtab %}
{% endtabs %}

## Download anonymized video

<mark style="color:blue;">`GET`</mark> `https://localhost/v1/file/{id}/video/anonymised`

Download anonymized video

#### Path Parameters

| Name | Type   | Description                                          |
| ---- | ------ | ---------------------------------------------------- |
| id   | String | The `id` (UUID) of the file that will be downloaded. |

{% tabs %}
{% tab title="200: OK video/mp4" %}
Media type: "video/mp4"
{% endtab %}

{% tab title="422: Unprocessable Entity JSON" %}

```
{
  "detail": "..."
}
```

{% endtab %}

{% tab title="500: Internal Server Error " %}

{% endtab %}
{% endtabs %}

## Download binary mask

<mark style="color:blue;">`GET`</mark> `https://localhost/v1/file/{id}/binary-mask`

#### Path Parameters

| Name                                 | Type   | Description                                                                    |
| ------------------------------------ | ------ | ------------------------------------------------------------------------------ |
| id<mark style="color:red;">\*</mark> | String | The `id` (UUID) of the file whose binary segmentation mask will be downloaded. |

#### Query Parameters

| Name       | Type   | Description                                                                                                                                 |
| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| mask-scale | Number | <p>Specifies the ratio at which the mask file will be scaled down, range between <code>0 .. 100</code>.</p><p>Default: <code>100</code></p> |

{% tabs %}
{% tab title="200: OK PNG" %}
Media type: image/png
{% endtab %}

{% tab title="422: Unprocessable Entity JSON" %}

```javascript
{
  "detail": "..."
}
```

{% endtab %}

{% tab title="500: Internal Server Error " %}

{% endtab %}
{% endtabs %}

For conceptual information on segmentation masks, see:

{% content-ref url="/pages/omGhPCeIYcpHVDD8Y0zg" %}
[Segmentation Masks and Metadata](/container/usage/segmentation-masks-and-metadata)
{% endcontent-ref %}

## Download instance mask

<mark style="color:blue;">`GET`</mark> `https://localhost/v1/file/{id}/instance-mask`

#### Path Parameters

| Name | Type   | Description                                                                      |
| ---- | ------ | -------------------------------------------------------------------------------- |
| id   | String | The `id` (UUID) of the file whose instance segmentation mask will be downloaded. |

#### Query Parameters

| Name       | Type   | Description                                                                                                                                 |
| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| mask-scale | Number | <p>Specifies the ratio at which the mask file will be scaled down, range between <code>0 .. 100</code>.</p><p>Default: <code>100</code></p> |

{% tabs %}
{% tab title="200: OK PNG" %}

```javascript
Media type: image/png
```

{% endtab %}

{% tab title="422: Unprocessable Entity JSON" %}

```javascript
{
    "detail": "..."
}
```

{% endtab %}

{% tab title="500: Internal Server Error " %}

{% endtab %}
{% endtabs %}

For conceptual information on segmentation masks, see:

{% content-ref url="/pages/omGhPCeIYcpHVDD8Y0zg" %}
[Segmentation Masks and Metadata](/container/usage/segmentation-masks-and-metadata)
{% endcontent-ref %}

## Download image metadata (JSON)

<mark style="color:blue;">`GET`</mark> `https://localhost/v1/file/{id}/metadata`

#### Path Parameters

| Name                                 | Type   | Description                                                    |
| ------------------------------------ | ------ | -------------------------------------------------------------- |
| id<mark style="color:red;">\*</mark> | String | The `id` (UUID) of the file whose metadata will be downloaded. |

{% tabs %}
{% tab title="200: OK JSON" %}

```json
{
  "id": "cc6198c8-c696-11ee-afbe-0242ac120002.jpg",
  "detections": [
    {
      "id": 0,
      "parent_image": "cc6198c8-c696-11ee-afbe-0242ac120002.jpg",
      "offset": [
        70,
        1796
      ],
      "bbox": [
        421,
        1805,
        597,
        1982
      ],
      "type": 103,
      "score": 0.999830961227417,
      "is_anonymised": true,
      "type_label": "face",
      "color": null
    }
  ],
  "size": [
    3000,
    4000
  ],
  "duration": 0.6000208689947613,
  "filename": "cc6198c8-c696-11ee-afbe-0242ac120002.jpg",
  "folder": "/tmp/input"
}
```

{% endtab %}

{% tab title="422: Unprocessable Entity JSON" %}

```
{
    "detail": "..."
}
```

{% endtab %}

{% tab title="500: Internal Server Error " %}

{% endtab %}
{% endtabs %}

## Download video metadata (JSON)

<mark style="color:blue;">`GET`</mark> `https://localhost/v1/file/{id}/video/metadata`

Returns the metadata for the specified range of frames of the last processed video as JSON.

Consecutive frame IDs start at 0.

See [Segmentation Masks and Metadata](/container/usage/segmentation-masks-and-metadata#video-metadata-example)

#### Path Parameters

| Name                                 | Type   | Description                                                     |
| ------------------------------------ | ------ | --------------------------------------------------------------- |
| id<mark style="color:red;">\*</mark> | String | The `id` (UUID) of the video whose metadata will be downloaded. |

#### Query Parameters

| Name                                           | Type   | Description                                                                                                                                                                     |
| ---------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| start\_frame<mark style="color:red;">\*</mark> | Number | <p>Specifies the first frame of the range of frames for which the metadata will be downloaded. Range: <code>0 .. last\_frame</code>.</p><p>Default: <code>0</code></p>          |
| end\_frame<mark style="color:red;">\*</mark>   | Number | <p>Specifies the last frame of the range of frames for which the metadata will be downloaded. Range: <code>1 .. last\_frame</code>.</p><p>Default: <code>last\_frame</code></p> |

{% tabs %}
{% tab title="200: OK Metadata" %}

<pre class="language-json"><code class="lang-json"><strong>[
</strong>  {
    "id": 0,
    "detections": [
      {
        "id": 0,
        "parent_image": 0,
        "offset": [
          1501,
          1280
        ],
        "bbox": [
          1504,
          1280,
          1563,
          1337
        ],
        "type": 103,
        "score": 0.8185984492301941,
        "is_anonymised": true,
        "type_label": "face",
        "color": null
      }
    ],
    "size": [
      2160,
      3840
    ],
    "duration": 0.3577723959897412
  },
  {
    "id": 1,
    "detections": [
      {
        "id": 0,
        "parent_image": 1,
        "offset": [
          1499,
          1283
        ],
        "bbox": [
          1513,
          1283,
          1574,
          1335
        ],
        "type": 103,
        "score": 0.8149935007095337,
        "is_anonymised": true,
        "type_label": "face",
        "color": null
      }
    ],
    "size": [
      2160,
      3840
    ],
    "duration": 0.3155565749912057
  },  ...
]
</code></pre>

{% endtab %}

{% tab title="422: Unprocessable Entity No video has been uploaded" %}

```
{
    "detail": "Upload a video file at v1/file before using this endpoint."
}
```

{% endtab %}

{% tab title="422: Unprocessable Entity Image instead of video has been uploaded" %}

```
{
    "detail": "You can receive anonymised video metadata only after video upload"
}
```

{% endtab %}
{% endtabs %}

## Container and Task management

## Check Celantur Container status

<mark style="color:blue;">`GET`</mark> `https://localhost/v1/status`

Returns health status of of Celantur Container.\
200 when running, 500 when down.

{% tabs %}
{% tab title="200: OK JSON" %}

```javascript
{
  "ts": "2024-02-08T15:35:43.853905",
  "api_version": "v1",
  "status": "RUNNING"
}
```

{% endtab %}

{% tab title="500: Internal Server Error " %}

{% endtab %}
{% endtabs %}

## List all processing tasks

<mark style="color:blue;">`GET`</mark> `https://localhost/v1/task/list`

{% tabs %}
{% tab title="200: OK JSON" %}
Returns a list of tasks.
{% endtab %}
{% endtabs %}

## Delete all existing tasks

<mark style="color:red;">`DELETE`</mark> `https://localhost/v1/task/list`

Delete all the tasks' records and/or input and output files.

#### Query Parameters

| Name         | Type    | Description                                                                                                                                                            |
| ------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| confirm      | Boolean | Provide true to confirm your action.                                                                                                                                   |
| delete-scope | String  | <p><code>task-and-files</code> to delete everything.<br><code>only-files</code> to delete only files, keeping the records.<br>Default: <code>task-and-files</code></p> |

{% tabs %}
{% tab title="200: OK JSON" %}

```json
{ "result": "success", "message": "string" }
```

{% endtab %}

{% tab title="422: Unprocessable Entity " %}

{% endtab %}
{% endtabs %}

## Get information about a specific task

<mark style="color:blue;">`GET`</mark> `https://localhost/v1/task/{id}`

#### Path Parameters

| Name                                 | Type   | Description                                                                                                   |
| ------------------------------------ | ------ | ------------------------------------------------------------------------------------------------------------- |
| id<mark style="color:red;">\*</mark> | String | task / upload **id** (UUID) that is part of the response from [#upload-file](#upload-file "mention") request. |

{% tabs %}
{% tab title="200: OK JSON" %}

```json
{ "result": "success", "message": "string" }
```

{% endtab %}
{% endtabs %}

## Delete a specific task

<mark style="color:red;">`DELETE`</mark> `https://localhost/v1/task/{id}`

Remove the record and/or input and output files of a specific task.

#### Path Parameters

| Name                                 | Type   | Description                                                                                                   |
| ------------------------------------ | ------ | ------------------------------------------------------------------------------------------------------------- |
| id<mark style="color:red;">\*</mark> | String | task / upload **id** (UUID) that is part of the response from [#upload-file](#upload-file "mention") request. |

#### Query Parameters

| Name         | Type   | Description                                                                                                                                                            |
| ------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| delete-scope | String | <p><code>task-and-files</code> to delete everything.<br><code>only-files</code> to delete only files, keeping the records.<br>Default: <code>task-and-files</code></p> |

{% tabs %}
{% tab title="200: OK JSON" %}

```json
{ "result": "success", "message": "string" }
```

{% endtab %}
{% endtabs %}

## Examples

### Check server status

Check the server status by sending a GET request to the [#checks-celantur-container-status](#checks-celantur-container-status "mention")endpoint:

```bash
curl -i -X GET 'http://127.0.0.1:7000/v1/status'
```

{% code title="Response" %}

```json
{
  "ts": "2024-02-08T15:35:43.853905",
  "api_version": "v1",
  "status": "RUNNING"
}
```

{% endcode %}

### Anonymize images

#### Post image to pixelate faces

{% code overflow="wrap" %}

```bash
curl -i -X POST 'http://127.0.0.1:7000/v1/file?method=pixelate&face=True' -F 'fileobject=@/path/to/original-image.jpg'
```

{% endcode %}

#### Post image to blur blur whole persons and show debug information

{% code overflow="wrap" %}

```bash
curl -i -X POST 'http://127.0.0.1:7000/v1/file?method=blur&debug=True&person=True' -F 'fileobject=@/path/to/original-image.jpg'
```

{% endcode %}

Post method returns image id with GET request links:

{% code title="JSON Response" %}

```json
{
    "content-type": "image/jpeg",
    "id": "{image_id}",
    "metadata-url": "http://localhost:7000/v1/file/{image_id}/metadata",
    "binary-mask-url": "http://localhost:7000/v1/file/{image_id}/binary-mask",
    "instance-mask-url": "http://localhost:7000/v1/file/{image_id}/instance-mask",
    "anonymised-url": "http://localhost:7000/v1/file/{image_id}/anonymised"
}
```

{% endcode %}

#### Download anonymized image

{% code overflow="wrap" %}

```bash
curl -X GET http://127.0.0.1:7000/v1/file/{image_id}/anonymised --output /path/to/anonymised-image.jpg
```

{% endcode %}

![](/files/K3nvu7YRlQ9YxUOWvGPg)

![](/files/Ctmp6KGnNhZPgUv2Cpuh)

**Photo Credits:** [Omar Lopez](https://unsplash.com/photos/rwF_pJRWhAI) on [Unsplash](https://unsplash.com/)

#### Download segmentation mask

{% code overflow="wrap" %}

```bash
curl -X GET http://127.0.0.1:7000/v1/file/{image_id}/binary-mask --output /path/to/binary-mask.png
```

{% endcode %}

#### ![](/files/c1YXmb9HIfr29Teav8uw)

#### Download instance segmentation mask

{% code overflow="wrap" %}

```bash
curl -X GET http://127.0.0.1:7000/v1/file/{image_id}/instance-mask --output /path/to/instance-mask.png
```

{% endcode %}

#### Download downscaled instance segmentation mask

{% code overflow="wrap" %}

```bash
curl -X GET http://127.0.0.1:7000/v1/file/{image_id}/instance-mask?mask-scale=50 --output /path/to/instance-mask.png
```

{% endcode %}

![](/files/2o3bdmEtMOykDmZJNG8E)

#### Download metadata

```bash
curl -X GET http://127.0.0.1:7000/v1/file/{image_id}/metadata
```

```json
{
    "id": "omar-lopez-rwF_pJRWhAI-unsplash.jpg",
    "detections": [
    {
        "id": 0,
        "parent_image": "omar-lopez-rwF_pJRWhAI-unsplash.jpg",
        "offset": [
            1560,
            744
        ],
        "bbox": [
            1957,
            744,
            3003,
            1855
        ],
        "type": 103,
        "score": 0.9993754029273987,
        "is_anonymised": true,
        "type_label": "face",
        "color": null
    },
    {
        "id": 1,
        "parent_image": "omar-lopez-rwF_pJRWhAI-unsplash.jpg",
        "offset": [
            2682,
            760
        ],
        "bbox": [
            3091,
            760,
            4078,
            1680
        ],
        "type": 103,
        "score": 0.9989292025566101,
        "is_anonymised": true,
        "type_label": "face",
        "color": null
    },
    {
    "id": 0,
        "parent_image": "omar-lopez-rwF_pJRWhAI-unsplash.jpg",
        "offset": [
            3736,
            712
        ],
        "bbox": [
            4015,
            758,
            4777,
            1520
        ],
        "type": 103,
        "score": 0.9988161325454712,
        "is_anonymised": true,
        "type_label": "face",
        "color": null
    }
    ],
    "size": [
        3456,
        5184
    ],
    "duration": 1.8533296539999355,
    "filename": "omar-lopez-rwF_pJRWhAI-unsplash.jpg",
    "folder": null
}
```


# TCP mode

You can run Celantur Container in TCP mode. This allows you to send and receive images (in JPEG format or as NumPy array) over a TCP socket connection, resulting in performance gains by reducing read/write and data conversion overhead.

{% hint style="info" %}
Not yet supported in TCP mode

* Anonymization of video files
* Generation of metadata JSON files
  {% endhint %}

### Parameters

<table><thead><tr><th width="374">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>--server &#x3C;host:port></code></td><td><a href="#transfer-images-as-jpeg">TCP mode for JPEG image transfer.</a></td></tr><tr><td><code>--server-array &#x3C;host:port></code></td><td><a href="#transfer-images-as-numpy-arrays">TCP mode for NumPy array transfer.</a></td></tr></tbody></table>

## Transfer images as JPEG

Transfer images in JPEG format over a TCP connection by using

{% code title="Blur faces/license plates" %}

```sh
bash celantur.sh --server 0.0.0.0:9999 -a face -a license-plate --format whole
```

{% endcode %}

Find a Python implementation of the **client script** here:

{% embed url="<https://github.com/celantur/celantur-examples/blob/main/server/celantur-jpeg-client.py>" %}
Implementation
{% endembed %}

## Transfer images as NumPy arrays

Transfer images as NumPy arrays over a TCP connection by using

```
bash celantur.sh --server-array 0.0.0.0:9999 -a face -a license-plate --format whole
```

Add `save-mask binary --mask-scale 20` as [parameters](/container/usage/batch-and-stream-mode#parameters) to receive segmentation masks instead of an anonymized image. The received binary mask has to be saved as PNG.

{% code title="Get binary masks" overflow="wrap" %}

```sh
bash celantur.sh --server-array 0.0.0.0:9999 -a face -a license-plate --format whole --save-mask binary --mask-scale 20
```

{% endcode %}

Find a Python implementation of the **client script** here:

{% embed url="<https://github.com/celantur/celantur-examples/blob/main/server/celantur-numpy-client.py>" %}
Implementation
{% endembed %}

## FAQ

### I'm transferring data over a VPN, does that work?

Yes, transferring data via TCP mode over a VPN works.

{% hint style="warning" %}
The **maximum TCP frame size** has to be lower than the one specified for your VPN, to avoid issues during data transfer.
{% endhint %}


# Segmentation Masks and Metadata

Celantur container can generate two different segmentation masks and metadata per processed image:

* Binary Segmentation
* Instance Segmentation

It's activated with the `--save-mask {all, instance, binary}` parameter. The segmentation is saved as a PNG file.

<figure><img src="/files/Y44sQGjmfWsraYhWr9In" alt=""><figcaption><p>Anonymization, binary segmentation and instance segmentation applied to an image with Celantur software.</p></figcaption></figure>

## Binary Segmentation

The binary segmentation mask consist of two colors:

* Background is black
* Anonymized segments are white

The file will be saved as `image-name-bin-mask.png`.

## Instance Segmentation

#### v26.02.1 and later

In instance segmentation masks, the RGB color values are used to differentiate to individual instances/objects.

* The R (red) channel is 0.
* The G (green) channel encodes individual instances / objects.
* The B (blue) channel encodes the object type:

| Object type   | Blue channel value | Blue channel value in binary |
| ------------- | ------------------ | ---------------------------- |
| Person        | `128`              | `1000 0000`                  |
| License plate | `64`               | `0100 0000`                  |
| Face / head   | `32`               | `0010 0000`                  |
| Vehicle       | `16`               | `0001 0000`                  |

When objects overlap, their color codes are combined using the binary OR operation, e.g. overlap of license plate and vehicle results in 80 (16 + 64), overlap of two persons remains 128.

E.g. `[0, 85, 16]` is a vehicle. 16 identifies the object type, 85 identifies the instance from others.

The file will be saved as `image-name-ins-mask.png`.

#### Pre v26.02.1

In instance segmentation masks, the RGB color values are used to differentiate to individual instances/objects.

* The R (red) channel is 0.
* The G (green) channel encodes individual instances / objects.
* The B (blue) channel encodes the object type:
  * Person: `128`
  * License plate: `64`
  * Face: `192`
  * Vehicle: `255`

E.g. `[0, 85, 192]` is a face.

## Scale Down Mask Files

By adding the optional `--mask-scale {0-100}` (CLI) or `/v1/file/1/instance-mask?mask-scale={0-100}` (Container API) parameter, mask files will be scaled down by the specified ratio.

## Metadata

### Image metadata

Metadata about detected instances/objects are stored in the corresponding `image-name.json` file.

### Image metadata example

```json
{
    "id": "image-name.jpg",
    "detections": [
    {
        "id": 0,
        "parent_image": "image-name.jpg",
        "offset": [
            1560,
            744
        ],
        "bbox": [
            1957,
            744,
            3003,
            1855
        ],
        "type": 103,
        "score": 0.9993754029273987,
        "is_anonymised": true,
        "type_label": "face",
        "color": null
    },
    "size": [
        3456,
        5184
    ],
    "duration": 1.8533296539999355,
    "filename": "image-name.jpg",
    "folder": null
}
```

### Video metadata

Metadata is generated for individual frames and provided as a range of mulitple frames.

* **Batch/Stream mode:**\
  The information is stored in `filename-[startframe]-[endframe].json` in the output directory. The maximum number of frames covered by a single file is 500.
* **REST API mode:**\
  The information can be retrieved via the [REST API (v1) mode](/container/usage/rest-api-v1-mode#download-video-metadata-json) endpoint.

### Video metadata example

```json
[
  {
    "id": 0,
    "detections": [
      {
        "id": 0,
        "parent_image": 0,
        "offset": [
          3,
          4
        ],
        "bbox": [
          3,
          4,
          201,
          171
        ],
        "type": 103,
        "score": 0.8267934918403625,
        "is_anonymised": true,
        "type_label": "face",
        "color": null
      }
    ],
    "size": [
      178,
      320
    ],
    "duration": 0.35388135999892256
  },
  {
    "id": 1,
    "detections": [
      {
        "id": 0,
        "parent_image": 1,
        "offset": [
          0,
          6
        ],
        "bbox": [
          0,
          20,
          137,
          175
        ],
        "type": 103,
        "score": 0.8945223689079285,
        "is_anonymised": true,
        "type_label": "face",
        "color": null
      }
    ],
    "size": [
      178,
      320
    ],
    "duration": 0.2979645720006374
  },
  ...
]
```

### Metadata attribute reference

#### Attributes of a image or video frame

<table><thead><tr><th width="171">Attribute</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>The id of the image (file name) or video frame (sequential number)</td></tr><tr><td>detections</td><td>List of detections, see <a data-mention href="#detected-instances-objects-provided-as-a-list-under-the-detections-attribute">#detected-instances-objects-provided-as-a-list-under-the-detections-attribute</a></td></tr><tr><td>size</td><td>Size of the image or frame in [width, height]</td></tr><tr><td>duration</td><td>Duration of processing (inference and anonymization) an image or video frame. Does not include IO, e.g. read/write from hard drive.</td></tr><tr><td>filename</td><td>Name of the file</td></tr><tr><td>folder</td><td>Name of the folder (relative to root input folder)</td></tr></tbody></table>

#### Detected instances/objects provided as a list under the `detections` attribute

<table><thead><tr><th width="171">Attribute</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>The id of the detection, a sequential number starting from 0.</td></tr><tr><td>parent_image</td><td>The name of the image or the id of the video frame the detected instance/object was found on</td></tr><tr><td>offset</td><td>The offset of the detection's bounding box from the upper left corner of the image (x/y coordinates in pixels)</td></tr><tr><td>bbox</td><td>The coordinates of the detection's bounding box (x1, y1, x2, y2)</td></tr><tr><td>score</td><td>The detection's confidence score. States how confident the model is about the detection being a specific label (see type_label) between 0.0 and 1.0.</td></tr><tr><td>is_anonymized</td><td>Specifies whether the detection was anonymized (or detected with <code>method = detect</code>).</td></tr><tr><td>type_label</td><td>The detection's label assigned by the model. E.g. face, license plates, etc.</td></tr><tr><td>type</td><td>Numerical representation of the <code>type_label</code>.</td></tr><tr><td>color</td><td>The detections color (RGB) in the instance segmentation mask.</td></tr><tr><td>duration</td><td>Processing duration for a video frame (only for videos).</td></tr></tbody></table>


# Customize Blurring

Make the default anonymization method visually more appealing and accurate.

{% hint style="info" %}
Celantur ***Container*****&#x20;and&#x20;*****Cloud API*** (see[API Endpoints](/cloud-api/api-endpoints#upload-image)) offer the possibility to customize blurring. The key concepts described on this page apply to both.
{% endhint %}

Celantur Container can be customized to make default anonymization visually more appealing.

There are two sets of parameters that the user can tweak to customize the output. The default settings of these parameters were carefully selected to never harm the quality of anonymization, but that means that in certain scenarios (for example, low resolution images) these protective anonymization measures might harm visual appearance of the final result. This might become an issue if the anonymized data is publicly available.

## Gradual blur

Currently, gradual anonymization works with license plates and faces. Each of the anonymized objects has two parameters that are responsible for gradual blur.

![Gradual blur applied to an image](/files/83ipx4IFBizyEMUPILTZ)

In the image 3 bounding boxes around the face are depicted: outer, inner, and actual bounding boxes. Outside the outer bounding box nothing is blurred and inside the inner bounding box the blurring is maximal. Between these two boxes, the transition from no blur to maximum blur happens linearly. The location of outer and inner bounding boxes is determined as relative difference in bounding box size with respect to the actual bounding box. These differences are controlled by two parameters: `--<object>-anonymization-gradient-start` to control the outer boundary box and `--<object>-anonymization-gradient-stop` to control the inner boundary box. The total list of the parameters that are currently supported:

* `--face-anonymization-gradient-start x`
* `--face-anonymization-gradient-stop x`
* `--license-plate-anonymization-gradient-start x`
* `--license-plate-anonymization-gradient-stop x`

For example, if one sets parameter `--face-anonymization-gradient-start 0.5`, it means that the gradual blurring will start at 50% outside the actual bounding box. If one then sets `--face-anonymization-gradient-stop 0.2` the anonymization will not be maximal in the bounding box itself, but only inside 80% of the remaining bounding box. The default value of this parameter is set to `0`, because it is not safe to change it (anonymization might not be perfect if this parameter is set to anything but the default value).

<table><thead><tr><th width="499">Parameter</th><th align="right">Default value</th></tr></thead><tbody><tr><td><code>face-anonymization-gradient-start</code></td><td align="right">0.3</td></tr><tr><td><code>face-anonymization-gradient-stop</code></td><td align="right">0.0</td></tr><tr><td><code>license-plate-anonymization-gradient-start</code></td><td align="right">0.3</td></tr><tr><td><code>license-plate-anonymization-gradient-stop</code></td><td align="right">0.0</td></tr></tbody></table>

## Kernel size

Another tool that exists to improve anonymization and control its visual appearance is `--kernel-size-<anonymized_object>`. The kernel size determines the size of the neighborhood that the anonymized value is calculated from. The larger the kernel size, the more pixels will be included in the neighborhood, and the greater the blur/pixelate effect will be. A smaller kernel size will result in more preservation of details. The full list of kernel size parameters goes as follows:

* `--kernel-size-face x`
* `--kernel-size-person x`
* `--kernel-size-license-plate x`
* `--kernel-size-vehicle x`

Kernel size can be set up in either relative or absolute values. Normally, default absolute kernel size values are enough, however, in certain scenarios relative values might become handy. Relative values are in the range `0..1` and determine the kernel size for anonymized objects as relative to the object size. This can be useful in the following scenarios:

* Objects in the images are often either very small (distant) or very large (close). This setting guarantees that the anonymization will look similar on both types of objects.
* In videos, this setting is very effective to combat flickering of anonymized objects and therefore is enabled by default.

<table><thead><tr><th width="339.3333333333333">Parameter</th><th align="right">Default value image</th><th align="right">Default value video</th></tr></thead><tbody><tr><td><code>kernel-size-face</code></td><td align="right">0.35</td><td align="right">0.35</td></tr><tr><td><code>kernel-size-person</code></td><td align="right">91</td><td align="right">91</td></tr><tr><td><code>kernel-size-license-plate</code></td><td align="right">0.5</td><td align="right">0.5</td></tr><tr><td><code>kernel-size-vehicle</code></td><td align="right">61</td><td align="right">0.15</td></tr></tbody></table>


# Using CPU only

By default, Celantur Container requires a Nvidia GPU to offer the best performance. But in certain scenarios, access to GPUs might be limited or too expensive (e.g. cloud deployment).

By specifying the `--cpu-mode` parameter, only the CPU will be utilized to run Celantur Container.

```sh
bash celantur.sh --cpu-mode -a face -a license-plate --format whole
```


# Object Tracking

Object tracking in videos

Our solution features automatic object tracking in videos to ensure that moving objects are reliably detected and anonymised.

### Understanding Object Tracking

Object tracking is a computer vision technique that follows objects as they move across frames in a video. We use object tracking in conjunction with our object detection algorithm. The object detection model identifies objects of interest (such as faces or license plates) in each frame. Then, the object tracking algorithm tracks these objects across frames, ensuring they are consistently anonymized even if they temporarily disappear from view.

### Benefits of Object Tracking

* **Reduced Flickering:** Object tracking significantly reduces the occurrence of flickering detections, where an object is anonymized in one frame and then reappears unanonymized in the next. This improves the overall quality and consistency of the anonymized video.
* **Improved Accuracy:** By tracking objects across frames, our object tracking feature can help to correct errors in the object detection process. This leads to more accurate and reliable anonymization.

### How to Use Object Tracking in Celantur

Object tracking is enabled by default for **video anonymisation**. You can disable it using `--no-object-tracking` as a command-line argument in [Batch and Stream mode](/container/usage/batch-and-stream-mode) or `no-object-tracking`as query parameter in [REST API (v1) mode](/container/usage/rest-api-v1-mode).


# Benchmarks

Celantur Container benchmarks

## RTX 4090 24 GB, Intel Core i7-13700

Hardware specification:

* Intel Core i7-13700
* G.SKILL Flare X5 64 GB RAM (2x32)
* MSI MAG B760 TOMAHAWK WIFI DDR5 Mainboard, Intel
* Asus GeForce RTX 4090 24 GB
* 2 TB Samsung SSD 980 PRO, PCIe 4.0 NVMe M.2

{% hint style="info" %}
Processing time is end-to-end from loading to saving images, excluding software ramp-up time, e..g. loading model into memory.
{% endhint %}

### 1 - 8 MP Images (GPU)

Processing time of **100 images** using GPU.

<table><thead><tr><th width="141">Image Resolution</th><th width="212.66668701171875">Processing Time (100 images)</th><th width="197">Memory Utilization</th><th>Comparison with Celantur SDK</th></tr></thead><tbody><tr><td>1 MP (1 Tile)</td><td><strong>6 s</strong></td><td><p><strong>2.6 GB VRAM</strong></p><p><strong>4 GB RAM</strong></p></td><td>4 s<br>686 MB VRAM<br>&#x3C; 500 MB RAM</td></tr><tr><td>2 MP (1 Tile)</td><td><strong>11 s</strong></td><td><p><strong>2.7 GB VRAM</strong></p><p><strong>4.5 GB RAM</strong></p></td><td><p>4.6 s</p><p>686 MB VRAM</p><p>&#x3C;500 MB RAM</p></td></tr><tr><td>8 MP (2 Tiles)</td><td><strong>85 s</strong></td><td><p><strong>10 GB VRAM</strong></p><p><strong>5 GB RAM</strong></p></td><td><p>10s</p><p>686 MB VRAM</p><p>&#x3C;500 MB RAM</p></td></tr></tbody></table>

### Images (CPU)

Processing time of **100 images** using CPU only.

<table><thead><tr><th width="161">Image Resolution</th><th width="222">Processing Time (100 images)</th><th width="152">Memory Utilization</th><th>Comparison with Celantur SDK</th></tr></thead><tbody><tr><td>1 MP (1 Tile)</td><td><strong>34 s</strong></td><td><strong>&#x3C; 1.5GB RAM</strong></td><td><p>15 s</p><p>&#x3C; 800 MB RAM</p></td></tr><tr><td>2 MP (1 Tile)</td><td><strong>38 s</strong></td><td><strong>&#x3C; 1.5 GB RAM</strong></td><td><p>15 s</p><p>&#x3C; 900 MB RAM</p></td></tr><tr><td>8 MP (2 Tiles)</td><td><strong>195 s</strong></td><td><strong>&#x3C; 3 GB RAM</strong></td><td><p>30 s</p><p>&#x3C; 1.4 GB RAM</p></td></tr></tbody></table>

### 32 MP Images (GPU)

Processing time of **1 image** using GPU.

Using Celantur Container v25.04.2.

<table><thead><tr><th width="181">Image Resolution</th><th>Processing Time (1 image)</th><th>Memory Utilization</th></tr></thead><tbody><tr><td>32 MP (8000x4000)</td><td><strong>1.04 s</strong></td><td><p>up to <strong>11.8 GB VRAM</strong></p><p><strong>5 GB RAM</strong></p></td></tr></tbody></table>

{% code title="Command" overflow="wrap" %}

```bash
-a person -a face -a license-plate --format pano:8000
```

{% endcode %}

### 72 MP Images (GPU)

Processing time of **1 image** by **one instance** of Celantur Container using GPU.

Using Celantur Container v25.09.1.

<table><thead><tr><th width="181">Image Resolution</th><th>Processing Time (1 image)</th><th>Memory Utilization</th></tr></thead><tbody><tr><td>72 MP</td><td><strong>0.27 s</strong></td><td><p>up to <strong>4 GB VRAM</strong></p><p><strong>4.5 GB RAM</strong></p></td></tr></tbody></table>

Processing time and throughput with **8 instances of Celantur Container** using GPU.

Using Celantur Container v25.11.1.

<table><thead><tr><th width="181">Image Resolution</th><th>Processing Time per Image</th><th>Throughput</th></tr></thead><tbody><tr><td>72 MP</td><td><strong>0.13 s</strong></td><td>7.5 images / s</td></tr></tbody></table>

{% code title="Command" overflow="wrap" %}

```bash
for i in $(seq 1 8); do PROCESS_DIR=$HOME/test$i ./celantur.sh -a face -a license-plate --format '{"number":[4,1],"overlap":[300,0],"section":[0,1870,12288,4950]}' & ; done
```

{% endcode %}

### 91 MP Images (GPU)

Processing time of **1 image** (Mosaic X panorama) using GPU.

Using Celantur Container v25.04.2.

<table><thead><tr><th width="181">Image Resolution</th><th>Processing Time (1 image)</th><th>Memory Utilization</th></tr></thead><tbody><tr><td>91 MP (13504x6752)</td><td><strong>2.9 s</strong></td><td><p>up to <strong>15 GB VRAM</strong></p><p><strong>6 GB RAM</strong></p></td></tr></tbody></table>

{% code title="Command" overflow="wrap" %}

```bash
--model segmentatio-omnium -a face -a license-plate --license-plate-threshold 0.1 --face-threshold 0.1 -f '{"number":[5,1],"overlap":[400,0],"section":[0,2200,13504,5300]}'
```

{% endcode %}

### FullHD Video (GPU)

Processing time of **1 video** (GoPro/mp4) using GPU.

Using Celantur Container v25.11.1.

<table><thead><tr><th width="181">Video Resolution / Framerate</th><th>Processing Time</th><th>Video Duration</th></tr></thead><tbody><tr><td>FullHD / 30 fps</td><td>7 m</td><td>7 m</td></tr></tbody></table>

{% code title="Command" overflow="wrap" %}

```bash
--video --keep-bit-rate -a face -a license-plate
```

{% endcode %}


# Comparison

## Celantur vs. EgoBlur Gen 2

EgoBlur Gen 2 is an open-source AI model from Meta. Comparison conducted during July 2026.

### Setup <a href="#setup" id="setup"></a>

The EgoBlur repo got a little bit refactored which made the setup easier than Gen 1 and it now works without any error.

### Usage <a href="#usage" id="usage"></a>

With EgoBlur2 you can still **only anonymize faces and license plates** and **no whole vehicles and persons**. The clear focus of these models are with the Meta Glasses, since now you can set a specific set of cameras during inference for some finetuned confidence thresholds.

The demo script still only processes a single image at a time and custom logic is also required to read folders, tile large images, save metadata, etc.

### Results <a href="#results" id="results"></a>

#### Celantur Container 26.04.1 vs EgoBlur Gen 2 <a href="#celantur-container-26.04.1-and-egoblur2-celantur-gamma-july-2026" id="celantur-container-26.04.1-and-egoblur2-celantur-gamma-july-2026"></a>

Compared to the Celantur Container, EgoBlur Gen 2 shows a similar or slightly lower Recall for license-plates and a significantly lower one for heads. With a few exceptions, the Precision of the Celantur Container for heads is higher across all reference datasets. With a few exceptions, the Precision is also higher for license-plates.

\
The End-to-End processing times, including the whole start up, model loading, etc., are similar, although the container seems to be a little bit slower. This overhang becomes less the more images are processed. The processing times per image, including inference and anonymization, are significantly faster with the Celantur Container, especially for large images where tiling is necessary. In such cases the container is up to 3x faster than EgoBlur Gen 2. It has to be noted that EgoBlur Gen 2 got \~3x faster compared to the 1st Gen. version.

\
Even though EgoBlur Gen 2 needs to load two roughly 430MB models into VRAM, the VRAM usage during inference is a little bit lower, especially for large panorama images. The higher VRAM usage from the Container is probably caused by the additional segmentation masks that the Celantur model generates.

**Test system specification:** RTX 4090 24 GB, Intel Core i7-13700, 64 GB RAM (2x32)

| **Dataset**                       | **VRAM Consumption** Celantur Container | **VRAM Consumption** EgoBlur Gen 2 | **Total Processing Time** Celantur Container | **Total Processing Time** EgoBlur Gen 2 | **Processing Time per Image** Celantur Container **\[sec.]** | **Processing Time per Image** EgoBlur Gen &#x32;**\[sec.]** |
| --------------------------------- | --------------------------------------- | ---------------------------------- | -------------------------------------------- | --------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------- |
| Dashcam                           |                                         |                                    |                                              |                                         |                                                              |                                                             |
| <p><br>100 images x 1920x1080</p> | 1546                                    | 1796                               | 00: 00 : 13                                  | 00: 00 : 12                             | 0.043 ± 0.115                                                | 0.087 ± 0.112                                               |
| Dashcam                           |                                         |                                    |                                              |                                         |                                                              |                                                             |
| <p><br>50 images x 3840x2160</p>  | 3450                                    | 1730                               | 00 : 00 : 14                                 | 00 : 00 : 10                            | 0.096 ± 0.162                                                | 0.128 ± 0.158                                               |
| Indoor Mapping                    |                                         |                                    |                                              |                                         |                                                              |                                                             |
| <p><br>100 images x 3648x5472</p> | 1808                                    | 2680                               | 00 : 00 : 37                                 | 00 : 01 : 05                            | 0.242 ± 0.154                                                | 0.658 ± 0.199                                               |
| Drone/UAV                         |                                         |                                    |                                              |                                         |                                                              |                                                             |
| <p><br>50 images x 4032x3024</p>  | 1872                                    | 2168                               | 00 : 00 : 24                                 | 00 : 00 : 42                            | 0.215 ± 0.164                                                | 0.684 ± 0.264                                               |
| Mobile Mapping                    |                                         |                                    |                                              |                                         |                                                              |                                                             |
| <p><br>50 panos x 8000x4000</p>   | 2110                                    | 2022                               | 00 : 00 : 16                                 | 00 : 00 : 16                            | 0.213 ± 0.274                                                | 0.519 ± 0.405                                               |
| Mobile Mapping                    |                                         |                                    |                                              |                                         |                                                              |                                                             |
| <p><br>50 panos x 12288x6144</p>  | 2838                                    | 2494                               | 00 : 00 : 46                                 | 00 : 00 : 59                            | 0.287 ± 0.163                                                | 0.789 ± 0.275                                               |
| Mobile Mapping                    |                                         |                                    |                                              |                                         |                                                              |                                                             |
| <p><br>50 panos x 13504x6752</p>  | 4226                                    | 2590                               | 00 : 00 : 54                                 | 00 : 01 : 04                            | 0.314 ± 0.161                                                | 0.846 ± 0.217                                               |

### Conclusion <a href="#conclusion" id="conclusion"></a>

EgoBlur Gen 2, by default, is very limited in its capabilities and requires some coding proficiency to get the desired results. Some drawbacks include:

* **Limited functionality**\
  The default sample script only processes a single image at a time. The only output of the sample script is the anonymized version of the input image.\
  Basic functionality like image tiling for larger images, scanning folders for multiple images, saving metadata, customizing the appearence of the anonymization is all missing and must be self implemented.
* **Lackluster Results**\
  While the detection capabilities for license-plates are comparable to the Celantur Container, Heads are repeatedly not detected. Furthermore, EgoBlur2 produces significantly more false-positive detections than Celantur Container, reducing the overall quality of the end result.

While EgoBlur Gen 2 is considerable faster than the 1st generation model, it is still plagued by many of the same problems and it remains slower than Celantur Container.

## Celantur vs. EgoBlur Gen 1

EgoBlur is an open-source AI model from Meta. Comparison conducted during October 2025.

### Setup <a href="#setup" id="setup"></a>

The setup turned out to be surprisingly difficult. In the official repo they provide an `environment.yaml` file to create a new conda environment. This didn’t work at all on our servers. Constant problems with the specified versions of OpenCV, Numpy and torch. Only solution was to create an environment from scratch with Python's venv.

### Usage <a href="#usage" id="usage"></a>

With EgoBlur only faces and license plates can be anonymized, **no whole vehicles and persons**. Furthermore you can only process 1 image at a time with the provided sample script and need custom logic to: read folders, tile large images, save metadata, etc.

### Results <a href="#results" id="results"></a>

Compared to the Celantur Container, EgoBlur shows a similar Recall for license-plates but a lower one for Heads. The Precision of the Celantur Container across all tested datasets is significantly better.\
The End-to-End processing times, including the whole start up, model loading, etc., are similar, although the container seems to be a little bit slower. This is to be expected I guess since we have a lot more features and logic to handle.

The processing times per image, including inference and anonymization, are significantly faster with the Celantur Container. The VRAM usage for both solutions is quite similar.

**Test system specification:** RTX 4090 24 GB, Intel Core i7-13700, 64 GB RAM (2x32)

<table><thead><tr><th>Dataset</th><th>VRAM Consumption Celantur Container</th><th>VRAM Consumption EgoBlur</th><th>Celantur consumes x% less VRAM</th><th>Total Processing Time [HH : MM : SS]</th><th>Total Processing Time [HH : MM : SS]</th><th>Celantur x% faster</th><th>Processing Time per Image [sec.]</th><th>Processing Time per Image [sec.]</th><th data-hidden>Total Images</th><th data-hidden>Resolution</th></tr></thead><tbody><tr><td>Dashcam<br>100 images x 1920x1080</td><td>1.2</td><td>3.8</td><td>68%</td><td>00: 00 : 07</td><td>00: 00 : 20</td><td>65%</td><td>0.048 ± 0.132</td><td>0.164 ± 0.198</td><td>100</td><td>1920x1080</td></tr><tr><td>Dashcam<br>50 images x 3840x2160</td><td>2.7</td><td>11.2</td><td>76%</td><td>00 : 00 : 10</td><td>00 : 00 : 35</td><td>71%</td><td>0.113 ± 0.187</td><td>0.610 ± 0.250</td><td>50</td><td>3840x2160</td></tr><tr><td>Indoor Mapping<br>100 images x 3648x5472</td><td>1.4</td><td>7.9</td><td>82%</td><td>00 : 00 : 36</td><td>00 : 03 : 34</td><td>83%</td><td>0.280 ± 0.146</td><td>1.877 ± 0.279</td><td>100</td><td>3648x5472</td></tr><tr><td>Drone/UAV<br>50 images x 4032x3024</td><td>1.1</td><td>9.3</td><td>88%</td><td>00 : 00 : 21</td><td>00 : 01 : 31</td><td>77%</td><td>0.283 ± 0.182</td><td>1.544 ± 0.492</td><td>50</td><td>4032x3024</td></tr><tr><td>Mobile Mapping<br>50 panos x 8000x4000</td><td>1.4</td><td>7.7</td><td>82%</td><td>00 : 00 : 35</td><td>00 : 01 : 42</td><td>66%</td><td>0.534 ± 0.202</td><td>1.513 ± 0.382</td><td>50</td><td>8000x4000</td></tr><tr><td>Mobile Mapping<br>50 panos x 12288x6144</td><td>1.6</td><td>12.1</td><td>87%</td><td>00 : 00 : 45</td><td>00 : 03 : 19</td><td>77%</td><td>0.733 ± 0.210</td><td>3.049 ± 0.347</td><td>50</td><td>12288x6144</td></tr><tr><td>Mobile Mapping<br>50 panos x 13504x6752</td><td>2.0</td><td>12.8</td><td>84%</td><td>00 : 00 : 54</td><td>00 : 03 : 41</td><td>76%</td><td>0.924 ± 0.242</td><td>3.326 ± 0.358</td><td>50</td><td>13504x6752</td></tr></tbody></table>

### Conclusion <a href="#conclusion" id="conclusion"></a>

EgoBlur, by default, is very limited in its capabilities and requires software engineering proficiency to get the desired results. Some drawbacks include:

* **Limited functionality**\
  The default sample script only processes a single image at a time. The only output of the sample script is the anonymized version of the input image.\
  Basic functionality like image tiling for larger images, scanning folders for multiple images, saving metadata, customizing the appearance of the anonymization is all missing and must be self implemented.
* **Cumbersome Setup**\
  The setup of the environment to run EgoBlur also expects the user to know what a conda environment is and how to set it up. The provided environment.yaml file is not fail-proof however and to fix any issues one must again have the knowledge to debug the environment and code.
* **Lacklaster Results**\
  While the detection capabilities for license-plates are comparable to the Celantur Container, Heads are repeatedly not detected. Furthermore, **EgoBlur produces significantly more false-positive** detections than Celantur Container, reducing the overall quality of the end result.


# Release Notes

Discover the newest features and improvements of the latest Celantur Container versions.

{% hint style="success" %}
Read [how to update](/container/requirements-and-installation/updates) to the latest version of Celantur Container.
{% endhint %}

## 2026

### Version 26.04.2 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Released on April 29th, 2026.

* Improved model trained with additional indoor, outdoor and dashcam images.
* Improve garbage collection.
* FIX bug with webhook not working in REST API mode.
* FIX bug with sync request blocking async requests in REST API mode.

### Version 26.04.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Released on April 3rd, 2026.

* Upgrade software dependencies in Docker image to reduce vulnerabilities.

### Version 26.03.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Released on March 16th, 2026.

* Improve segmentation mask processing. User can remove disconnected parts (controllable via environmental variable).

### Version 26.02.2 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Released on February 24h, 2026.

* Improve EXIF metadata copying in JPEG data.
* Improve logging
  * for telemetry (if enabled)
  * for video processing (more verbose error message if post-processing fails)
* Manual garbage collection and GPU cache clearing to improve memory performance and reduce risks of memory overflow.
* FIX issue in REST API mode, where the DELETE request does not delete the metadata JSON of video files in the output folder within the container.
* FIX Issue in REST API mode, when processing a defect video, `status` is "done" instead of "failed".
* \[EXPERIMENTAL] Enable gathering of hardware utilisation metrics with `--monitor data.json`

### Version 26.02.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Released on February 4h, 2026.

* New scheme for [Segmentation Masks and Metadata](/container/usage/segmentation-masks-and-metadata#instance-segmentation).
* Adjust error handling in licensing verification.

### Version 26.01.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Released on January 29th, 2026.

* :exclamation: **Breaking change (batch and stream mode):** When using `--save-mask`, segmentation masks are saved with hyphenated suffixes (`image-name-bin-mask.png`, `image-name-ins-mask.png`) instead of underscore suffixes (`image-name_bin_mask.png`, `image-name_ins_mask.png`). Details: [Segmentation masks and metadata](/container/usage/segmentation-masks-and-metadata).
* Expose object tracking parameters as environmental variables.
* Customer can disable video post-processing, where audio and data streams from the input video are merged into the output video, with `--no-ffmpeg-merge` .
* Stream mode now also supports video processing.
* In batch and stream mode, customer can choose to process images and/or videos with `-t image` and `-t video`. Default is `-t image` without `-t video,` `--video` is alias for `-t video` without `-t image`.
* FIXED: Wrong color channels causes degraded detection performance.

**Known bugs**:

* <mark style="color:$info;">FIXED in v26.02.1: Overlapping instance segmentation masks mix up the colours of the instances.</mark>
* <mark style="color:$info;">FIXED in v26.02.2:</mark> <mark style="color:$info;">In REST API mode, the DELETE request does not delete the metadata JSON of video files in the output folder within the container.</mark>

## 2025 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

### Version 25.11.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Released on November 13th, 2025.

* Update of the Docker base image to Ubuntu 24.04 with Python 3.12

### Version 25.10.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Released on October 1st, 2025.

* Bugfix: Gradual blur now works for license plate blurring.
* Bugfix: `--face-anonymization-gradient-stop` now works as intended.
* Bugfix: Issue with datetime timezones in telemetry.
* Bugfix: `license` command works now as intended.
* Bugfix: In video processing, metadata JSON are now written in 500-frame chunks (500 frames per JSON file).

### Version 25.09.1 (preview) <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Released on September 8th, 2025.

**Attention**: This release is based on major rewrite of our code base. It contains some breaking changes.

#### Hardware support

* Support for NVIDIA Hooper and Blackwell architecture.
* Faster performance.
* Improve hardware utilisation (lower GPU memory consumption).

#### ML model updates

* `segmentatio-omnium` is now the default model!\
  The default thresholds for face and license-plate are now 0.2.
* :exclamation: Model `object-detection-v2` is **removed**, use `segmentatio-omnium` instead.
* CLI parameters `--model-segmentation` , `----model-license-plate` , `--model-keypoint` are deprecated.
* Model retrained.

#### Other improvements

* Improve anonymisation with smoother gradual blur.
* Instance segmentation masks (`--save-mask instance`) have more distinct colors.
* Stream mode (`--stream`) now also supports video processing!
* Fix bugs in TCP modes:
  * `--save-mask binary` now returns binary mask instead of blurred image.
  * `--debug` `--score` now also works in TCP modes.
* :exclamation: In Container API synchronous mode, a `POST` request is rejected, if an anonymisation process is ongoing.

#### Obsolete parameters

Following parameters can be removed without any change in behaviour.

* CLI parameter `--metrics` is removed.
* CLI parameter `--non-parallel` is removed.

#### :exclamation:Known bugs

* <mark style="color:$info;">\[FIXED in v25.10.1] Gradual blur does not work for license plate anonymisation.</mark>
* <mark style="color:$info;">\[FIXED in v25.10.1] CLI parameter</mark> <mark style="color:$info;">`--face-anonymization-gradient-stop`</mark> <mark style="color:$info;">does not work.</mark>
* <mark style="color:$info;">\[FIXED in v25.10.1]</mark> <mark style="color:$info;">`license`</mark> <mark style="color:$info;">subcommand does not work.</mark>
* <mark style="color:$info;">\[FIXED in v25.10.1] Issue with datetime timezone in telemetry.</mark>
* <mark style="color:$info;">\[FIXED in v26.02.2]</mark> <mark style="color:$info;">In Container API mode, when processing a defect video,</mark> <mark style="color:$info;">`status`</mark> <mark style="color:$info;">is "done" instead of "failed".</mark>
* <mark style="color:$info;">\[FIXED in v25.10.1] In video processing, metadata are not written in 500-frame chunks (500 frames per file) as it should be.</mark>
* <mark style="color:$info;">\[FIXED in v26.01.1] Wrong color channels causes degraded detection performance.</mark>

### Version 25.05.1 (hotfix) <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on May 19th, 2025

* Fix issue in Container API caused by processing corrupt video files.

### Version 25.04.2 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on April 23, 2025

* **Improved anonymization quality of** `segmentatio-omnium` **model:**\
  Images taken by UAVs / drones.

### Version 25.04.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on April 8, 2025

* **Improved anonymization quality of** `segmentatio-omnium` **model:**\
  High-resolution Mobile Mapping panoramas, Dashcam images (California/USA)

### Version 25.03.1 (hotfix)

Release on March 18, 2025

* Display file name of the video being processed in log
* Fixed: Graceful shutdown in Batch mode (ctrl+c)
* Fixed: Face blur appearance
* Fixed: error in video object tracking
* Fixed: Wrong parameter to --tcp-jpeg terminates the container but does not print out any log
* Fixed: Container API displays non-user-friendly error message if -i and -o parameters are not specified
* Fixed: In Container API, `GET /file/1/anonymised` after setting method to "detect" returns non-anonymized image

### Version 25.01.2 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on February 18, 2025

* Fixed issue with faulty tiling parameter
* Fixed tiling errors not being displayed
* Fixed `GET /v1/status` not responding if a non-sync request is running.
* Removed `--prioritize-nvenc` flag
* Ensure graceful shutdown on Ctrl-C in API mode.
* Removed `--object-tracking` flag from help (by default on, disable with `--no-object-tracking`).

### Version 25.01.1 (hotfix) <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on January 13, 2025

* Fixed bug that made the Container stop unexpectedly and without logging any errors.
* Minor improvements of `object-detection-v2` model.

## 2024 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

### Version 24.10.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on October 31, 2024

* **Improved overall detection quality of** `object-detection-v2` **model (with a focus on imagery from the US)**\
  Generally higher recall and precision over all tested use cases and scenarios.
* **Reduced memory usage**\
  Lower memory consumption for large images and panoramas due to optimized storage of segmentation masks.
* **Preserve IPTC metadata in anonymized images**\
  Copy over essential IPTC metadata from original to anonymized JPEG images.

### Version 24.08.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on August 20, 2024

* Improved logging, updated logging format and hid irrelevant log messages:
  * Logs are colored in STDOUT depending on the log level.
  * Log level can be set via `--log-level` parameter.
  * In REST API mode, the HTTP requests are not logged anymore.
* `object-detection-v2` model now also supports segmentation masks with `--save-mask`.
* <mark style="color:$info;">Known bug: The combination of</mark> <mark style="color:$info;">`--model object-detection-v2`</mark> <mark style="color:$info;">and</mark> <mark style="color:$info;">`--cpu-mode`</mark> <mark style="color:$info;">causes error.</mark>

### Version 24.05.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on June 17, 2024

* Remove "ghost" detections when object tracking is enabled for video anonymisation.
* Fix bug with NVIDIA driver caused by conflicting library versions.
* Software maintenance (refactoring) and dependency upgrades

### Version 24.04.1 (hotfix) <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on April 7, 2024

* Fix bug: 'color' output in metadata JSON is null instead of RGB triplet for `--save-mask all` and `--save-mask instance`.
* Fix bug: In API mode, response to `POST /v1/file` does not contain `anonymised_url`
* When API mode starts without `--save-mask` parameter, retrieving segmentation masks with `GET /file/{id}/binary-mask` or `GET /file/{id}/instance-mask` now causes 404 instead 500 error.
* Fix bug: In API mode, `DELETE /task/{id}` does not remove video metadata json files.

### Version 24.03.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on March 28, 2024

* Improved `object-detection-v2` model.
* Fixed bug with REST API query parameter naming: Dashes `-` are now interchangeable with underscores `_` in parameter names.
* XMP metadata are now cloned into output images: [Batch and Stream mode](/container/usage/batch-and-stream-mode#will-image-exif-and-xmp-metadata-be-carried-over-to-the-anonymized-image)
* The Docker container now starts by default as user with uid `1000` and gid `1000`.

### Version 24.02.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on Febuary 20, 2024

* Improve UX of Container API asynchronous processing.

### Version 24.01.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on Jan 18, 2024

* API mode now supports **asynchronous processing**.
* API mode now supports **webhooks**.
* Improved `object-detection-v2` model.
* In API mode, the `-i <input>` and `-o <output>` folders are used to temporary store the input and output data.

{% hint style="info" %}
If you are using API mode, **remove** the following two lines from`celantur.sh` to avoid an PermissionError:

`-v "${PROCESS_DIR}/input":"${DOCKER_HOME}/input"`

`-v "${PROCESS_DIR}/output":"${DOCKER_HOME}/output"`
{% endhint %}

* In API mode, the keys in JSON response to `POST /v1/file` now contain underscore instead of dashes.

  ```json
  {
    "id": "string",
    "content_type": "before: content-type",
    "anonymized_video": "before: anonymized-video",
    "metadata_url": "before: metadata-url"
  }
  ```
* Misc. bugfixes

## 2023

### Version 23.12.1 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on Dec 7, 2023

* Improved `object-detection-v2` model.
* Bugfix: Fetching video metadata as JSON returned no detections in certain cases.

*Known issue (Fixed in version 24.02.1): In REST API mode and using the* `object-detection-v2` *model, when submitting a video followed by an image an error occurs (500 HTTP response, "*&#x45;rror in ASGI Framework" in Container log)*. We'll address this issue with a hotfix or in the upcoming release.*

### Version 23.11.2 <a href="#draft-version-23.11.2" id="draft-version-23.11.2"></a>

Release on Nov 14, 2023 (Bugfixes)

* Bugfix: Container API CLI parameters are not overriden by POST query parameters.
* Bugfix: Video processing causes crash when video file has no metadata.

### Version 23.11.1 <a href="#draft-version-23.11.1" id="draft-version-23.11.1"></a>

Release on Nov 7, 2023

* General license plate detection improvements (reduction of false positives).
* The `object-detection-v2` model has been retrained on UK license plates.

### Version 23.10.2 <a href="#draft-version-23.10.2" id="draft-version-23.10.2"></a>

Release on Oct 3, 2023

* Integrated object tracking for video processing.
* Keep [video metadata](https://doc.celantur.com/container/usage/batch-and-stream-mode#is-my-video-metadata-carried-over-to-the-anonymized-video) (stream/track and container metadata) when anonymizing videos
* Create [video metadata](/container/usage/segmentation-masks-and-metadata#video-metadata) (frame-wise) as JSON of anonymized videos

### Version 23.09.2 <a href="#draft-version-23.09.1" id="draft-version-23.09.1"></a>

Released on October 03, 2023

* In Container REST API, the type of the attribute `id` in the response of `POST /file` changes from number to string.

### Version 23.09.1 <a href="#draft-version-23.09.1" id="draft-version-23.09.1"></a>

Released on Sep 12, 2023

* Minor internal changes.

### Version 23.08.2 <a href="#draft-version-23.08.2" id="draft-version-23.08.2"></a>

Released on Sep 5, 2023

* Integrate new video processing model.
* Refactoring of OpenCV dependencies for video processing.

### Version 23.08.1 <a href="#draft-version-23.08.1" id="draft-version-23.08.1"></a>

Released on Aug 23, 2023

* Minor internal changes

### Version 23.07.3 <a href="#draft-version-23.07.3" id="draft-version-23.07.3"></a>

Released on Aug 14, 2023

* Bugfix: Licensing did not work in some cases.

### Version 23.07.2 <a href="#draft-version-23.07.2" id="draft-version-23.07.2"></a>

Released on Jul 22, 2023

* Introduce functionality to limit container usage via license files.
* Misc. bug fixes.

### Version 23.07.1 <a href="#draft-version-23.07.1" id="draft-version-23.07.1"></a>

Released with 23.07.2

* Refactor memory allocation for multiprocessing.
* Refactor image data handling.
* Known issue: `--model object-detection` does not work with shared memory (`--use-shared-memory`)

### Version 23.06.2

Released: 2023-07-13

* Fixed: Wrong bounding boxes in metrics output.
* Fixed: Logging didn't write to main log.
* Fixed: Video processing didn't accept `--debug` `--score` parameters.
* Fixed: `--stream --overwrite` crashes when the output directory contained the file that is named the same as input file.
* Fixed: Misc. vulnerabilities in Celantur Container.
* Fixed: Video processing cannot write out video files if output folder does not exit.
* Minor bugfixes and quality of life improvements.

### Version 23.04.3

Released: 2023-04-30

* Minor bugfixes and quality of life improvements.

### Version 23.03.2

Released: 2023-03-31

* Video anonymization supports now existing inference threshold parameters, e.g. `--<object>-threshold`.
* Fixed: `--debug --score` parameters did not work properly.
* Fixed: blur function caused process to stop in certain edge cases.

### Version 23.02.1

Released: 2023-02-28

* Minor bugfixes and quality of life improvements.

### Version 23.01.2

Released: 2023-01-31

* Fixed: Segmentation and binary masks were blank.

## 2022

### Version 22.12.1

Released: 2022-12-31

* **Customizable Blurring**\
  The blurring effect can now be customized by setting gradient start and stop value, as well as the kernel size for specific objects. [Read how it works.](https://www.celantur.com/doc/beautify-blur/).
* Code refactoring and maintenance (anonymiser code).
* Fixed issue with garbage collection.

### Version 22.11.2

Released: 2022-11-30

* **Get segmentation masks in NumPy TCP mode**\
  By setting the `--save-mask` parameter, segmentation masks can now be returned by the Container (default are numpy arrays).
* Fixed: Celantur Container new logs to STDOUT instead of STDERR.

### Version 22.10.2

Released: 2022-11-03

* Code refactoring to improve performance for video processing (on GPU).
* Fixed: Binary masks contained vehicles and persons, even though only license plates were specified.

### Version 22.09.2

Released: 2022-09-30

* **File-wise detection thresholds**\
  Set individual detection thresholds per file by specifying `face-threshold`, `person-threshold`, `vehicle-threshold` and `license-plate-threshold` when using the [Container API](https://www.celantur.com/doc/container-api/) or [Batch Mode](https://www.celantur.com/doc/on-premise/usage/).
* Container API health endpoint (/status) is now non-blocking.
* Fixed: Automatic tiling.
* Fixed: When anonymising person and license-plate, persons are not anonymised.
* Updated celantur-core dependencies.

### Version 22.08.1

Released: 2022-08-31

* Code refactoring to improve software maintenance.

### Version 22.07.2

Released: 2022-07-31

* **PNG support for Container API**\
  PNG images can be ingested with the Container API.
* Several bug fixes and quality of life improvements.

### Version 22.06.8

Released: 2022-06-30

* **REST API**\
  You can now send and receive images from the container via a REST API. This makes integration into your data pipelines even easier and more convenient: [Celantur Container API Documentation](https://www.celantur.com/doc/container-api/)
* **Generate segmentation masks**\
  Create binary or instance segmentation masks for processed images. These mask files can be used for further image analysis and faster processing: [Generate segmentation masks with the Celantur container](https://www.celantur.com/doc/segmentation-masks/)
* **Up to 60% faster processing by generating only metadata and segmentation masks**\
  By selecting the new “detect” method (instead of e.g. “blur”), the container is running only the inference on images, skipping the anonymization. This results in faster processing times when only metadata or segmentation masks are required.
* **Size of Docker image reduced by 1 GiB**
* Several bug fixes and quality of life improvements.


# Getting Started

Getting started with Celantur Edge SDK.

## Documentation and Samples

Technical information: [Celantur SDK Library](https://www.celantur.com/sdk/doc/current/)

Samples: [SDKExample on GitHub](https://github.com/celantur/SDKExample).

## Get a Demo

{% hint style="info" %}
[Reach out to our team](https://www.celantur.com/contact/) to request a demo version.
{% endhint %}

## Anonymizing Panorama Images

Settings:

* ROI: 0.0, 0.2 x 1.0, 0.6
* Tiling: 5 x 1
* Tile Overlap 0.1 x 0.0

{% embed url="<https://youtu.be/EGf5Noyb6rk>" %}
Real-time blurring of a dashcam live stream with Celantur Edge SDK on an Nvidia Jetson.
{% endembed %}

## Features

<table><thead><tr><th width="239.33331298828125">Feature</th><th width="119.99993896484375">Category</th><th width="298.33343505859375">Description</th><th>Available since</th></tr></thead><tbody><tr><td>Bounding box blurring</td><td>Blurring</td><td>Blur license plates (rectangular shape) and faces (oval shape).</td><td>v1.0</td></tr><tr><td>Segmentation blurring</td><td>Blurring</td><td>Blur segmentation masks</td><td>v1.1</td></tr><tr><td>License plate and face</td><td>Detection</td><td></td><td>v1.0</td></tr><tr><td>Vehicle and person</td><td>Detection</td><td></td><td>v1.1</td></tr><tr><td>Setting detection thresholds</td><td>Detection</td><td>User can set detection threshold</td><td>v1.0</td></tr><tr><td>Custom tiling</td><td>Detection</td><td>Control how many tiles an image is split into before inference.</td><td>v1.0</td></tr><tr><td>Image blurring</td><td>Image processing</td><td>Blurred image as 3-channel matrices.</td><td>v1.0</td></tr><tr><td>Encode and decode JPEG images</td><td>Image processing</td><td>JPEG images can be loaded and blurred images can be saved as JPEG images.</td><td>v1.0</td></tr><tr><td>Conserve JPEG metdata</td><td>Image processing</td><td>JPEG metadata (XMP, EXIF) are copied over in the anonymised image.</td><td>v1.0</td></tr><tr><td>Detection as structured data</td><td>Detection</td><td>Detection metadata (type and position of bounding box) can be retrieved.</td><td>v1.0</td></tr><tr><td>TensorRT GPU inference</td><td>Inference</td><td>Inference on NVIDIA GPU.</td><td>v1.1</td></tr><tr><td>ONNX CPU inference</td><td>Inference</td><td>Inference on Intel and AMD processors.</td><td>v1.0</td></tr><tr><td>OpenVINO CPU inference</td><td>Inference</td><td>Inference on Intel (and AMD) processors.</td><td></td></tr><tr><td>Configure multithreading</td><td>Inference</td><td>Set number of threads for CPU processing.</td><td>v1.0</td></tr><tr><td>Object tracking</td><td>Video processing</td><td></td><td>v1.4</td></tr></tbody></table>


# Requirements and Installation


# Requirements

Software and hardware requirements to run Celantur Edge SDK.

## Hardware Requirements

* CPU: minimum 4 cores.
* Memory: recommended 8 GiB RAM.
* GPU \[optional]: NVIDIA GeForce GTX 1060 or newer.

## Software Requirement

* OS: Linux / [Ubuntu](https://ubuntu.com/download/desktop) 22.04 LTS
* Additional [libraries will be provided](/sdk/requirements-and-installation/installation) by Celantur.

## Licensing

You will be provided a **license file** which is required to run Celantur SDK.


# Installation

Installing Celantur SDK.

## Install prerequisites:

```bash
apt install -y \
    ffmpeg \
    libexif-dev \
    libprotobuf-dev \
    libopenexr25 \
    libgstreamer1.0-0 \
    libgstreamer-plugins-base1.0-0 \
    wget
```

## Install Celantur dependencies

Celantur will provide you links to Debian packages:

* Celantur SDK (`cpp-processing`)
* Boost
* OpenCV
* ONNX Runtime

Install them with:

```bash
apt install ./celantur-*.deb
```

### Optional: Install OpenVINO 2024

For compiling and running [OpenVINO models](https://docs.openvino.ai/2026/get-started/install-openvino.html?).

```bash
wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB && \
    apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB && \
    echo "deb https://apt.repos.intel.com/openvino/2024 ubuntu22 main" | tee /etc/apt/sources.list.d/intel-openvino-2024.list && \
    apt update && \
    apt install -y openvino && \
    rm GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB
```

### Optional: Install TensorRT 10

For compiling and running TensorRT (TRT) models (GPU inference with data in CPU memory as input and output), see [official NVIDIA installation guide](https://docs.nvidia.com/deeplearning/tensorrt/latest/installing-tensorrt/install-debian.html#installing-debian).

### Optional: Install CUDA 11.7

For running full inference on NVIDIA GPU (with data in GPU memory as input and output), [install CUDA 11.7](https://developer.nvidia.com/cuda-11-7-0-download-archive).

## Download the model

Celantur will provide you link to download the model.

## Test the installation

Try out the [SDK examples](https://github.com/celantur/SDKExample/).


# Usage

Celantur SDK guide for model compilation and inference

Check out the [SDK library reference](https://www.celantur.com/sdk/doc/current/) and [examples](https://github.com/celantur/SDKExample/).

<table><thead><tr><th width="113">Example</th><th>What it demonstrates</th></tr></thead><tbody><tr><td><a href="https://github.com/celantur/SDKExample/blob/main/onnx.cpp">onnx</a></td><td>Minimal CPU anonymisation with the ONNX inference engine, plus tuning inference settings such as thread count and optimisation level.</td></tr><tr><td><a href="https://github.com/celantur/SDKExample/blob/main/openvino.cpp">openvino</a></td><td>Compile and run a model with the OpenVINO CPU inference engine.</td></tr><tr><td><a href="https://github.com/celantur/SDKExample/blob/main/tensorrt.cpp">tensorrt</a></td><td>Compile and run a model on GPU with TensorRT, including precision and optimisation level.</td></tr><tr><td><a href="https://github.com/celantur/SDKExample/blob/main/cuda.cpp">cuda</a></td><td>Full GPU inference pipeline without copying image data back to the CPU.</td></tr><tr><td><a href="https://github.com/celantur/SDKExample/blob/main/tracking.cpp">tracking</a></td><td>Video processing with object tracking using a smaller model.</td></tr><tr><td><a href="https://github.com/celantur/SDKExample/blob/main/jpeg.cpp">jpeg</a></td><td>Full CPU workflow: JPEG decode/encode with EXIF preservation, detection visualisation, per-class counts, and metric serialisation.</td></tr></tbody></table>

## Workflow for model compilation <a href="#workflow-for-model-compilation" id="workflow-for-model-compilation"></a>

The default model is ONNX. You can transcompile the model to OpenVINO for better performance on Intel CPUs or TensorRT for better performance on NVIDIA GPUs.

For NVIDIA GPUs, you need to compile a new model for each type of [GPU architecture](https://www.nvidia.com/en-us/technologies/).<br>

1. Create instance of `ModelCompiler`
2. Get settings `InferenceEnginePluginCompileSettings` from `ModelCompiler.preload_model(model_path)`;
3. Optional: Adjust settings `InferenceEnginePluginCompileSettings`
4. Execute model compilation with `ModelCompiler.compile_mode()`

#### Example code for TensorRT

```cpp
#include "CelanturSDKInterface.h"
#include "CommonParameters.h"

// 1. Create instance of ModelCompiler
CelanturSDK::ModelCompilerParams compiler_params;
compiler_params.inference_plugin = "/usr/local/lib/libTensorRTRuntime.so";
CelanturSDK::ModelCompiler compiler("/path/to/license", compiler_params);

// 2. Get settings
celantur::InferenceEnginePluginCompileSettings settings = compiler.preload_model("/path/to/model.onnx.enc");

// 3. Adjust settings       
settings["precision"] = celantur::CompilePrecision::FP32;
settings["optimisation_level"] = celantur::OptimisationLevel::Low;

// 4. Compile model
compiler.compile_model(settings, model_path_compiled);
```

## Workflow for inference and blurring <a href="#workflow-for-inference-and-blurring" id="workflow-for-inference-and-blurring"></a>

### Initialise process engine <a href="#initialise-process-engine" id="initialise-process-engine"></a>

1. Create instance of `Processor` using the model.
2. Get `InferenceEnginePluginSettings` from `Processor.get_inference_settings()`
3. Optional: Adjust inference settings.
4. Load model with your adjusted settings.

#### Example Code

```cpp
#include "CelanturSDKInterface.h"
#include "CommonParameters.h"

// 1. Create instance of Processor 
celantur::ProcessorParams params;
//    If you use TensorRT
params.inference_plugin = "/usr/local/lib/libTensorRTRuntime.so";
params.swapRB = true;
CelanturSDK::Processor processor(params, "/path/to/license");

// 2. Get settings.
celantur::InferenceEnginePluginSettings settings = processor.get_inference_settings(model_path_compiled);

// 4. Load the compiled inference model.
processor.load_inference_model(settings);
```

### Run inference and blurring <a href="#run-inference-and-blurring" id="run-inference-and-blurring"></a>

5. Run inference with `Processor.process()`
6. Get anonymised image with `Processor.get_result()`
7. Get detections with `Processor.get_detections()` (necessary step to remove item from queue).

#### Example Code

```cpp
#include "CelanturSDKInterface.h"
#include "CelanturDetection.h"
#include <opencv2/opencv.hpp>

// Load image
cv::Mat image = cv::imread("/path/to/original/image");

// 5. Run inference
processor.process(image);

// 6. Get anonymised image
cv::Mat out = processor.get_result();

// 7. Get detections. Necessary to free up the memory.
processor.get_detections();

// Save the image
cv::imwrite("/path/to/anonymised/image", out);
```


# Integration

Performance and integration considerations to integrate the Celantur SDK effectively.

## Pipeline Efficiency: Encoding/Decoding

To achieve real-time throughput, minimizing overhead is essential.

### **Avoid Redundant Encoding/Decoding**

The SDK interface expects a `cv::Mat` of individual frames. Integrating directly at this level avoids the overhead of repeated image encoding/decoding, which is critical for maintaining performance.

### Identify Bottlenecks

* Decoding/Encoding: Becomes a significant bottleneck with very large images (e.g., 70+ MP).
* Detection: Often the primary bottleneck for small to medium resolution images.
* Blurring: Generally the fastest stage of the pipeline.

### Recommendations

If the system is feeding the SDK fast enough (e.g., via optimized decoding like turbojpeg), it is possible to reach 100% GPU utilization with a single processor.

## CPU vs. GPU Performance (TensorRT/OpenVINO)

The SDK supports diverse deployment environments, offering specific performance pathways.

### GPU (TensorRT) Optimization

* TensorRT requires a hardware-specific engine file (`.plan`). This process is dependent on the specific GPU type, driver version, and TensorRT version.
* Performance depends on input tensor profiles (e.g., fixed vs. dynamic input sizes). Optimizing for fixed input sizes or well-defined profiles typically yields better performance than dynamic ranges.
* GPU memory usage may ramp up until it reaches a stable ceiling; this ceiling is generally determined by the maximum input resolution processed.

### CPU (OpenVINO/ONNX)

* CPU inference is available via OpenVINO or ONNX and serves as a robust alternative where GPU acceleration is not present or feasible.
* Scaling CPU performance often requires external parallelism. Handling multiple video feeds simultaneously is recommended for maximizing 24-core CPU utilization.

## Scaling Options

Strategic scaling ensures efficient use of infrastructure without unnecessary overhead.

### Single Processor vs. Multiple Pods

If one processor can successfully utilize 100% of the assigned hardware resources (CPU/GPU) when fed images fast enough, deploying multiple pods/containers on the same machine often provides no performance improvement.

### Horizontal Scaling

* For video processing, implement external parallelism by running multiple concurrent video feeds through the SDK.
* Horizontal scaling (multiple containers/nodes) is effective, but it is advised to monitor whether the input feeding stage (decoding) is keeping pace with the detection stage to prevent under-utilization.

## Model Selection & Tuning

* Model Variants: Models are provided in various profiles (default, small) and optimized for different hardware targets (e.g., FP32). Selecting the right model size involves balancing accuracy requirements with the hardware resource ceiling.
* Detection Thresholds: Users can set detection thresholds to control the sensitivity of the model. High thresholds may miss objects, while low thresholds can lead to false positives (artifacts).
* Continuous Improvement: In large-scale projects, performance can be optimized by testing against reference datasets. Providing proprietary imagery for model training can significantly reduce false negatives.

## Integration Architecture

### Selective Redaction

The SDK allows filtering detections (based on bounding boxes or object types) before the blurring stage, enabling workflows where specific objects (e.g., one person in a frame) can be kept visible while others are anonymized, or detections from 3rd party sources can be ingested.


# Architecture

### Overview

The main class is `CelanturSDK::Processor`. It provides the interface to the anonymisation library.

To create the instance of this class one needs:

1. `ProcessorParams` class with `inference_plugin` field instantiated.
2. `license_path` variable that points to the valid instance of the license.

After creating the processor, you need to load an model and use following functions to perform anonymisation:

1. `process` to post a new image to processing. The function is non-blocking and returns control immediately after posting the image to the processing queue.
2. `get_result` to get the next anonymised image from the queue.
3. `get_detections` to get the list of detections that were detected. One can use them e.g. to debug the results, display detections or create metadata JSON similar to [Container](/container/getting-started).

### Modules

You need two CMake modules to use SDK. First is `CppProcessing::CelanturSDK` that consists of the general interfaces to the SDK and is the entry point for interaction with it. Another one is `CppProcessing::common-module` , which consists of multiple definitions, classes and structures.

Other shared objects do not provide include files because they are transient dependencies of `CelanturSDK` .

### Plugins

Different inference plugins require different dependencies installed on the target machine. For example, `libONNXInference.so` depends on [ONNX](https://onnx.ai/) to run the detection on CPU. `libTensorRTRuntime.so` depends on NVIDIA's CUDA libraries to provide detections on GPU. To avoid having hard dependencies to these libraries, we use the plugin system where the dependencies are encapsulated in the plugin that is being loaded at runtime. You need to load at least one inference engine plugin for the SDK to work, which is covered in <https://github.com/celantur/SDKExample/>.


# Benchmarks

Celantur Edge SDK benchmarks

## RTX 4090 24 GB, AMD Ryzen 9 7900X

Hardware specification:

* AMD Ryzen 9 7900X 12-Core Processor
* G.SKILL Flare X5 64 GB RAM (2x32)
* MSI MAG B760 TOMAHAWK WIFI DDR5 Mainboard, Intel
* Asus GeForce RTX 4090 24 GB
* 2 TB Samsung SSD 980 PRO, PCIe 4.0 NVMe M.2

### Images (GPU, TensorRT)

* Measured with Celantur SDK v1.5.1.
* Processing time of 100 images using GPU.
* One SDK process running (higher throuput by parallelization possible).
* Includes software ramp-up time (end-to-end).

{% tabs %}
{% tab title="TensorRT (1280)" %}

<table><thead><tr><th width="178">Image Resolution (Tiling)</th><th width="127">E2E Throughput (imgs/s)</th><th width="128">Processing Time (100 images)</th><th>VRAM</th><th>RAM</th></tr></thead><tbody><tr><td>1 MP (1 Tile)</td><td>36</td><td>2.8 s</td><td>682 MB</td><td>490 MB</td></tr><tr><td>2 MP (1 Tile)</td><td>34</td><td>3 s</td><td>682 MB</td><td>490 MB</td></tr><tr><td>8 MP (2 Tiles)</td><td>11</td><td>9.1 s</td><td>682 MB</td><td>490 MB</td></tr><tr><td>72 MP (4 Tiles)</td><td>8.8</td><td>11.3 s</td><td>682 MB</td><td>655 MB</td></tr></tbody></table>
{% endtab %}

{% tab title="TensorRT (640)" %}

<table><thead><tr><th width="173">Image Resolution (Tiling)</th><th width="130">E2E Throughput (imgs/s)</th><th width="124">Processing Time (100 images)</th><th>VRAM</th><th>RAM</th></tr></thead><tbody><tr><td>1 MP (1 Tile)</td><td>121</td><td>0.83 s</td><td>554 MB</td><td>484 MB</td></tr><tr><td>2 MP (1 Tile)</td><td>101</td><td>0.99 s</td><td>554 MB</td><td>484 MB</td></tr><tr><td>8 MP (2 Tiles)</td><td>17</td><td>5.88 s</td><td>554 MB</td><td>484 MB</td></tr><tr><td>72 MP (4 Tiles)</td><td>10</td><td>10 s</td><td>554 MB</td><td>662 MB</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

### Images (CPU Mode)

* Measured with Celantur Edge SDK v1.5.1.
* Processing time of 100 images using CPU (OpenVINO).
* One SDK process running (higher throuput by parallelization possible).
* Includes software ramp-up time (end-to-end).

{% tabs %}
{% tab title="OpenVINO (1280)" %}

<table><thead><tr><th width="173">Image Resolution (Tiling)</th><th width="130">E2E Throughput (imgs/s)</th><th width="124">Processing Time (100 images)</th><th>CPU Util.</th><th>RAM</th></tr></thead><tbody><tr><td>1 MP (1 Tile)</td><td>7</td><td>14.29 s</td><td>86%</td><td>670 MB</td></tr><tr><td>2 MP (1 Tile)</td><td>7</td><td>14.29 s</td><td>86%</td><td>670 MB</td></tr><tr><td>8 MP (2 Tiles)</td><td>3</td><td>33.33 s</td><td>75%</td><td>670 MB</td></tr><tr><td>72 MP (4 Tiles)</td><td>1.65</td><td>60.61 s</td><td>57%</td><td>878 MB</td></tr></tbody></table>
{% endtab %}

{% tab title="OpenVINO (640)" %}

<table><thead><tr><th width="173">Image Resolution (Tiling)</th><th width="130">E2E Throughput (imgs/s)</th><th width="124">Processing Time (100 images)</th><th>CPU Util.</th><th>RAM</th></tr></thead><tbody><tr><td>1 MP (1 Tile)</td><td>27</td><td>3.7 s</td><td>81%</td><td>655 MB</td></tr><tr><td>2 MP (1 Tile)</td><td>24</td><td>4.17 s</td><td>68%</td><td>655 MB</td></tr><tr><td>8 MP (2 Tiles)</td><td>8</td><td>12.5 s</td><td>56%</td><td>655 MB</td></tr><tr><td>72 MP (4 Tiles)</td><td>5</td><td>20 s</td><td>31%</td><td>673 MB</td></tr></tbody></table>
{% endtab %}

{% tab title="ONNX (1280)" %}

<table><thead><tr><th width="173">Image Resolution (Tiling)</th><th width="130">E2E Throughput (imgs/s)</th><th width="124">Processing Time (100 images)</th><th>CPU Util.</th><th>RAM</th></tr></thead><tbody><tr><td>1 MP (1 Tile)</td><td>1.6</td><td>62 s</td><td>96%</td><td>1,4 GB</td></tr><tr><td>2 MP (1 Tile)</td><td>1.5</td><td>66 s</td><td>95%</td><td>1,3 GB</td></tr><tr><td>8 MP (2 Tiles)</td><td>0.75</td><td>133 s</td><td>92%</td><td>1,5 GB</td></tr><tr><td>72 MP (4 Tiles)</td><td>0.4</td><td>250 s</td><td>84%</td><td>1,7 GB</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

## Nvidia Jetson AGX Orin Developer Kit

### Images

Measured with Celantur Edge SDK v1.0.0.

Processing time of 100 images on Nvidia Jetson AGX Orin Developer Kit. Includes software ramp-up time (end-to-end).

<table><thead><tr><th width="217">Image Resolution / Tiling</th><th width="220">Processing Time (100 images)</th><th>Memory Utilization</th></tr></thead><tbody><tr><td>1 MP (1 Tile)</td><td>3.3 s</td><td>686 MB VRAM, &#x3C; 500 MB RAM</td></tr><tr><td>2 MP (1 Tile)</td><td>3.3 s</td><td>686 MB VRAM, &#x3C; 500 MB RAM</td></tr><tr><td>8 MP (2 Tiles)</td><td>7.6 s</td><td>686 MB VRAM, &#x3C; 500 MB RAM</td></tr></tbody></table>


# Troubleshooting

### Memory management

Too many images in the processing queue might cause out-of-memory error and terminate the SDK without error. Calling `get_result` will remove the image from the queue and thus reduce the memory consumption.

### Multiprocessing

In certain cases, e.g. using Cloud instances, the machine might become unresponsive, if more compute resources are used than specified. Each of [Architecture](/sdk/architecture#plugins) have their own way to configure multiprocessing.

For ONNX CPU plugin, you can [set the number of intra and outer threads](https://github.com/celantur/SDKExample/blob/main/inference_tinkering.cpp).


# Release Notes

Release notes for Celantur SDK / Edge.

## 2026

### Version 1.5.1

Release on June 3rd, 2026.

* **Full GPU inference:** Use data in GPU memory as input and output for inference instead of copying from CPU memory. See [example](https://github.com/celantur/SDKExample/blob/main/gpu_inference.cpp).
* Run models with different input sizes. A **smaller, faster model** (with 640x640 input size) is now available upon request.
* **Improved default model** (segmentatio-omnium v10) trained with additional indoor, outdoor and dashcam images.

#### Dependencies

Same as for [#version-1.1.0](#version-1.1.0 "mention").

### Version 1.4.0

Release on March 19th, 2026.

* Add object tracking.
* Separate detection from blurring. See [example](https://github.com/celantur/SDKExample/blob/v1.4.0/detect.cpp).

#### Dependencies

Same as for [#version-1.1.0](#version-1.1.0 "mention").

### Version 1.3.0

Released on January 27th, 2026.

* Remove dependency on protobuf.
* Available with new model (segmentatio-omnium v8).

#### Dependencies

Same as for [#version-1.1.0](#version-1.1.0 "mention").

## 2025

### Version 1.2.0

Released on October 21st, 2025.

* Beautify blur for bounding boxes.
* SKD supports smaller models.
* TensorRT support.
* Fix bug where tiling and segmentation mask creation crashes the application.

#### Dependencies

Same as for [#version-1.1.0](#version-1.1.0 "mention")

### Version 1.1.0

First public release of Celantur SKD on July 18th, 2025.

* C++ library.
* Inference with ONNX and OpenVINO.
* Blurring of faces, license plates, persons and vehicles.
* Blurring using segmentation mask or bounding boxes.
* Detection metadata as structured data or JSON string.
* Custom tiling.
* Setting detection thresholds.
* Read and save JPEG images.
* Multithreading.
* Video processing plugin.
  * H.254 en- and decoding.
* Deliverable as Docker image or Debian libraries.

#### Dependencies

* Boost v1.84.0
* ONNX v1.20.1
* OpenCV v4.7.0
* TensorRT v10.0.1.6
* Optional: libjpeg-turbo v3.1.0


# Getting Started

How to get started with Celantur Cloud API

## Overview

Celantur Cloud API lets you **anonymize images fully automated with simple REST API calls.**

Read the [concept](/cloud-api/concept) and [API endpoints](/cloud-api/api-endpoints) page for a technical deep dive.

**API URL:** `https://api.celantur.com/v2/`

## Access and Authorization

Sign up to app.celantur.com, and [use these credentials to access the Cloud API](/cloud-api/authorization).

## Send Requests

Implement [API endpoints](/cloud-api/api-endpoints), or use our [ready-to-use Python script](/cloud-api/examples#ready-to-use-sample-script).


# Concept

Understanding the concepts behind Celantur Cloud API

## Introduction

The Celantur Cloud API is a REST API and provides a secure, scalable and efficient way to anonymize images while preserving data privacy. This service allows users to protect personal information within images by blurring or obfuscating identifiable objects such as faces, persons, license plates and vehicles. By leveraging this API, developers can seamlessly integrate image anonymization into their applications or workflows.

The **service is asynchronous**, therefore it allows users to submit requests (tasks) that are processed in the background, enabling non-blocking operations. Users can check the status of tasks or retrieve results later, enhancing efficiency and responsiveness in handling time-consuming workloads. Uploaded images might take a few seconds to process.

<figure><img src="/files/BCDx7qVn1YVa2JcLAO3p" alt=""><figcaption><p>HTTPS workflow diagram of Celantur Cloud API v2</p></figcaption></figure>

## Entities

* **Task**: Represents the asynchronous image anonymization process on the server side.
* **Original image**: An image containing personal data which needs to be anonymized.
* **Anonymized image**: An image with personal data anonymized.
* **Metadata/Detections**: JSON representation of detected personal information on the image.
* **Binary segmentation mask**: The binary segmentation mask for the provided image.
* I**nstance segmentation mask**: The instance segmentation mask for the provided image.
* **Upload URL**: A pre-signed URL the original image is being uploaded to, in order to start the anonymization. The upload URL expires after 3600 seconds (60 minutes). A new task needs to be generated if the upload URL has expired.
* **Anonymized URL**: A pre-signed URL the anonymized image can be downloaded from. The URL is re-generated every time a request is sent to the GET v2/task and GET v2/task/{id}/status endpoints. The URL expires after 14400 seconds (4 hours). The expiration duration is reset when the URL is re-generated.
* **Binary segmentation mask URL**: A pre-signed URL the binary segmentation mask can be downloaded from. The URL expires after 14400 seconds (4 hours). The expiration duration is reset when the URL is re-generated.
* **Instance segmentation mask URL**: A pre-signed URL the instance segmentation mask can be downloaded from. The URL expires after 14400 seconds (4 hours). The expiration duration is reset when the URL is re-generated.

## Workflow

### 1. Authorization

To access the Celantur Cloud API, users must first authorize themselves by providing a username and password. This step ensures that only authorized users can utilize the service and keep data secure. Use your existing account credentials for <https://app.celantur.com>, or create a new account.

Endpoint: [API Endpoints](/cloud-api/api-endpoints#sign-in-authorization)

### 2. Creating a Task

After successful authentication, users can initiate the anonymization process by creating a task through the POST /v2/task endpoint. A task defines the specific image anonymization requirements, including the areas to be anonymized and the desired anonymization thresholds. The API response provides the task’s configuration in JSON, including a format unique **task ID** and an **upload URL** to which the image has to be uploaded to, in order to start the anonymization task.

* Endpoint: [API Endpoints](/cloud-api/api-endpoints#create-anonymization-task)

### 3. Uploading the Image

With the task ID and upload URL obtained in the previous step, the original image can now be uploaded to the API. Users can transfer their images securely to the provided upload URL with a **PUT request** and content-type `image/jpeg` or `image/png` . Once the upload is complete, the anonymization task commences asynchronously. If the file uploaded to the `upload_url` is not of the proper content-type the the task status will be set to `failed` along with the failure cause `CONTENT_TYPE_ERROR`

### 4. Checking Task Status

During the anonymization task, users can check the status of their task by querying the /task/id/status endpoint. The API will return information about the task's status, indicating whether it is “new”, “queued”, “processing”, “done” or “failed”.

* Endpoint: [API Endpoints](/cloud-api/api-endpoints#get-task-status)
* Alternatively, [Webhooks](/cloud-api/webhooks) can be used to be notified when a task has been finished.

### 5. Downloading Anonymized Image

Once the task is finished, users can download the anonymized image from the task's **anonymized URL**. This URL is pointing to an AWS S3 bucket where the images are stored, ensuring secure and reliable access to the anonymized image. The S3 bucket employs strong encryption mechanisms to safeguard the confidentiality and integrity of the anonymized data.

### 6. Downloading metadata and segmentation masks

Once the task is finished, users can also download the metadata and segmentation masks. Detections are created by default. Creation of segmentation masks need to be activated during the initial creation of the task [API Endpoints](/cloud-api/api-endpoints#create-anonymization-task).

* Endpoint: [API Endpoints](/cloud-api/api-endpoints#get-task-metadata)

## Task status

A task has one of multiple stati:

* “new”: The task has been created and persisted in the database.
* “queued”: The task has been put in the queue and is waiting to be processed.
* “processing”: The task is being processed.
* “done”: The task has been successfully done.
* “deleted”: All files and detections of the task were deleted.
* “failed”: The task failed. A “failure\_cause” property will be added to the response body of [GET v2/task/id](https://docs.google.com/document/d/1RLja9nrtc1lBNTdrCcbWmIL_u-O4XzkDlD5YzG6ytH0/edit?pli=1#heading=h.3se7prv71a5n) and [GET /task/id/status](https://docs.google.com/document/d/1RLja9nrtc1lBNTdrCcbWmIL_u-O4XzkDlD5YzG6ytH0/edit?pli=1#heading=h.vt20aek6oa6z) with the following values:
* * IMAGE\_DEFECT: The uploaded file is corrupt and can not be read. Please check if the file is valid.
  * TASK\_FILE\_DOESNT\_EXIST: The uploaded file was not uploaded successfully.
  * INTERNAL\_ERROR: An internal error occurred. Please get in touch with Celantur.
  * CONTENT\_TYPE\_ERROR: The uploaded file has the wrong content-type. In this case uploaded file will automatically be deleted.
  * PARAMETER\_ERROR\_FORMAT: The format entered for image is wrong for image size. Please check the format for the given image size.

## Data retention

All the files are retained for **five days after task creation** on our Celanter servers and then permanently deleted.

## FAQ

* **My upload URL expired, what can I do?**
  * A new task needs to be generated if the upload URL has expired.
* **My anonymized URL (for downloading the anonymized image) expired, what can I do?**
  * The URL is re-generated every time a request is sent to the GET v2/task and GET v2/task/{id}/status endpoints.
* **How do I find out what went wrong if the task status is “failed”?**
  * Please contact Celantur and tell us the task ID.


# Authorization

Authenticating with Celantur Cloud API

Celantur Cloud API is only usable when a user is authenticated. 🔒

Files are assigned to the user who has uploaded uploaded them. Other users can't access your files.

## How to get your authorization token

1. Create a new account or log in to app.celantur.com.
2. Use your app.celantur.com credentials with the [API Endpoints](/cloud-api/api-endpoints#sign-in-authorization) API endpoint to receive your authorization token.
3. Use the authorization token for interacting with the [API Endpoints](/cloud-api/api-endpoints)

```python
import requests

def main():    
  credentials = {'username': 'xxx', 'password': 'xxx'}
  response = requests.post(
    'https://api.celantur.com/v2/signin/', 
    json=credentials, 
    headers={'Content-Type':'application/json'}
  )
  auth_token = response.json()['AuthenticationResult']['AccessToken']

  status = requests.get(
    'https://api.celantur.com/v1/file/' + file_id + '/status', 
    headers={'Authorization': auth_token}
  )  
```

{% hint style="info" %}
**Access token support** will be available soon.
{% endhint %}


# Examples

Examples to use Celantur Cloud API v2

## Ready-to-use sample script

Get started by using the linked sample script.

<https://github.com/celantur/celantur-examples/blob/main/cloud-api/cloud-api-v2-client.py>

{% code title="Usage" overflow="wrap" %}

```bash
cloud-api-v2-client.py -i input-folder -o output-folder -u "username" -p "password" -c configuration.json
```

{% endcode %}

Tasks are configured via properties in the `configuration.json` file.\
For reference, see [API Endpoints](/cloud-api/api-endpoints#create-anonymization-task).

{% code title="configuration.json" %}

```json
{
    "anonymization_method": "blur",
    "face": true,
    "license-plate": true
}
```

{% endcode %}


# API Endpoints

Celantur Cloud API v2 endpoints

## Overview

**API URL:**

```
https://api.celantur.com/v2/
```

{% hint style="info" %}
Celantur Cloud API supports only images at the moment. Support for videos will be added soon.
{% endhint %}

## Create anonymization task

<mark style="color:green;">`POST`</mark> `https://api.celantur.com/v2/task`

Creates a task for anonymizing images.

Uploading an image to the `upload_url` starts the anonymization process. If the file uploaded to the `upload_url` is not the content type `image/jpeg` or `image/png` the task status will be set to `failed` along with the failure cause `CONTENT_TYPE_ERROR`

Required parameters for a task are `anonymization_method` and either face, person, license\_plate or vehicle.

#### Headers

| Name                                            | Type   | Description         |
| ----------------------------------------------- | ------ | ------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Authorization token |

#### Request Body

| Name                                                    | Type    | Description                                                                                                                                                                                                                                                                                                                          |
| ------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| anonymization\_method<mark style="color:red;">\*</mark> | String  | <p>Specifies anonymization method:</p><p><code>blur</code>, <code>pixelate</code>, <code>blacken</code></p>                                                                                                                                                                                                                          |
| face                                                    | Boolean | Specifies whether faces should be anonymized/detected.                                                                                                                                                                                                                                                                               |
| license-plate                                           | Boolean | Specifies whether license plates should be anonymized/detected.                                                                                                                                                                                                                                                                      |
| person                                                  | Boolean | Specifies whether persons should be anonymized/detected.                                                                                                                                                                                                                                                                             |
| vehicle                                                 | Boolean | Specifies whether vehicles should be anonymized/detected.                                                                                                                                                                                                                                                                            |
| debug                                                   | Boolean | <p>Print bounding boxes and segmentation masks of detected objects on the image.</p><p>Default: <code>false</code></p>                                                                                                                                                                                                               |
| score                                                   | Boolean | Print the detection scores of objects on the image. Works only if `debug` is `true`                                                                                                                                                                                                                                                  |
| format                                                  | String  | <p>Specifies how the input image is to be tiled. See <a data-mention href="/pages/I7oMH2TYkzRNbCRjwcOq#format-tiling">/pages/I7oMH2TYkzRNbCRjwcOq#format-tiling</a> for more information.<br>Pass pre-defined tiling as string, e.g. <code>"pano:8000"</code>, and custom tiling as object, e.g. <code>{"number: \[2, 2]}</code></p> |
| bbox                                                    | Boolean | Anonymize bounding boxes of objects (instead of segmentation).                                                                                                                                                                                                                                                                       |
| ignores                                                 | String  | <p>Specifies pixel coordinates of areas on the image in which no anonymization will be applied (as JSON).</p><p>Example:</p><p><code>\[{"topLeftX":182, "topLeftY":154,</code></p><p><code>"width":2000,</code></p><p><code>"height":2000}]</code></p>                                                                               |
| webhook                                                 | String  | <p>A webhook URL to which a POST request is sent to after successful processing.</p><p>More details here: <a data-mention href="/pages/0DGfEHu0aPCWIkfM0MxI">/pages/0DGfEHu0aPCWIkfM0MxI</a></p>                                                                                                                                     |
| start\_on                                               | String  | <p>Specifies whether the anonymization process of this task should start when a file has been uploaded (<code>upload</code>), or a request has been sent (<code>start\_request</code>) to POST v2/task/{id}/start.</p><p>Example:</p><p><code>start\_on: "start\_request"</code></p><p>Default: <code>upload</code></p>              |
| binary\_segmentation\_mask                              | Boolean | Specifies whether a binary segmentation mask should be generated for the provided file.                                                                                                                                                                                                                                              |
| instance\_segmentation\_mask                            | Boolean | Specifies whether an instance segmentation mask should be generated for the provided file.                                                                                                                                                                                                                                           |
| mask-scale                                              | Number  | <p>Specifies the ratio at which the mask file will be scaled down, range between <code>0 .. 100</code>.</p><p>Default: <code>100</code></p>                                                                                                                                                                                          |
| quality                                                 | Number  | <p>Specifies image quality of anonymized images in JPEG format: <code>0 .. 100</code></p><p>Default: <code>90</code></p>                                                                                                                                                                                                             |
| compress-level                                          | Number  | <p>Specifies image compression level of anonymized images in PNG format.</p><p>Default: <code>5</code></p>                                                                                                                                                                                                                           |
| kernel-size-face                                        | Number  | <p>Specifies the kernel size for face blurring. See <a data-mention href="/pages/kNLnfXcN7zFLsuxgsFe3">/pages/kNLnfXcN7zFLsuxgsFe3</a></p><p>Default: <code>0.35</code></p>                                                                                                                                                          |
| kernel-size-person                                      | Number  | <p>Specifies the kernel size for person blurring. See <a data-mention href="/pages/kNLnfXcN7zFLsuxgsFe3">/pages/kNLnfXcN7zFLsuxgsFe3</a></p><p>Default: <code>95</code></p>                                                                                                                                                          |
| kernel-size-license-plate                               | Number  | <p>Specifies the kernel size for license plate blurring. See <a data-mention href="/pages/kNLnfXcN7zFLsuxgsFe3">/pages/kNLnfXcN7zFLsuxgsFe3</a></p><p>Default: <code>0.5</code></p>                                                                                                                                                  |
| kernel-size-vehicle                                     | Number  | <p>Specifies the kernel size for vehicle blurring. See <a data-mention href="/pages/kNLnfXcN7zFLsuxgsFe3">/pages/kNLnfXcN7zFLsuxgsFe3</a></p><p>Default: <code>61</code></p>                                                                                                                                                         |
| face-anonymization-gradient-start                       | Number  | <p>Specifies the gradient start value for face blurring. See <a data-mention href="/pages/kNLnfXcN7zFLsuxgsFe3">/pages/kNLnfXcN7zFLsuxgsFe3</a></p><p>Default: <code>0.3</code></p>                                                                                                                                                  |
| face-anonymization-gradient-stop                        | Number  | <p>Specifies the gradient stop value for face blurring. See <a data-mention href="/pages/kNLnfXcN7zFLsuxgsFe3">/pages/kNLnfXcN7zFLsuxgsFe3</a></p><p>Default: <code>0.0</code></p>                                                                                                                                                   |
| license-plate-anonymization-gradient-start              | Number  | <p>Specifies the gradient start value for license plate blurring. See <a data-mention href="/pages/kNLnfXcN7zFLsuxgsFe3">/pages/kNLnfXcN7zFLsuxgsFe3</a></p><p>Default: <code>0.3</code></p>                                                                                                                                         |
| license-plate-anonymization-gradient-stop               | Number  | <p>Specifies the gradient stop value for license plate blurring. See <a data-mention href="/pages/kNLnfXcN7zFLsuxgsFe3">/pages/kNLnfXcN7zFLsuxgsFe3</a></p><p>Default: <code>0.0</code></p>                                                                                                                                          |
| face\_threshold                                         | Float   | <p>Specifies detection threshold from 0..1 for faces.</p><p>Default: <code>0.5</code></p>                                                                                                                                                                                                                                            |
| vehicle\_threshold                                      | Float   | <p>Specifies detection threshold from 0..1 for vehicles.</p><p>Default: <code>0.4</code></p>                                                                                                                                                                                                                                         |
| person\_threshold                                       | Float   | <p>Specifies detection threshold from 0..1 for persons.</p><p>Default: <code>0.4</code></p>                                                                                                                                                                                                                                          |
| license\_plate\_threshold                               | Float   | <p>Specifies detection threshold from 0..1 for license plates.</p><p>Default: <code>0.5</code></p>                                                                                                                                                                                                                                   |

{% tabs %}
{% tab title="200: OK Response body with JSON " %}
Response body JSON containing file information and parameters:

```javascript
{
'customer_id': '2c46d468-ee8c-4317-b4d4-aff8462f4543', 
'task_id': 1690264444814157, 
'create_time': '2023-07-25T05:54:04.814157', 
'delete_time': None, 
'name': None, 
'debug': False, 
'score': False, 
'anonymization_method': 'blur', 
'face': True, 
'license_plate': False, 
'person': False, 
'vehicle': False, 
'format': 'whole', 
'bbox': False, 
'ignores': '', 
'mask_scale': 100, 
'quality': 90, 
'compress_level': 5, 
'kernel_size_face': 0.35, 
'kernel_size_person': 91, 
'kernel_size_license_plate': 0.5, 
'kernel_size_vehicle': 61, 
'face_anonymization_gradient_start': 0.3, 
'face_anonymization_gradient_stop': 0.0, 'license_plate_anonymization_gradient_start': 0.3,
'license_plate_anonymization_gradient_stop': 0.0, 
'webhook': None, 
'start_on': 'upload', 
'extraction_types': None, 
'binary_segmentation_mask': False,
'instance_segmentation_mask': False,
'face_threshold': 0.5, 
'vehicle_threshold': 0.4, 
'person_threshold': 0.4, 
'license_plate_threshold': 0.5, 
'task_status': 'new', 
'webhook_status': set, 
'upload_url': 'https://cloudapi-customer-uploads-v2-prod-eu-central-1.s3.amazonaws.com/xxx-xxxx-xxxx-xxxx-xxxx/xxxxxxxx/1/original?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxx%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20230725T055404Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Security-Token=xxx……', 
'upload_url_expiration_duration': 3600
}

```

{% endtab %}

{% tab title="400: Bad Request Parameter doesn" %}

```json
{
"status_code":400, 
"error": "Could not create task. {parameter} parameter caused an error. This parameter does not exist."
}

```

{% endtab %}

{% tab title="400: Bad Request Parameter received unexpected value" %}

```json
{
"status_code":400, 
"error": "Could not create task. {parameter} parameter received an unexpected value."
}
```

{% endtab %}

{% tab title="400: Bad Request Parameter value value caused an error" %}

```json
{
"status_code":400, 
"error": "Could not create task. {parameter} parameter value caused an error. {Error cause}"
}

```

{% endtab %}

{% tab title="400: Bad Request Request body is not correct" %}

```json
{
"status_code":400, 
"error": "Could not create task. Request body is not correct. {Error cause}"
}

```

{% endtab %}

{% tab title="400: Bad Request JSON body missing" %}

```json
{
"status_code":400, 
"error": "Could not create task. Please add a JSON body."
}

```

{% endtab %}

{% tab title="400: Bad Request Task files are deleted" %}

```json
{
"status_code": 404,
"error": "Task is deleted. Please upload a new task."
}
```

{% endtab %}

{% tab title="500: Internal Server Error " %}

```json
{
"status_code":500, 
"error": "An unexpected error occurred. If the problem persists, please contact Celantur support (hello@celantur.com)."
}
```

{% endtab %}
{% endtabs %}

###

## Get task

<mark style="color:blue;">`GET`</mark> `https://api.celantur.com/v2/task/{id}`

Retrieve a specific task.\
The `anonymized_url` is included in the response body in case the `task_status` is `done` and the anonymized image can be downloaded.

In case the task failed, the `task_status` is set to `failed` and a "failure\_cause" property will be added to the response body.

#### Path Parameters

| Name                                 | Type   | Description    |
| ------------------------------------ | ------ | -------------- |
| id<mark style="color:red;">\*</mark> | String | id of the task |

#### Headers

| Name          | Type   | Description   |
| ------------- | ------ | ------------- |
| Authorization | String | Authorization |

{% tabs %}
{% tab title="200: OK Task as JSON" %}

```json
{
    "task_id": "1692464405235520",
    "create_time": "2023-07-27T13:25:05.295539",
    "delete_time": null,
    "debug": false,
    "score": false,
    "anonymization_method": "blur",
    "face": true,
    "license_plate": false,
    "person": false,
    "vehicle": false,
    "format": "whole",
    "bbox": false,
    "ignores": "",
    "mask_scale": "100",
    "quality": "90",
    "compress_level": "5",
    "kernel_size_face": "0.35",
    "kernel_size_person": "91",
    "kernel_size_license_plate": "0.5",
    "kernel_size_vehicle": "61",
    "face_anonymization_gradient_start": "0.3",
    "face_anonymization_gradient_stop": "0",
    "license_plate_anonymization_gradient_start": "0.3",
    "license_plate_anonymization_gradient_stop": "0",
    "start_on": "upload",
    "extraction_types": [],
    "face_threshold": "0.9",
    "vehicle_threshold": "0.4",
    "person_threshold": "0.4",
    "license_plate_threshold": "0.5",
    "original_url": "https://cloudapi-customer-uploads-v2-dev-eu-central-1.s3.amazonaws.com/xxx-xxx-xxx-xxx-xxxx/xxxxx/1/original?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxxF%2F20230727%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20230727T132849Z&X-Amz-Expires=14400&X-Amz-SignedHeaders=host&X-Amz-Security-Token=xxxx……..",
    "anonymized_url": "https://cloudapi-customer-uploads-v2-dev-eu-central-1.s3.amazonaws.com/xxxx-xxx-xxxx-xxxx-xxxxx/xxxxxxxxxx/1/anonymized.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxxx%2F20230727%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20230727T132849Z&X-Amz-Expires=14400&X-Amz-SignedHeaders=host&X-Amz-Security-Token=xxxxx……",
"anonymized_url_expiration_duration": 14400
	"webhook": "https://example.com/webhook/dev?param=test",
"webhook_status": "sent",
"binary_segmentation_mask": true,
"instance_segmentation_mask": true,
"binary_segmentation_mask_url": "https://cloudapi-customer-uploads-v2-dev-eu-central-1.s3.amazonaws.com/xxx-xxx-xxx-xxx-xxxx/xxxxx/1/original?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxxF%2F20230727%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20230727T132849Z&X-Amz-Expires=14400&X-Amz-SignedHeaders=host&X-Amz-Security-Token=xxxx…",
  "instance_segmentation_mask_url": "https://cloudapi-customer-uploads-v2-dev-eu-central-1.s3.amazonaws.com/xxx-xxx-xxx-xxx-xxxx/xxxxx/1/original?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxxF%2F20230727%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20230727T132849Z&X-Amz-Expires=14400&X-Amz-SignedHeaders=host&X-Amz-Security-Token=xxxx……",
"metadata_url": "https://api.celantur.com/v2/task/xxxxxxxxxxxxxxxx/metadata"
}

```

{% endtab %}

{% tab title="200: OK Task as JSON with task failure cause" %}

```json
{
	"task_id": task_id,
	…
	"task_status": "failed",
	"failure_cause": "IMAGE_DEFECT|TASK_FILE_DOESNT_EXIST|INTERNAL_ERROR|CONTENT_TYPE_ERROR"
}

```

{% endtab %}

{% tab title="400: Bad Request MIssing task ID" %}

```json
{
"status_code":400, 
"error": "Getting task results failed. Please enter a task ID."
}

```

{% endtab %}

{% tab title="400: Bad Request Task ID not an integer" %}

```json
{
"status_code":400, 
"error": "Wrong format for Task ID. {task_id} is not an integer."
}

```

{% endtab %}

{% tab title="400: Bad Request No task with specified task ID found" %}

```json
{
    "status_code":400, 
    "error": "Task ID not found. There is no task with task ID {task_id}."
}

```

{% endtab %}

{% tab title="500: Internal Server Error Unexpected error" %}

```json
{
"status_code":500, 
"error": "An unexpected error occurred. If the problem persists, please contact Celantur support (hello@celantur.com)."
}

```

{% endtab %}
{% endtabs %}

## Get task status

<mark style="color:blue;">`GET`</mark> `https://api.celantur.com/v2/task/{id}/status`

Returns the status of the specified task. The `anonymized_url` is included in the response body in case the `task_status` is “done” and the anonymized image can be downloaded.

In case the task failed, the `task_status` is set to `failed` and a "failure\_cause" property will be added to the response body.

#### Path Parameters

| Name                                 | Type   | Description    |
| ------------------------------------ | ------ | -------------- |
| id<mark style="color:red;">\*</mark> | String | id of the task |

#### Headers

| Name                                            | Type   | Description         |
| ----------------------------------------------- | ------ | ------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Authorization token |

{% tabs %}
{% tab title="200: OK Task status" %}

```json
{
"task_id": 1690464305295539,
"task_status": "done",
"delete_time": null, 
"webhook": "https://example.com/webhook/dev?param=test",
"webhook_status": "sent",
"anonymized_url": "https://cloudapi-customer-uploads-v2-dev-eu-central-1.s3.amazonaws.com/6b6986c2-20ee-45f9-b8b0-bb56c10cb6c0/1642464305211532/1/anonymized.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAVKZ73AQDDJGIR2DP%2F20230727%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20230727T133010Z&X-Amz-Expires=14400&X-Amz-SignedHeaders=host&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEMb%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDGV1LWNlbnRyYWwtMSJGMEQCIDOIQJSmlTa7ih%2F0Diy%2FEiAGTb4lEXo%2B17PxaPn0kDBjAiBDEfQp2iGNPENpbKrvlBBPVrg8hbAz2LQ8jm…E2wPUG3NN9HF2czMOJgRipr4jGlBX1P0xXH%2FWRy5ztcPmW1WOfxXRbuq637uqmTDdIR%2F55oq8zTLaFZ5TRDDh4ommBjqfAYPDyQCDbX0HdhPY5az54JKHKyov3OjEIgrLINWfFxlplHp5GK4RMNbsfA0%2Fusqt0JGwhIyb8kMz7jGEgzPLuOlEle89XwmhZP9gGaJy7oe8bJQK3t6ikuArv8BphnKfiLkP%2BSZc%2Bn%2BhGCT3sMxc9w5LtjzfNz33oYro2NkORSRCLdeTLEBBpRHAEX4ZlhxDEJr5QSAWGx7ceb7GWqcfqQ%3D%3D&X-Amz-Signature=d3e1e3e6ecbbba5457927a1236fd9251bcd762d2e43fa4969bb10481d57d79a9",
    "anonymized_url_expiration_duration": 14400,
"metadata_url": "https://api.celantur.com/v2/task/xxxxxxxxxxxxxxxx/metadata"
}

```

{% endtab %}

{% tab title="200: OK Task status for failed task with failure cause" %}

```json
{
	"task_id": task_id,
	…
	"task_status": "failed",
	"failure_cause": "IMAGE_DEFECT|TASK_FILE_DOESNT_EXIST|INTERNAL_ERROR|CONTENT_TYPE_ERROR"
}

```

{% endtab %}

{% tab title="400: Bad Request No task with specified task ID found" %}

```json
{
"status_code":400, 
"error": "Task ID not found. There is no task with task ID {task_id}."
}
```

{% endtab %}

{% tab title="400: Bad Request Task ID is not an interger" %}

```json
{
"status_code":400, 
"error": "Wrong format for Task ID. {task_id} is not an integer."
}

```

{% endtab %}

{% tab title="500: Internal Server Error Unexpected error" %}

```json
{
"status_code":500, 
"error": "An unexpected error occurred. If the problem persists, please contact Celantur support (hello@celantur.com)."
}

```

{% endtab %}
{% endtabs %}

## Get task metadata

<mark style="color:blue;">`GET`</mark> `https://api.celantur.com/v2/task/{id}/metadata`

Returns the metadata of the specified task. Metadata contain a `detections` property containing a list of detections of the corresponding file.

204 with an empty body is returned when :

\- No detections where found

\- The task has not finished processing yet

\- The task failed

#### Path Parameters

| Name                                 | Type   | Description    |
| ------------------------------------ | ------ | -------------- |
| id<mark style="color:red;">\*</mark> | String | id of the task |

#### Headers

| Name                                            | Type   | Description         |
| ----------------------------------------------- | ------ | ------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Authorization token |

{% tabs %}
{% tab title="200: OK Task metadata with detections" %}

```json
{
    "task_id": 1693905790526783,
    "detections": [
        {
            "score": 0.9993058443069458,
            "offset": [
                443.0,
                533.0
            ],
            "color": null,
            "bbox": [
                619.0,
                639.0,
                794.0,
                813.0
            ],
            "parent_image": "",
            "id": 0.0,
            "type_label": "face",
            "type": 103.0,
            "is_anonymised": true
        },
      ...
    ]
}

```

{% endtab %}

{% tab title="204: No Content No detections, task\_status failed or task has not finished processing yet" %}

{% endtab %}

{% tab title="400: Bad Request No task with specified task ID found" %}

```json
{
"status_code":400, 
"error": "Task ID not found. There is no task with task ID {task_id}."
}

```

{% endtab %}

{% tab title="400: Bad Request Task ID is not an integer" %}

```json
{
"status_code":400, 
"error": "Wrong format for Task ID. {task_id} is not an integer."
}

```

{% endtab %}

{% tab title="500: Internal Server Error Unexpected error" %}

```json
{
"status_code":500, 
"error": "An unexpected error occurred. Please try creating a task again. If the problem persists, please contact Celantur support (hello@celantur.com)."
}

```

{% endtab %}
{% endtabs %}

## List tasks

<mark style="color:blue;">`GET`</mark> `https://api.celantur.com/v2/task/list`

List tasks and filter by creation time and task status.

Use pagination by specifying the `next_page_key` parameter.

#### Query Parameters

| Name                                                   | Type   | Description                                                                                                                                                                                                                                                              |
| ------------------------------------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| create\_time\_before<mark style="color:red;">\*</mark> | String | <p>Filter: Return tasks which were created before the specified date.</p><p>Format: <code>YYYY-MM-DD</code></p>                                                                                                                                                          |
| create\_time\_after<mark style="color:red;">\*</mark>  | String | <p>Filter: Return tasks which were created after the specified date.</p><p>Format: <code>YYYY-MM-DD</code></p>                                                                                                                                                           |
| task\_status                                           | String | <p>Filter by specified task status. Has to be either "new", "queued", "processing", "done" or "failed".</p><p>Default: None</p>                                                                                                                                          |
| next\_page\_key                                        | String | The task\_id that specifies the starting position of a page. The task with the provided task\_id is not part of the page.                                                                                                                                                |
| limit                                                  | Number | <p>Maximum number of tasks on a page. If the parameter is smaller than the minimum or larger than the maximum the parameter will automatically be set to minimum or maximum value.</p><p>Minimum: <code>10</code> Maximum: <code>300</code> Default: <code>10</code></p> |

#### Headers

| Name                                            | Type   | Description         |
| ----------------------------------------------- | ------ | ------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Authorization token |

{% tabs %}
{% tab title="200: OK " %}

```json
{
    "limit": 5,
    "count": 5,
    "next_page_key": 1689161781804287,
    "items": [
        {
            "task_id": 1689161328607410,
            "create_time": "2023-07-12T11:28:48.607410",
            "task_status": "done"
        },
        {
            "task_id": 1689161451227087,
            "create_time": "2023-07-12T11:30:51.227087",
            "task_status": "done"
        },
        {
            "task_id": 1689161743300320,
            "create_time": "2023-07-12T11:35:43.300320",
            "task_status": "done"
        },
        {
            "task_id": 1689161768856287,
            "create_time": "2023-07-12T11:36:08.856287",
            "task_status": "done"
        },
        {
            "task_id": 1689161781804287,
            "create_time": "2023-07-12T11:36:21.804287",
            "task_status": "done"
        }
    ]
}
```

{% endtab %}

{% tab title="400: Bad Request Format error of create\_time\_before/create\_time\_after" %}

```json
{
    "status_code": 400,
    "error": "Please enter a properly formatted time for the create_time_before value. Correct format:  YYYY-MM-DD"
}
```

{% endtab %}

{% tab title="400: Bad Request Wrong task\_id format" %}

```json
{
    "status_code": 400,
    "error": "Wrong format for task_id. Please enter an integer."
}
```

{% endtab %}

{% tab title="400: Bad Request Wrong task\_status" %}

```json
{
    "status_code": 400,
    "error": "Please enter a correct task_status. Task status value can only be one of ['new', 'queued', 'processing', 'done', 'failed']"
}
```

{% endtab %}

{% tab title="400: Bad Request create\_time\_\* parameters are missing" %}

```json
{
    "status_code": 400,
    "error": "No create_time_* parameters have been specified."
}
```

{% endtab %}

{% tab title="400: Bad Request create\_time\_after parameter is later than or equal to create\_time\_before" %}

```json
{
    "status_code": 400,
    "error": "Please check your create_time_* parameters. create_time_after can not be 
              later than/equal to create_time_before."
}
```

{% endtab %}

{% tab title="500: Internal Server Error Unexpected error" %}

```json
{
    "status_code": 500,
    "error": "An unexpected error occurred. If the problem persists, please contact Celantur support (hello@celantur.com)."
}
```

{% endtab %}
{% endtabs %}

## Sign in (authorization)

<mark style="color:green;">`POST`</mark> `https://api.celantur.com/v2/signin`

Provide your username and password credentials (of your app.celantur.com account) as a JSON payload to authenticate, and receive your AccessToken to use Celantur Cloud API.

`{ "username": "username@usermail.com", "password": "password" }`

#### Request Body

| Name                                       | Type   | Description               |
| ------------------------------------------ | ------ | ------------------------- |
| username<mark style="color:red;">\*</mark> | String | Username as JSON property |
| password<mark style="color:red;">\*</mark> | String | Password as JSON property |

{% tabs %}
{% tab title="200: OK Authentication result" %}

```javascript
{
    "AccessToken": "eyJraWQiOiJr…Wa_CNpFRyNIjbt5qjAED1-oH8pEKpO-KPTttuSGHw",
    "ExpiresIn": 3600,
    "TokenType": "Bearer",
    "RefreshToken": "eyJjd...t8OWzmXJpmPnuNbBzr1vPA",
    "IdToken": "eyJraWQiOiI1aTlFa…ZIttv0gNRJRp39LvyzAn5LJWJBw7Ju8szRRBA"
}
```

{% endtab %}

{% tab title="400: Bad Request Incorrect username or password" %}

```
{
   "message": "Incorrect username or password.",
   "code": "NotAuthorizedException",
   "time": "2023-07-31T07:13:56.569Z",
   "requestId": "ce5c6036-18de-4476-9388-59ddcded7943",
   "statusCode": 400,
   "retryable": false,
   "retryDelay": 57.558191461534605
}
```

{% endtab %}
{% endtabs %}

## Delete task files.

<mark style="color:red;">`DELETE`</mark> `https://api.celantur.com/v2/task/{id}/files`

Deletes the files and detections associated with the specified task.

In case the task files are already deleted, any newly uploaded files through upload URL will also be deleted.

#### Path Parameters

| Name                                 | Type   | Description    |
| ------------------------------------ | ------ | -------------- |
| id<mark style="color:red;">\*</mark> | String | id of the task |

#### Headers

| Name                                            | Type   | Description         |
| ----------------------------------------------- | ------ | ------------------- |
| Authorization<mark style="color:red;">\*</mark> | String | Authorization token |

{% tabs %}
{% tab title="200: OK Task deleted" %}

```json
{
"files_deleted": true,
"task_id": "{task_id}"
}

```

{% endtab %}

{% tab title="400: Bad Request Task is already deleted" %}

```json
{
"status_code": 400,
"error": "Task with ID 1696335137350403 already deleted."
}
```

{% endtab %}

{% tab title="400: Bad Request No task with specified task ID found" %}

```json
{
"status_code":400, 
"error": "Task ID not found. There is no task with task ID {task_id}."
}
```

{% endtab %}

{% tab title="400: Bad Request Task ID is not an interger" %}

```json
{
"status_code":400, 
"error": "Wrong format for Task ID. {task_id} is not an integer."
}

```

{% endtab %}

{% tab title="500: Internal Server Error Unexpected error" %}

```json
{
"status_code":500, 
"error": "An unexpected error occurred. If the problem persists, please contact Celantur support (hello@celantur.com)."
}

```

{% endtab %}
{% endtabs %}


# Webhooks

Celantur Cloud API v2 uses webhooks to notify your application when a file has been processed.

## Overview

By setting a `webhook` URL in the request to [API Endpoints](/cloud-api/api-endpoints#create-anonymization-task), a HTTPS POST request will be sent to the specified URL, as soon as the submitted file has finished processing.

{% code overflow="wrap" %}

```python
payload = {
    "anonymization_method": "blur",
    "face": True,
    "webhook": "https://example.com/webhook/dev?param=test"
}

response = requests.post(
     "https://api.celantur.com/v2/task/", 
      data=json.dumps(payload), 
      headers={'Authorization': auth_token}
 )

```

{% endcode %}

The payload sent to the webhook URL looks like this:

```json
{
    "customer_id": "247d7a0f-f03c-40b9-bed6-b2c4a00c5d80", 
    "task_id": 1693295888421318, 
    "task_status": "done", 
    "anonymized_url": "https://cloudapi-customer-uploads-v2-dev-eu-central-1.s3.amazonaws.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxxxxxxxxxxxxxxx/1/anonymized.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAVKZ73AQDINGO3STH%2F20230829%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20230829T080023Z&X-Amz-Expires=14400&X-Amz-SignedHeaders=host&X-Amz-Signature=5c99b77982c11da5e9889d3c88c0d2a109270d8c2b0f17d61566ccxxx0495xxx”
}

```

{% hint style="info" %}
Webhooks are especially useful to trigger the download of a file, right after it has finished processing.
{% endhint %}

## Webhook status

The task’s webhook status is either:

* `empty`
* `set`
* `sent`
* `failed`

The webhook status can be retrieved from the response bodies of [API Endpoints](/cloud-api/api-endpoints#get-task) and [API Endpoints](/cloud-api/api-endpoints#get-task-status) endpoint.

## Prerequisites for webhooks

* [ ] Make sure you have a publicly available HTTPS endpoint (URL) on your server.
* [ ] Set the webhook URL in the [API Endpoints](/cloud-api/api-endpoints#create-anonymization-task) request's JSON body.


# v1 (deprecated)

{% hint style="warning" %}
Celantur Cloud API v1 has been deprecated in September 2023. **Please use v2.**
{% endhint %}


# Release Notes

Celantur Cloud API v2 Release Notes

## 2026 <a href="#draft-23.09.3" id="draft-23.09.3"></a>

### Version 26.04.2

Deployed on April 30th, 2026.

Upgrade Cloud API backend to [version 26.04.2 of Container](#version-26.04.2).

* New model trained on additional images.

### Version 26.03.1

Deployed on March 8th, 2026.

Upgrade Cloud API backend to [version 26.03.1 of Container](#version-26.03.1) .

* Faster processing and better detection with new inference engine.

## 2023 <a href="#draft-23.09.3" id="draft-23.09.3"></a>

### Version 23.09.3 <a href="#draft-23.09.3" id="draft-23.09.3"></a>

Deployed on Oct 5th, 2023

* Improve internal system monitoring.

### Version 23.09.2 <a href="#draft-23.09.2" id="draft-23.09.2"></a>

Deployed on Sep 27, 2023

* Download metadata and [segmentation masks](/container/usage/segmentation-masks-and-metadata#binary-segmentation) --> [API Endpoints](/cloud-api/api-endpoints#get-task-metadata)
* Fixed issue with format parameter "whole"
* Introduced GET task list endpoint --> [API Endpoints](/cloud-api/api-endpoints#list-tasks)

### Version 23.09.1 <a href="#draft-23.09.1" id="draft-23.09.1"></a>

Deployed on Sep 11, 2023 20.00 CEST.

* Introduced [webhooks](/cloud-api/webhooks) to Cloud API v2.

### Version 23.08.2 <a href="#draft-23.08.2" id="draft-23.08.2"></a>

Deployed with v23.09.1

* Enabled CORS for Cloud API v2.

### Version 23.08.1 <a href="#draft-23.08.1" id="draft-23.08.1"></a>

Deployed with 23.09.1

* Added failure reasons to v2 get task id response in case of failure.

### Version 23.07.3 <a href="#draft-23.07.3" id="draft-23.07.3"></a>

Deployed on Jul 31, 2023

* Introduced new and improved existing error codes.
* Fixed misc. minor issues

### Version 23.07.2 <a href="#draft-23.07.2" id="draft-23.07.2"></a>

Deployed on Jul 22, 2023

* Misc. QOL improvements.

### Version 23.07.1 <a href="#draft-23.07.1" id="draft-23.07.1"></a>

Deployed with version 23.07.2

* First prod deployment of Cloud API v2 🎉.


# Image Anonymization in Esri ArcGIS Online

Easily blur personal information in images hosted on ArcGIS Online by using Celantur Cloud API.

### Introduction

This tutorial will guide you through the process of anonymizing personal information in your images stored in ArcGIS Online. We'll use a [Jupyter Notebook](https://github.com/celantur/celantur-arcgis-tools/tree/main/jupyter-notebook) to connect ArcGIS Online with the [Celantur Cloud API](/cloud-api/getting-started).

The Notebook will fetch the original image attachments which have not been anonymized yet, send them to Celantur Cloud API for anonymization, and save the anonymized images back to ArcGIS Online.

<figure><img src="/files/3YTiGNP2pJfrlC4AtVTN" alt=""><figcaption><p>Architecture of Celantur Cloud API and ArcGIS Online integration</p></figcaption></figure>

### Prerequisites

Before you begin, ensure you have the following:

* [ ] An Esri ArcGIS Online account with access to the Notebook service
* [ ] A Celantur account (app.celantur.com)
* [ ] Basic understanding of Python

### Steps

#### 1. Log in to ArcGIS Online

Log in to your ArcGIS Online account.

#### 2. Prepare Feature Layer in ArcGIS Online

1. On the ArcGIS page <https://celantur.maps.arcgis.com/home/content.html> click to `New Item` button and proceed with creation of `Feature Layer`.
2. Then open that new Item, and open `Data` tab and select `Fields` sub-tab
3. Click to `Add` button (only if this field does not yet exist)
   * `Field Name`: `is_anonymized`
   * `Display Name`: `Is anonymized`
   * `Type`: `integer`
   * `Default Value`: `0`
   * Click `Add New Field`

#### 3. Add Images

Add images as attachment to points via e.g. Field Maps app. Make sure the same Feature Service Layer is specified in the Notebook code.

#### 4. Add the Notebook

1. In ArcGIS online, create a new Notebook.
2. Insert the Notebook content from <https://github.com/celantur/arcgis-jupyter-dev> into your newly created Notebook.

#### 5. Configure the Notebook

1. In the section of `! CREDENTIALS !` specify your credentials accordingly
2. Go to section `Main`
   * Adjust `layer_id` uid value to the corresponding layer you want to use.
   * Adjust params to your taste, see <https://doc.celantur.com/cloud-api/api-endpoints#create-anonymization-task>
3. Create directory `/arcgis/home/downloads`
4. Run the Notebook

#### 6. Check Anonymized Images

Verify that the personal information in your images has been successfully anonymized.

#### 7. Schedule the Notebook (optional)

Schedule the Notebook to be executed regularly.

{% hint style="warning" %}
Limitations:

The current Notebook code will process **all images** where `is_anonymized` equals `false`. Please consider the impact of the amount of images on the Notebook runtime.
{% endhint %}

### Conclusion

Congratulations! 🎉 You have successfully anonymized images in Esri ArcGIS Online using the provided Jupyter Notebook and Celantur Cloud API. Feel free to explore the code and customize it for your specific use case.

If you encounter any issues or have suggestions for improvement, please address your contact person at Celantur.


# Image Anonymization in Esri ArcGIS Pro

Easily blur personal information in images hosted on ArcGIS Online by using a Geoprocessing Tool and Celantur Cloud API.

### Introduction

This tutorial will guide you through the process of anonymizing personal information in your images stored in a ArcGIS Online Feature Layer, by using Celantur's **Geoprocessing Tool in ArcGIS Pro** to connect to [Celantur Cloud API](/cloud-api/getting-started).

The Geoprocessing Tool will fetch the original image attachments which have not been anonymized yet, send them to Celantur Cloud API for anonymization, and save the anonymized images back to ArcGIS Online.

### Prerequisites

Before you begin, ensure you have the following:

* [ ] A Celantur account (app.celantur.com)
* [ ] Esri ArcGIS Pro
* [ ] A Feature Layer with a custom `new_anonymized` field

### Steps

#### 1. Prepare Feature Layer in ArcGIS Online

1. On the ArcGIS page <https://celantur.maps.arcgis.com/home/content.html> click to `New Item` button and proceed with creation of `Feature Layer` (skip this step if you have an existing feature layer).
2. Then open that new Item, and open `Data` tab and select `Fields` sub-tab
3. Click to `Add` button (only if this field does not yet exist)
   * `Field Name`: `new_anonymized`
   * `Display Name`: `Is anonymized`
   * `Type`: `integer`
   * `Default Value`: `0`
   * Click `Add New Field`

#### 2. Add the Celantur Geoprocessing Tool to ArcGIS Pro

1. Download the Celantur Geoprocessing Tool ([CelanturBlurringToolbox.pyt](https://github.com/celantur/celantur-arcgis-tools/blob/main/geoprocessing-toolbox/CelanturBlurringToolbox.pyt)) from <https://github.com/celantur/celantur-arcgis-tools/tree/main/geoprocessing-toolbox>
2. In ArcGIS Pro
   1. Switch to "Insert" ribbon
   2. Click "Toolbox" dropdown
   3. Click "Add Toolbox"
   4. Select and open the Celantur Geoprocessing Tool (.pyt file)
   5. In the "Catalog" pane, select "Project"
   6. Expand "Toolboxes" and "CelanturBlurringTool" in the tree
   7. Double-click the "Celantur Blurring Tool" script

<figure><img src="/files/O4rv0olsxjemvd9OOdsZ" alt=""><figcaption><p>Adding and opening the Celantur Blurring Tool in ArcGIS Pro.</p></figcaption></figure>

####

#### 3. Add Images

Add images as attachment to points via e.g. Field Maps app.

#### 4. Anonymize images with Celantur Geoprocessing Tool

1. In ArcGIS Pro, open the Celantur Geoprocessing Tool and specify your Celantur App username (email) and password, as well as the Feature Service Layer containing the images you want to anonymize.
2. Click "Run" to start the anonymization process.

<figure><img src="/files/FP8beVLPivmLUQK8wGV6" alt=""><figcaption></figcaption></figure>

### Conclusion

Congratulations! 🎉 You have successfully anonymized images in Esri ArcGIS Pro by using the provided Geoprocessing Tool and Celantur Cloud API.

If you encounter any issues or have suggestions for improvement, please address your contact person at Celantur.


# Anonymization of ROS2 .mcap files

Blur images in ROS2 .mcap files with Celantur Container and a custom script

Celantur container does not support `.mcap` files as an input format. However, we provide a **script** to extract images from such files and a script to merge anonymized images back into the `.mcap` file. Using those in combination with Celantur Container one can anonymize ROS2 .mcap files.

For more information about this process and the script, please see: [**https://github.com/celantur/celantur-examples/tree/main/mcap-files**](https://github.com/celantur/celantur-examples/tree/main/mcap-files)


# FARO Blurring Workflow

## Export/Import FARO laser scanner images for blurring

{% hint style="info" %}
Image resolution must not be changed during the workflow.
{% endhint %}

### Step by step

1. Open your registered project
2. Select `Explore`
3. Export Color Overlays:
   1. Right click a scan
   2. Click `Operations` > `Color/Pictures` > `Export Color Overlay...`
4. Apply blurring on exported .bmp image file, e.g. fully automated with [Celantur](https://www.celantur.com/image-anonymization-terrestrial-laser-scanning/).
5. Import blurred Color Overlay
   1. Right click scan
   2. Click `Operations` > `Color/Pictures` > `Replace Color Overlay...`
6. The blurred color overlay will be displayed after a few moments.

<figure><img src="/files/6jKJHnnNijTZAua4qSJG" alt=""><figcaption><p>Context menu flow to export and import color overlays for blurring in FARO SCENE</p></figcaption></figure>


# Anonymize Teledyne Flir PGR images

Use Horus Batch Processing and Celantur Container to blur Teledyne Flir PGR images.

{% hint style="info" %}
[**Horus Horison**](https://horus.nu/integration-accelerator/) **and** [**Celantur Container**](/container/getting-started) **are required for this workflow.**
{% endhint %}

A lot of street level imagery is collected in container formats like Teledyne Flir \*.PGR (output of e.g. [Ladybug panorama cameras](https://www.flir.eu/products/ladybug6/)) or Horus \*.dat.

Horus offers software tools to combine Celantur Container with image conversion in one go. The following imagery types and conversions are supported:

* PGR2PGR
* PGR2JPEG
* Horus2Horus
* Horus2JPEG
* JPEG2JPEG

Besides the combination of Celantur Container and the conversion, the Horus software helps to streamline and speed up the anonymization process.

## Starting a Batch Job

1. Verify that Celantur Container is running in [API mode](/container/usage/rest-api-v1-mode), by calling the [REST API (v1) mode](/container/usage/rest-api-v1-mode#check-celantur-container-status) endpoint.\
   Alternatively, see the Horus documentation how to verify this.
2. Start the `“Horus_Linking_Lab-*-x86_64.AppImage”`.
3. Connect to ‘This System’:\
   ![](/files/JWw35MW6HXycUk2tpJjf)
4. Open the ‘Batch Processing’ tool on the main menu:\
   ![](/files/4r7lboTGxwlfSblpnGm4)
5. Select ‘New Job’ to start a batch job:\
   ![](/files/f8ACZgLQFRKlAzrEfnKc)\ <img src="/files/V06BNO5vasiGSvKPoRYU" alt="" data-size="original">
   1. *Select a process:*\
      \- Blur JPEG Images\
      \- Blur PGR Images
   2. *Select a pipeline:*\
      \- Blurring vehicles and people\
      \- Blurring license plates and faces.\
      This setting is only used for blurring.
   3. *Source folder:*\
      Define the path of the parent directory where the recordings are stored.
   4. *Create a job for each sub-folder of the source:*\
      Choose to create a separate batch job for each descendant sub-folder of the source location.
   5. *Destination folder:*\
      Define the path to the location where the new data will be written to.
   6. *Start new job:*\
      Press on the blue ‘start new job’ button to add the batch job to the queue.
6. Monitor the status of the batch job.\
   ![](/files/8twGZmX3ZcwmEmk8jCjU)\
   If there are no pending jobs currently being processed or in the queue, then the new job will automatically start processing.\
   By selecting a batch job, you can view additional information about the processing.\
   If you are unsure if the batch job is being processed, you may open the Graph Builder and verify if the pipeline is running and processing data.\
   When the processing is done the job will be marked as completed.
7. Check the output of the batch job.\
   Verify that the process has correctly processed the data by checking the destination folder.\
   Verify that vehicles and/or persons are now blurred.

<table data-card-size="large" data-column-title-hidden data-view="cards"><thead><tr><th></th><th></th><th data-hidden></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Contact Horus</strong></td><td><em>Request help or a demo from the Horus team.</em></td><td></td><td></td><td><a href="https://horus.nu/contact-us/">https://horus.nu/contact-us/</a></td></tr><tr><td><strong>Contact Celantur</strong></td><td><em>Request help or a demo from the Celantur team.</em></td><td></td><td></td><td><a href="https://www.celantur.com/contact/">https://www.celantur.com/contact/</a></td></tr></tbody></table>

{% hint style="info" %}
More information: <https://horus.nu/anonymization-mobile-mapping-street-level-imagery/>
{% endhint %}


