Skip to content

Commit a8bf4dd

Browse files
authored
Port SegmentationImage to the new image archetype style (#6928)
### What * Part of #6386 * Part of #6844 * Very similar to #6915 ### 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 the web demo (if applicable): * Using examples from latest `main` build: [rerun.io/viewer](https://rerun.io/viewer/pr/6928?manifest_url=https://app.rerun.io/version/main/examples_manifest.json) * Using full set of examples from `nightly` build: [rerun.io/viewer](https://rerun.io/viewer/pr/6928?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json) * [x] The PR title and labels are set such as to maximize their usefulness for the next release's CHANGELOG * [x] If applicable, add a new check to the [release checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)! * [x] If have noted any breaking changes to the log API in `CHANGELOG.md` and the migration guide - [PR Build Summary](https://build.rerun.io/pr/6928) - [Recent benchmark results](https://build.rerun.io/graphs/crates.html) - [Wasm size tracking](https://build.rerun.io/graphs/sizes.html) To run all checks from `main`, comment on the PR with `@rerun-bot full-check`.
1 parent 82abe40 commit a8bf4dd

File tree

37 files changed

+414
-534
lines changed

37 files changed

+414
-534
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* 3D transform APIs: Previously, the transform component was represented as one of several variants (an Arrow union, `enum` in Rust) depending on how the transform was expressed. Instead, there are now several components for translation/scale/rotation/matrices that can live side-by-side in the 3D transform archetype.
88
* Python: `NV12/YUY2` are now logged with the new `ImageChromaDownsampled`
99
* [`ImageEncoded`](https://rerun.io/docs/reference/types/archetypes/image_encoded?speculative-link):s `format` parameter has been replaced with `media_type` (MIME)
10-
* [`DepthImage`](https://rerun.io/docs/reference/types/archetypes/depth_image) is no longer encoded as a tensor, and expects its shape in `[width, height]` order
10+
* [`DepthImage`](https://rerun.io/docs/reference/types/archetypes/depth_image) and [`SegmentationImage`](https://rerun.io/docs/reference/types/archetypes/segmentation_image) are no longer encoded as a tensors, and expects its shape in `[width, height]` order
1111

1212
🧳 Migration guide: http://rerun.io/docs/reference/migration/migration-0-18?speculative-link
1313

crates/store/re_types/definitions/rerun/archetypes/depth_image.fbs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
namespace rerun.archetypes;
22

33

4-
/// A depth image.
4+
/// A depth image, i.e. as captured by a depth camera.
55
///
6-
/// The shape of the [components.TensorData] must be mappable to an `HxW` tensor.
7-
/// Each pixel corresponds to a depth value in units specified by `meter`.
6+
/// Each pixel corresponds to a depth value in units specified by [components.DepthMeter].
87
///
98
/// \cpp Since the underlying `rerun::datatypes::TensorData` uses `rerun::Collection` internally,
109
/// \cpp data can be passed in without a copy from raw pointers or by reference from `std::vector`/`std::array`/c-arrays.

crates/store/re_types/definitions/rerun/archetypes/segmentation_image.fbs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,11 @@ namespace rerun.archetypes;
33

44
/// An image made up of integer [components.ClassId]s.
55
///
6-
/// The shape of the [components.TensorData] must be mappable to an `HxW` tensor.
76
/// Each pixel corresponds to a [components.ClassId] that will be mapped to a color based on annotation context.
87
///
98
/// In the case of floating point images, the label will be looked up based on rounding to the nearest
109
/// integer value.
1110
///
12-
/// Leading and trailing unit-dimensions are ignored, so that
13-
/// `1x640x480x1` is treated as a `640x480` image.
14-
///
1511
/// See also [archetypes.AnnotationContext] to associate each class with a color and a label.
1612
///
1713
/// \cpp Since the underlying `rerun::datatypes::TensorData` uses `rerun::Collection` internally,
@@ -27,8 +23,14 @@ table SegmentationImage (
2723
) {
2824
// --- Required ---
2925

30-
/// The image data. Should always be a 2-dimensional tensor.
31-
data: rerun.components.TensorData ("attr.rerun.component_required", order: 1000);
26+
/// The raw image data.
27+
data: rerun.components.Blob ("attr.rerun.component_required", order: 1000);
28+
29+
/// The size of the image.
30+
resolution: rerun.components.Resolution2D ("attr.rerun.component_required", order: 1500);
31+
32+
/// The data type of the segmentation image data (U16, U32, …).
33+
data_type: rerun.components.ChannelDataType ("attr.rerun.component_required", order: 2000);
3234

3335
// --- Optional ---
3436

crates/store/re_types/definitions/rerun/components/color_model.fbs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ namespace rerun.components;
55
/// Specified what color components are present in an [archetypes.Image].
66
///
77
/// This combined with [components.ChannelDataType] determines the pixel format of an image.
8-
enum ColorModel: byte {
8+
enum ColorModel: byte (
9+
"attr.docs.unreleased"
10+
) {
911
/// Grayscale luminance intencity/brightness/value, sometimes called `Y`
1012
L (default),
1113

crates/store/re_types/definitions/rerun/components/resolution2d.fbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ namespace rerun.components;
22

33
/// The width and height of a 2D image.
44
struct Resolution2D (
5+
"attr.docs.unreleased",
56
"attr.python.aliases": "npt.NDArray[np.int], Sequence[int], Tuple[int, int]",
67
"attr.python.array_aliases": "npt.NDArray[np.int], Sequence[int]",
78
"attr.rust.derive": "Default, Copy, PartialEq, Eq, Hash, bytemuck::Pod, bytemuck::Zeroable",

crates/store/re_types/src/archetypes/depth_image.rs

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/store/re_types/src/archetypes/segmentation_image.rs

Lines changed: 66 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 33 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{
2-
datatypes::TensorData,
2+
components::{ChannelDataType, Resolution2D},
3+
datatypes::{Blob, TensorBuffer, TensorData},
34
image::{find_non_empty_dim_indices, ImageConstructionError},
45
};
56

@@ -16,62 +17,47 @@ impl SegmentationImage {
1617
where
1718
<T as TryInto<TensorData>>::Error: std::error::Error,
1819
{
19-
let mut data: TensorData = data
20+
let tensor_data: TensorData = data
2021
.try_into()
2122
.map_err(ImageConstructionError::TensorDataConversion)?;
2223

23-
let non_empty_dim_inds = find_non_empty_dim_indices(&data.shape);
24+
let non_empty_dim_inds = find_non_empty_dim_indices(&tensor_data.shape);
2425

25-
match non_empty_dim_inds.len() {
26-
2 => {
27-
assign_if_none(&mut data.shape[non_empty_dim_inds[0]].name, "height");
28-
assign_if_none(&mut data.shape[non_empty_dim_inds[1]].name, "width");
26+
if non_empty_dim_inds.len() != 2 {
27+
return Err(ImageConstructionError::BadImageShape(tensor_data.shape));
28+
}
29+
30+
let (blob, data_type) = match tensor_data.buffer {
31+
TensorBuffer::U8(buffer) => (Blob(buffer), ChannelDataType::U8),
32+
TensorBuffer::U16(buffer) => (Blob(buffer.cast_to_u8()), ChannelDataType::U16),
33+
TensorBuffer::U32(buffer) => (Blob(buffer.cast_to_u8()), ChannelDataType::U32),
34+
TensorBuffer::U64(buffer) => (Blob(buffer.cast_to_u8()), ChannelDataType::U64),
35+
TensorBuffer::I8(buffer) => (Blob(buffer.cast_to_u8()), ChannelDataType::I8),
36+
TensorBuffer::I16(buffer) => (Blob(buffer.cast_to_u8()), ChannelDataType::I16),
37+
TensorBuffer::I32(buffer) => (Blob(buffer.cast_to_u8()), ChannelDataType::I32),
38+
TensorBuffer::I64(buffer) => (Blob(buffer.cast_to_u8()), ChannelDataType::I64),
39+
TensorBuffer::F16(buffer) => (Blob(buffer.cast_to_u8()), ChannelDataType::F16),
40+
TensorBuffer::F32(buffer) => (Blob(buffer.cast_to_u8()), ChannelDataType::F32),
41+
TensorBuffer::F64(buffer) => (Blob(buffer.cast_to_u8()), ChannelDataType::F64),
42+
TensorBuffer::Nv12(_) | TensorBuffer::Yuy2(_) => {
43+
return Err(ImageConstructionError::ChromaDownsamplingNotSupported);
2944
}
30-
_ => return Err(ImageConstructionError::BadImageShape(data.shape)),
3145
};
3246

47+
let (height, width) = (
48+
&tensor_data.shape[non_empty_dim_inds[0]],
49+
&tensor_data.shape[non_empty_dim_inds[1]],
50+
);
51+
let height = height.size as u32;
52+
let width = width.size as u32;
53+
let resolution = Resolution2D::from([width, height]);
54+
3355
Ok(Self {
34-
data: data.into(),
56+
data: blob.into(),
57+
resolution,
58+
data_type,
3559
draw_order: None,
3660
opacity: None,
3761
})
3862
}
3963
}
40-
41-
fn assign_if_none(name: &mut Option<::re_types_core::ArrowString>, new_name: &str) {
42-
if name.is_none() {
43-
*name = Some(new_name.into());
44-
}
45-
}
46-
47-
// ----------------------------------------------------------------------------
48-
// Make it possible to create an ArrayView directly from an Image.
49-
50-
macro_rules! forward_array_views {
51-
($type:ty, $alias:ty) => {
52-
impl<'a> TryFrom<&'a $alias> for ::ndarray::ArrayViewD<'a, $type> {
53-
type Error = crate::tensor_data::TensorCastError;
54-
55-
#[inline]
56-
fn try_from(value: &'a $alias) -> Result<Self, Self::Error> {
57-
(&value.data.0).try_into()
58-
}
59-
}
60-
};
61-
}
62-
63-
forward_array_views!(u8, SegmentationImage);
64-
forward_array_views!(u16, SegmentationImage);
65-
forward_array_views!(u32, SegmentationImage);
66-
forward_array_views!(u64, SegmentationImage);
67-
68-
forward_array_views!(i8, SegmentationImage);
69-
forward_array_views!(i16, SegmentationImage);
70-
forward_array_views!(i32, SegmentationImage);
71-
forward_array_views!(i64, SegmentationImage);
72-
73-
forward_array_views!(half::f16, SegmentationImage);
74-
forward_array_views!(f32, SegmentationImage);
75-
forward_array_views!(f64, SegmentationImage);
76-
77-
// ----------------------------------------------------------------------------

0 commit comments

Comments
 (0)