> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ovalbee.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ovalbee.com/_mcp/server.

# Filter images

> Removes or keeps whole images of an OvalBee dataset by labels count, asset tags, classes, image size, and object-level conditions (area share, box aspect, geometry, object tag), combined with And or Or, then adds the selected images to a destination dataset. It acts on whole images - an image matches the object conditions when one of its objects satisfies all of them at once, and the image moves to the destination with all of its labels. To clean up individual labels instead, use Filter annotations.

## Overview

Matches images by object-count, asset-tag, class, image-size, and object conditions, combined with **And** or **Or**, then adds the matched images — or everything but them — with their annotations to a destination dataset.

The badge shows how many new images were added and opens the result.

```mermaid
flowchart LR
  n1["Dataset"] --> n2["Filter images"] --> n3["Dataset"]
```

## How it works

Checks every image of the source dataset against the conditions you set, combined with **And** or with **Or**.

Selects the images that do not match when **Matched images** is **Remove**, or only the matches when it is **Keep**.

Adds the selected images and their annotations to the destination dataset, skipping images already there, then refreshes its statistics.

## FAQ

#### How are multiple conditions combined?

The **Operator** input decides. With **And**, the default, an image matches only when it satisfies every condition you set. With **Or**, one is enough. Conditions left empty do not take part, and a single condition means the same thing either way. Setting no condition at all is a validation error rather than a match-everything run.

A range counts as one condition whether you fill one side of it or both. The tag conditions also count as one: every listed tag must be present. The object conditions (area, box aspect, geometry, object tag) form a single condition as well — one object must satisfy all of them at once.

#### Which annotation is checked?

Object counts, annotation tags, classes, and object conditions come from the image's annotation in the source dataset. Image tag conditions read the image itself.

An image without an annotation counts as having zero objects and no classes, and it never matches an annotation tag or object condition. With **Matched images** set to **Remove**, such images therefore stay in the result.

#### Where does the image size come from?

From the image's annotation first, and from the image's own metadata when the annotation does not record it. An image whose size is not known from either source never matches an image-size condition.

Every range works the same way: fill both sides to bound it from both ends, fill one side for "at least" or "at most", and leave both empty to switch the condition off.

#### Why is the first run with object or image-size conditions slower?

These conditions need per-object statistics. The first run computes them for every annotation that does not have them yet, which means downloading those annotations. Later runs over the same annotations reuse the results.

#### What if I don't select a destination dataset?

The node writes into its own output dataset — created on the first run, a new empty version of it on a rerun.

#### What if no images are selected?

The run succeeds and the badge shows zero. A new destination stays empty, while an existing destination stays unchanged.

#### Why can the badge count be lower than the number of selected images?

Images already present in the destination dataset are skipped. The badge counts only newly added images.

## Inputs

**`Source dataset`** `dataset` — required

Dataset to filter. Key: `SRC_DATASET`.

---

**`Destination dataset`** `dataset`

Where the selected images go. Leave empty to use the node's own output dataset. Key: `DST_DATASET`.

---

**`Matched images`** `select` — required, default: remove

Remove keeps everything except the matches. Keep keeps only the matches. Key: `MATCHED_IMAGES`.

Options:

* Remove (`remove`)
* Keep (`keep`)

---

**`Operator`** `select` — required, default: and

And requires every condition below. Or requires just one of them. Key: `CONDITIONS_OPERATOR`.

Options:

* And (`and`)
* Or (`or`)

---

**`Has tags`** `asset_tags`

Tags the image or its annotation carries. Write images:key or annotations:key, and add =value to require a value. Values come from `SRC_DATASET`. Key: `HAS_TAGS`.

---

**`Has classes`** `ontology`

Classes the image must contain at least one of. Values come from `SRC_DATASET`. Key: `HAS_CLASSES`.

---

**`Image width (px)`** `range`

Pixel width an image must fall within. Minimum: `1`. Step: `1`. Key: `IMAGE_WIDTH_PX`.

---

**`Image height (px)`** `range`

Pixel height an image must fall within. Minimum: `1`. Step: `1`. Key: `IMAGE_HEIGHT_PX`.

---

**`Objects per image`** `range`

Number of objects an image must have, counted from its annotation. Minimum: `0`. Step: `1`. Key: `OBJECTS_COUNT`.

---

**`Object area (%)`** `range`

Share of the image one object covers, in percent. Minimum: `0`. Maximum: `100`. Step: `0.5`. Key: `OBJECT_AREA_PERCENT`.

---

**`Object box aspect`** `range`

How stretched one object is: its long side over its short side. 1 is a square. Minimum: `1`. Step: `0.1`. Key: `OBJECT_BOX_ASPECT`.

---

**`Object geometry`** `select`

Shape the object is drawn with. Key: `OBJECT_GEOMETRY`.

Options:

* Rectangle (`rectangle`)
* Polygon (`polygon`)
* Bitmap (`bitmap`)
* Alpha mask (`alpha_mask`)
* Point (`point`)
* Line (`line`)
* Graph (`graph`)

---

**`Object tag`** `string`

Tag the object carries. Write key, or key=value to require a value. Key: `OBJECT_TAG`.

---

## Outputs

**`Dataset`** `dataset`

ID of the destination dataset with selected images. Shown as an artifact. Key: `DATASET`.

---

**`Last Images Count`** `string`

Number of images added to the destination dataset. Shown on the node as a badge. Selecting the badge opens `DATASET`. Key: `LAST_IMAGES_COUNT`.

---

## JSON config

Machine-readable node interface for automation and advanced usage.

#### Show JSON

```json
{
  "name": "Filter images",
  "description": "Removes or keeps whole images of an OvalBee dataset by labels count, asset tags, classes, image size, and object-level conditions (area share, box aspect, geometry, object tag), combined with And or Or, then adds the selected images to a destination dataset. It acts on whole images - an image matches the object conditions when one of its objects satisfies all of them at once, and the image moves to the destination with all of its labels. To clean up individual labels instead, use Filter annotations.",
  "category": "Filter",
  "namespace": "ovalbee",
  "templateKey": "filter/filter_images",
  "version": "v1",
  "inputs": [
    {
      "key": "SRC_DATASET",
      "label": "Source dataset",
      "type": "dataset",
      "description": "Dataset to filter.",
      "required": true,
      "default": null,
      "visibleWhen": null,
      "options": {
        "creatable": false
      }
    },
    {
      "key": "DST_DATASET",
      "label": "Destination dataset",
      "type": "dataset",
      "description": "Where the selected images go. Leave empty to use the node's own output dataset.",
      "required": false,
      "default": null,
      "visibleWhen": null
    },
    {
      "key": "MATCHED_IMAGES",
      "label": "Matched images",
      "type": "select",
      "description": "Remove keeps everything except the matches. Keep keeps only the matches.",
      "required": true,
      "default": "remove",
      "visibleWhen": null,
      "options": {
        "options": [
          {
            "label": "Remove",
            "value": "remove"
          },
          {
            "label": "Keep",
            "value": "keep"
          }
        ]
      }
    },
    {
      "key": "CONDITIONS_OPERATOR",
      "label": "Operator",
      "type": "select",
      "description": "And requires every condition below. Or requires just one of them.",
      "required": true,
      "default": "and",
      "visibleWhen": null,
      "options": {
        "options": [
          {
            "label": "And",
            "value": "and"
          },
          {
            "label": "Or",
            "value": "or"
          }
        ]
      }
    },
    {
      "key": "HAS_TAGS",
      "label": "Has tags",
      "type": "asset_tags",
      "description": "Tags the image or its annotation carries. Write images:key or annotations:key, and add =value to require a value.",
      "required": false,
      "default": "",
      "visibleWhen": null,
      "options": {
        "ref": "SRC_DATASET"
      }
    },
    {
      "key": "HAS_CLASSES",
      "label": "Has classes",
      "type": "ontology",
      "description": "Classes the image must contain at least one of.",
      "required": false,
      "default": null,
      "visibleWhen": null,
      "options": {
        "ref": "SRC_DATASET",
        "selectable": true
      }
    },
    {
      "key": "IMAGE_WIDTH_PX",
      "label": "Image width (px)",
      "type": "range",
      "description": "Pixel width an image must fall within.",
      "required": false,
      "default": null,
      "visibleWhen": null,
      "options": {
        "min": 1,
        "step": 1,
        "type": "integer"
      }
    },
    {
      "key": "IMAGE_HEIGHT_PX",
      "label": "Image height (px)",
      "type": "range",
      "description": "Pixel height an image must fall within.",
      "required": false,
      "default": null,
      "visibleWhen": null,
      "options": {
        "min": 1,
        "step": 1,
        "type": "integer"
      }
    },
    {
      "key": "OBJECTS_COUNT",
      "label": "Objects per image",
      "type": "range",
      "description": "Number of objects an image must have, counted from its annotation.",
      "required": false,
      "default": null,
      "visibleWhen": null,
      "options": {
        "min": 0,
        "step": 1,
        "type": "integer"
      }
    },
    {
      "key": "OBJECT_AREA_PERCENT",
      "label": "Object area (%)",
      "type": "range",
      "description": "Share of the image one object covers, in percent.",
      "required": false,
      "default": null,
      "visibleWhen": null,
      "options": {
        "min": 0,
        "max": 100,
        "step": 0.5
      }
    },
    {
      "key": "OBJECT_BOX_ASPECT",
      "label": "Object box aspect",
      "type": "range",
      "description": "How stretched one object is: its long side over its short side. 1 is a square.",
      "required": false,
      "default": null,
      "visibleWhen": null,
      "options": {
        "min": 1,
        "step": 0.1
      }
    },
    {
      "key": "OBJECT_GEOMETRY",
      "label": "Object geometry",
      "type": "select",
      "description": "Shape the object is drawn with.",
      "required": false,
      "default": null,
      "visibleWhen": null,
      "options": {
        "options": [
          {
            "label": "Rectangle",
            "value": "rectangle"
          },
          {
            "label": "Polygon",
            "value": "polygon"
          },
          {
            "label": "Bitmap",
            "value": "bitmap"
          },
          {
            "label": "Alpha mask",
            "value": "alpha_mask"
          },
          {
            "label": "Point",
            "value": "point"
          },
          {
            "label": "Line",
            "value": "line"
          },
          {
            "label": "Graph",
            "value": "graph"
          }
        ]
      }
    },
    {
      "key": "OBJECT_TAG",
      "label": "Object tag",
      "type": "string",
      "description": "Tag the object carries. Write key, or key=value to require a value.",
      "required": false,
      "default": null,
      "visibleWhen": null
    }
  ],
  "outputs": [
    {
      "key": "DATASET",
      "label": "Dataset",
      "type": "dataset",
      "description": "ID of the destination dataset with selected images.",
      "artifact": true,
      "badge": false,
      "badgeOpens": null,
      "hidden": false
    },
    {
      "key": "LAST_IMAGES_COUNT",
      "label": "Last Images Count",
      "type": "string",
      "description": "Number of images added to the destination dataset.",
      "artifact": false,
      "badge": true,
      "badgeOpens": "DATASET",
      "hidden": false
    }
  ]
}
```