Skip to content

Commit

Permalink
Fix presence of segmentation images and tensor causing generation of …
Browse files Browse the repository at this point in the history
…root space view (#3681)

### What

* Fixes #3677

Definitely need to come up with something better to steer the heuristics
- we made good strides in space view refactor and recent advances in
System heuristics, but there's still a lot to be desired!

In the test scene there's still the issue of a unexplicably large
accumulated bounding box which causes the camera to zoom out a lot. This
is most likely caused by an initially bad heuristic for the frustum
length. I suspect this is a problem we already had in 0.8 and might be
fairly hard to solve until we fixup our blueprint & object property
story.


Before:

![image](https://github.com/rerun-io/rerun/assets/1220815/fa3e3867-aa52-47da-b0a9-83eae9436429)

After:

![image](https://github.com/rerun-io/rerun/assets/1220815/2dd20446-bc68-4c22-99ab-0465f64262dc)


Test code:
```py
"""Log a pinhole and a random image."""
import numpy as np
import rerun as rr

rr.init("rerun_example_pinhole", spawn=True)
rng = np.random.default_rng(12345)

image = rng.uniform(0, 255, size=[3, 3, 3])
rr.log("world/camera/image", rr.Pinhole(focal_length=3, width=3, height=3))
rr.log("world/camera/image", rr.Image(image))

image = rng.uniform(0, 255, size=[3, 3, 1])
rr.log("seg", rr.SegmentationImage(image))
```

Also made sure this doesn't regress the fix in #3583 (which touched this
code last!)

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested [demo.rerun.io](https://demo.rerun.io/pr/3681) (if
applicable)

- [PR Build Summary](https://build.rerun.io/pr/3681)
- [Docs
preview](https://rerun.io/preview/a29d7764be26c9cc746a726c589a284ef7efad8f/docs)
<!--DOCS-PREVIEW-->
- [Examples
preview](https://rerun.io/preview/a29d7764be26c9cc746a726c589a284ef7efad8f/examples)
<!--EXAMPLES-PREVIEW-->
- [Recent benchmark results](https://ref.rerun.io/dev/bench/)
- [Wasm size tracking](https://ref.rerun.io/dev/sizes/)

---------

Co-authored-by: Emil Ernerfeldt <[email protected]>
  • Loading branch information
Wumpf and emilk authored Oct 5, 2023
1 parent 9599e2a commit b26ca17
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 10 deletions.
14 changes: 10 additions & 4 deletions crates/re_viewport/src/space_view_heuristics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ use nohash_hasher::{IntMap, IntSet};

use re_arrow_store::{LatestAtQuery, Timeline};
use re_data_store::EntityPath;
use re_types::archetypes::Image;
use re_types::components::{DisconnectedSpace, TensorData};
use re_types::{Archetype, ComponentNameSet};
use re_types::{
archetypes::{Image, SegmentationImage},
components::{DisconnectedSpace, TensorData},
Archetype, ComponentNameSet,
};
use re_viewer_context::{
AutoSpawnHeuristic, SpaceViewClassName, ViewContextCollection, ViewPartCollection,
ViewSystemName, ViewerContext,
Expand Down Expand Up @@ -129,7 +131,9 @@ fn contains_any_image(ent_path: &EntityPath, store: &re_arrow_store::DataStore)
.all_components(&Timeline::log_time(), ent_path)
.unwrap_or_default()
.iter()
.any(|comp| *comp == Image::indicator().name())
.any(|comp| {
*comp == SegmentationImage::indicator().name() || *comp == Image::indicator().name()
})
}

fn is_interesting_space_view_at_root(
Expand All @@ -142,6 +146,8 @@ fn is_interesting_space_view_at_root(
return false;
}

// TODO(andreas): We have to figure out how to do this kind of heuristic in a more generic way without deep knowledge of re_types.
//
// If there are any images directly under the root, don't create root space either.
// -> For images we want more fine grained control and resort to child-of-root spaces only.
for entity_path in &candidate.contents.root_group().entities {
Expand Down
2 changes: 1 addition & 1 deletion examples/python/controlnet/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Run
```sh
python 3 examples/python/controlnet/main.py
examples/python/controlnet/main.py
```
"""
from __future__ import annotations
Expand Down
4 changes: 3 additions & 1 deletion examples/python/face_tracking/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ def detect_and_log(self, image: npt.NDArray[np.uint8], frame_time_nano: int) ->
# log bounding box
rr.log(
f"video/detector/faces/{i}/bbox",
rr.Boxes2D(array=[bbox.origin_x, bbox.origin_y, bbox.width, bbox.height]),
rr.Boxes2D(
array=[bbox.origin_x, bbox.origin_y, bbox.width, bbox.height], array_format=rr.Box2DFormat.XYWH
),
rr.AnyValues(index=index, score=score),
)

Expand Down
11 changes: 9 additions & 2 deletions examples/python/multiprocessing/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,16 @@ def task(child_index: int) -> None:
), # noqa: E501 line too long
)
if child_index == 0:
rr.log(title, rr.Boxes2D(array=[5, 5, 80, 80], labels=title))
rr.log(title, rr.Boxes2D(array=[5, 5, 80, 80], array_format=rr.Box2DFormat.XYWH, labels=title))
else:
rr.log(title, rr.Boxes2D(array=[10 + child_index * 10, 20 + child_index * 5, 30, 40], labels=title))
rr.log(
title,
rr.Boxes2D(
array=[10 + child_index * 10, 20 + child_index * 5, 30, 40],
array_format=rr.Box2DFormat.XYWH,
labels=title,
),
)


def main() -> None:
Expand Down
2 changes: 1 addition & 1 deletion examples/python/multithreading/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def rect_logger(path: str, color: npt.NDArray[np.float32]) -> None:
rects_xy = np.random.rand(5, 2) * 1024
rects_wh = np.random.rand(5, 2) * (1024 - rects_xy + 1)
rects = np.hstack((rects_xy, rects_wh))
rr.log(path, rr.Boxes2D(array=rects, colors=color))
rr.log(path, rr.Boxes2D(array=rects, array_format=rr.Box2DFormat.XYWH, colors=color))


def main() -> None:
Expand Down
5 changes: 4 additions & 1 deletion examples/python/segment_anything_model/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ def run_segmentation(mask_generator: SamAutomaticMaskGenerator, image: Mat) -> N
rr.log("image/masks", rr.SegmentationImage(segmentation_img.astype(np.uint8)))

mask_bbox = np.array([m["bbox"] for _, m in masks_with_ids])
rr.log("image/boxes", rr.Boxes2D(array=mask_bbox, class_ids=[id for id, _ in masks_with_ids]))
rr.log(
"image/boxes",
rr.Boxes2D(array=mask_bbox, array_format=rr.Box2DFormat.XYWH, class_ids=[id for id, _ in masks_with_ids]),
)


def is_url(path: str) -> bool:
Expand Down
1 change: 1 addition & 0 deletions scripts/run_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
}

MIN_PYTHON_REQUIREMENTS: dict[str : tuple[int, int]] = {
"examples/python/controlnet": (3, 10),
# pyopf requires Python 3.10
"examples/python/open_photogrammetry_format": (3, 10),
}
Expand Down

0 comments on commit b26ca17

Please sign in to comment.