Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document annotation context in manual #2453

Merged
merged 10 commits into from
Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/code-examples/annotation-context/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Annotation context with two classes, using two labeled classes, of which ones defines a color.
rr.log_annotation_context(
"masks", # Applies to all entities below "masks".
[
rr.AnnotationInfo(id=0, label="Background"),
rr.AnnotationInfo(id=1, label="Person", color=(0, 0, 0)),
Wumpf marked this conversation as resolved.
Show resolved Hide resolved
],
)

# Annotation context with simple keypoints & keypoint connections.
rr.log_annotation_context(
"detections", # Applies to all entities below "detections".
rr.ClassDescription(
info=rr.AnnotationInfo(label="Snake"),
keypoint_annotations=[rr.AnnotationInfo(id=i, color=(0, 255 / 9 * i, 0)) for i in range(10)],
keypoint_connections=[(i, i + 1) for i in range(9)],
),
)
56 changes: 56 additions & 0 deletions docs/code-examples/annotation-context/example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Annotation context with two classes, using two labeled classes, of which ones defines a color.
MsgSender::new("masks") // Applies to all entities below "masks".
.with_timeless(true)
.with_component(&[AnnotationContext {
class_map: [
ClassDescription {
info: AnnotationInfo {
id: 0,
label: Some(Label("Background".into())),
color: None,
},
..Default::default()
},
ClassDescription {
info: AnnotationInfo {
id: 0,
label: Some(Label("Background".into())),
Wumpf marked this conversation as resolved.
Show resolved Hide resolved
color: Some(ColorRGBA(0x000000)),
},
..Default::default()
},
]
.into_iter()
.map(|class| (ClassId(class.info.id), class))
.collect(),
}])?
.send(rec_stream)?;

// Annotation context with simple keypoints & keypoint connections.
MsgSender::new("detections") // Applies to all entities below "detections".
.with_timeless(true)
.with_component(&[AnnotationContext {
class_map: std::iter::once((
ClassId(0),
ClassDescription {
info: AnnotationInfo {
id: 0,
label: Some(Label("Snake".into())),
color: None,
},
keypoint_map: (0..10)
.map(|i| AnnotationInfo {
id: i,
label: None,
color: Some(ColorRGBA::from_rgb(0, (255 / 9 * i) as u8, 0)),
})
.map(|keypoint| (KeypointId(keypoint.id), keypoint))
.collect(),
keypoint_connections: (0..9)
.map(|i| (KeypointId(i), KeypointId(i + 1)))
.collect(),
},
))
.collect(),
}])?
.send(rec_stream)?;
67 changes: 67 additions & 0 deletions docs/content/concepts/annotation-context.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
title: Annotation Context
order: 4
---

## Overview

Any visualization that assigns an identifier ("Class ID") to an instance or entity can profit from using Annotations.
Wumpf marked this conversation as resolved.
Show resolved Hide resolved
By using an Annotation Context, you can associate labels and colors with a given class and then re-use
that class across entities.

This is particularly useful for visualizing the output classifications algorithms
Wumpf marked this conversation as resolved.
Show resolved Hide resolved
(as demonstrated by the [Detect and Track Objects](https://github.com/rerun-io/rerun/tree/latest/examples/python/detect_and_track_objects) example),
but can be used more generally for any kind of reoccurring categorization within a Rerun recording.

![classids](https://static.rerun.io/5508e3fd5b2fdc020eda0bd545ccb97d26a01303_classids.png)

Check warning on line 16 in docs/content/concepts/annotation-context.md

View workflow job for this annotation

GitHub Actions / Spellcheck

Unknown word (classids)
Wumpf marked this conversation as resolved.
Show resolved Hide resolved


### Keypoints & Keypoint Connections

Rerun allows you to define keypoints *within* a class.
Each keypoint can define its own properties (colors, labels, etc.) that overwrite its parent class.

A typical example for keypoints would be the joints of a skeleton within a pose detection:
Wumpf marked this conversation as resolved.
Show resolved Hide resolved
In that case, the entire detected pose/skeleton is assigned a Class ID and each joint within gets a Keypoint ID.

To help you more with this (and similar) usecase(s), you can define connections between keypoints

Check warning on line 27 in docs/content/concepts/annotation-context.md

View workflow job for this annotation

GitHub Actions / Spellcheck

Unknown word (usecase)
Wumpf marked this conversation as resolved.
Show resolved Hide resolved
as part of your annotation class description:
The viewer will draw the connecting lines for all connected keypoints whenever that class is used.
Just as with labels & colors this allows you to use the same connection information on any instance that class in your scene.

Keypoints are currently only applicable to 2D and 3D points.

![keypoints](https://static.rerun.io/a8be4dff9cf1d2793d5a5f0d5c4bb058d1430ea8_keypoints.png)


### Logging an Annotation Context

Annotation Context is typically logged as [timeless](./timelines#timeless-data) data, but can change over time if needed.

The Annotation Context is defined as a list of Class Descriptions that define how classes are styled
(as well as optional keypoint style & connection).

Annotation contexts are logged with:

* Python: [`log_annotation_context`](https://ref.rerun.io/docs/python/latest/common/annotations/#rerun.log_annotation_context)
* Rust: [`AnnotationContext`](https://docs.rs/rerun/latest/rerun/external/re_log_types/component_types/context/struct.AnnotationContext.html)

code-example: annotation-context


## Affected Entities

Each entity that uses a Class ID component (and optionally Keypoint ID components) will look for
the nearest ancestor that in the [entity path hierarchy](./entity-path#path-hierarchy-functions) that has an Annotation Context defined.


## Segmentation images

Segmentation images are single channel integer images/tensors where each pixel represents a class id.
By default, Rerun will automatically assign colors to each class id, but by defining an Annotation Context,
you can explicitly determine the color of each class.

* Python: [`log_segmentation_image`](https://ref.rerun.io/docs/python/latest/common/images/#rerun.log_segmentation_image)
* Rust: Log a [`Tensor`](https://docs.rs/rerun/latest/rerun/components/struct.Tensor.html) with [`TensorDataMeaning::ClassId`](https://docs.rs/rerun/latest/rerun/components/enum.TensorDataMeaning.html#variant.ClassId)

![segmentation image](https://static.rerun.io/7c47738b791a7faaad8f0221a78c027300d407fc_segmentation_image.png)
2 changes: 1 addition & 1 deletion docs/content/concepts/batches.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Batch Data
order: 4
order: 5
---

Rerun has built-in support for batch data. Whenever you have a collection of things that all have the same type, rather
Expand Down
2 changes: 1 addition & 1 deletion docs/content/concepts/entity-path.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Path hierarchy plays an important role in a number of different functions within

* With the [Transform System](spaces-and-transforms.md) the `transform` component logged to any Entity always describes
the relationship between that Entity and its direct parent.
* When resolving the meaning of `class_id` and `keypoint_id` components, Rerun uses the Annotation Context from the nearest ancestor in the hierarchy.
* When resolving the meaning of Class ID and Keypoint ID components, Rerun uses the [Annotation Context](./annotation-context) from the nearest ancestor in the hierarchy.
* When adding data to [Blueprints](../reference/viewer/blueprint.md), it is common to add a path and all of its descendants.
* When using the `log_cleared` API, it is possible to mark an entity and all of its descendants as being cleared.
* In the future, it will also be possible to use path-hierarchy to set default-values for descendants.
Expand Down