> For the complete documentation index, see [llms.txt](https://docs.eyepop.ai/developer-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.eyepop.ai/developer-documentation/platform/sources-and-options/options/region-of-interest.md).

# Region of Interest

Crop every frame to a region before inference

`roi` crops every frame before the Pop sees it — a checkout lane in a wide shot, a conveyor belt, one bay of a car park. Everything outside is not analyzed, which cuts work as well as false positives from the rest of the scene.

A region is either a **rectangle** or a **contour**. Both crop to a rectangle: a contour crops to its bounding box and then blacks out everything inside that box but outside the ring, so the parts of the scene you did not draw around never reach the model.

Coordinates are **source pixels**, not fractions, with the origin at the top left — the same for both shapes. A region running past the right or bottom edge is trimmed rather than rejected, because the frame size is not known until the source is read.

## Which shape

A rectangle is the right answer when the area you care about is square to the camera. It is two corners and nothing to think about.

A contour is the answer when it is not. Anything viewed at an angle — a lane, a walkway, a conveyor running away from the camera — is a trapezoid in the frame, and the smallest rectangle containing it always contains part of whatever is beside it. A rectangle around one lane admits the next lane's traffic, and every vehicle queueing there is counted as though it were in the lane you meant.

<figure><img src="https://1956543008-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2tRktyRCGgE1tPlAfT4h%2Fuploads%2Fgit-blob-5614c9ead7fa94bbc749d8460681d707a0560ae1%2Froi-rectangle-vs-contour.png?alt=media" alt="The same region drawn on a street scene, then what a rectangle roi and a contour roi each feed to inference"><figcaption><p>The same region, three ways. The ring is drawn around the person by the barrier; its bounding box, in amber, also contains the red car on the road behind. A rectangle roi feeds that car to the model along with the person. A contour roi crops to the same box and blacks out everything outside the ring, so only the person reaches it. Source photo: HK YLD Yuen Long highway, Wikimedia Commons (<a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0</a>).</p></figcaption></figure>

## A rectangle

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

```python
from eyepop.data.types.asset import RectangleArea

job = endpoint.load_from(
    "rtsp://camera.example.com/stream1",
    roi=RectangleArea(x=160, y=0, width=320, height=480),
)
```

{% endtab %}

{% tab title="Node" %}

```typescript
import { AreaType } from '@eyepop.ai/eyepop'

const results = await endpoint.process({
    source: { url: 'rtsp://camera.example.com/stream1' },
    roi: { type: AreaType.RECTANGLE, x: 160, y: 0, width: 320, height: 480 },
})
```

{% endtab %}
{% endtabs %}

## A contour

Points are listed in order around the ring. The ring closes on its own — do not repeat the first point at the end.

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

```python
from eyepop.data.types.asset import ContourArea
from eyepop.data.types.common import Point2d

job = endpoint.load_from(
    "rtsp://camera.example.com/stream1",
    roi=ContourArea(points=[
        Point2d(x=220, y=90),
        Point2d(x=540, y=110),
        Point2d(x=610, y=470),
        Point2d(x=140, y=440),
    ]),
)
```

{% endtab %}

{% tab title="Node" %}

```typescript
import { AreaType } from '@eyepop.ai/eyepop'

const results = await endpoint.process({
    source: { url: 'rtsp://camera.example.com/stream1' },
    roi: {
        type: AreaType.CONTOUR,
        points: [
            { x: 220, y: 90 },
            { x: 540, y: 110 },
            { x: 610, y: 470 },
            { x: 140, y: 440 },
        ],
    },
})
```

{% endtab %}
{% endtabs %}

A ring needs at least three points, and they must not all fall on one line — three points on a diagonal have a bounding box with both a width and a height and still enclose nothing to crop to. A ring that crosses itself is filled by the even-odd rule, so a bowtie encloses its two lobes.

{% hint style="warning" %}
**An object straddling the ring is cropped along with the background.** The model sees the part inside and nothing of the part outside, so a subject only half inside may not be detected at all, and one crossing the edge appears to grow as it enters.

Where the timing of a detection matters — the moment something arrives, how long it stayed — draw the region wide enough to contain a whole subject at the point you care about, rather than tight to the boundary you are measuring.
{% endhint %}

## What comes back

Predictions come back in the **original** frame's coordinate space, not the crop's, for both shapes: the worker translates them back by the region's offset, and `source_width` / `source_height` report the uncropped source. Nothing downstream has to know a crop happened, or which shape was used.

A [`camera`](/developer-documentation/platform/sources-and-options/options.md#camera-calibration) calibration follows the same rule: it describes the original frame, not the crop, and needs no adjustment when an `roi` is set.

## What is rejected

A region is checked when it is accepted, rather than failing once the source is already starting. Refused:

|                                                     |                                                                                                        |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| a rectangle with a negative `x` or `y`              | a negative edge pads the frame rather than moving the region, so the crop is not the one you asked for |
| a rectangle with a zero or negative width or height | encloses nothing to crop to                                                                            |
| a contour of fewer than three points                | two points are a line segment                                                                          |
| a contour whose points all lie on one line          | encloses nothing, however large the bounding box                                                       |
| any coordinate that is not a finite number          |                                                                                                        |

A region larger than the frame is **not** refused. It is trimmed when the source is read, because a region written for a 4K camera is correct for that camera whatever the worker is handed first.
