Skip to content

Commit

Permalink
Python SDK: Rename ImageEncoded to ImageEncodedHelper
Browse files Browse the repository at this point in the history
This is to make room for a new `archetypes.ImageEncoded`.

`ImageEncodedHelper` handles both image files (JPEG, PNG, …)
and chroma sub-sampled data (NV12, YUY2).

In the new design, the former will be handled by `ImageEncoded`,
but chroma-subsampled images will be stored directly as `Image`s,
with a special `PixelFormat`.

This means that once 0.18 is done, only users using chroma subsampling
will have to update their code. I'll make sure the new `ImageEncoded`
archetype ctor supports all of the same parameters as the old helper,
so that there are helpful runtime error messages for our users.
  • Loading branch information
emilk committed Jul 14, 2024
1 parent 83762df commit 0634bab
Show file tree
Hide file tree
Showing 19 changed files with 43 additions and 36 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

# ⚠️ Breaking changes
* `mesh_material: Material` has been renamed to `albedo_factor: AlbedoFactor` [#6841](https://github.com/rerun-io/rerun/pull/6841)
* Python: `ImageEncoded` has been renamed `ImageEncodedHelper`

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


## [0.17.0](https://github.com/rerun-io/rerun/compare/0.16.1...0.17.0) - More Blueprint features and better notebooks - 2024-07-08
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace rerun.archetypes;
/// Rerun also supports compressed image encoded as JPEG, N12, and YUY2.
/// Using these formats can save a lot of bandwidth and memory.
/// \py To compress an image, use [`rerun.Image.compress`][].
/// \py To pass in an already encoded image, use [`rerun.ImageEncoded`][].
/// \py To pass in an already encoded image, use [`rerun.ImageEncodedHelper`][].
/// \rs See [`crate::components::TensorData`] for more.
/// \cpp See [`rerun::datatypes::TensorBuffer`] for more.
///
Expand Down
6 changes: 5 additions & 1 deletion docs/content/reference/migration/migration-0-18.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
---
title: Migrating from 0.17 to 0.18
title: Migrating from 0.17 to 0.18 (unreleased)
order: 180
---

NOTE! Rerun 0.18 has not yet been released


## ⚠️ Breaking changes
### `ImageEncoded`
* `ImageEncoded` has been renamed to `ImageEncodedHelper`


### `mesh_material: Material` has been renamed to `albedo_factor: AlbedoFactor` [#6841](https://github.com/rerun-io/rerun/pull/6841)
The field `mesh_material` in `Mesh3D` is now named `albedo_factor` and wraps a `datatypes.Rgba32`.

Expand Down
2 changes: 1 addition & 1 deletion docs/snippets/all/archetypes/image_advanced.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
rr.init("rerun_example_image_advanced", spawn=True)

# Log the image from the file.
rr.log("from_file", rr.ImageEncoded(path=file_path))
rr.log("from_file", rr.ImageEncodedHelper(path=file_path))

# Read with Pillow and NumPy, and log the image.
image = np.array(Image.open(file_path))
Expand Down
6 changes: 3 additions & 3 deletions examples/python/nuscenes_dataset/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Visualize the [nuScenes dataset](https://www.nuscenes.org/) including lidar, rad
</picture>

## Used Rerun types
[`Transform3D`](https://www.rerun.io/docs/reference/types/archetypes/transform3d), [`Points3D`](https://www.rerun.io/docs/reference/types/archetypes/points3d), [`Boxes3D`](https://www.rerun.io/docs/reference/types/archetypes/boxes3d), [`Pinhole`](https://www.rerun.io/docs/reference/types/archetypes/pinhole), [`Image`](https://ref.rerun.io/docs/python/0.14.1/common/image_helpers/#rerun.ImageEncoded)<sup>*</sup>
[`Transform3D`](https://www.rerun.io/docs/reference/types/archetypes/transform3d), [`Points3D`](https://www.rerun.io/docs/reference/types/archetypes/points3d), [`Boxes3D`](https://www.rerun.io/docs/reference/types/archetypes/boxes3d), [`Pinhole`](https://www.rerun.io/docs/reference/types/archetypes/pinhole), [`ImageEncodedHelper`](https://ref.rerun.io/docs/python/0.17.0/common/image_helpers)<sup>*</sup>

## Background
This example demonstrates the ability to read and visualize scenes from the nuScenes dataset, which is a public large-scale dataset specifically designed for autonomous driving.
Expand Down Expand Up @@ -90,9 +90,9 @@ rr.log(f"world/ego_vehicle/{sensor_name}", rr.Points3D(points, colors=point_colo
```

### Camera data
Camera data is logged as encoded images using [`ImageEncoded`](https://ref.rerun.io/docs/python/0.14.1/common/image_helpers/#rerun.ImageEncoded).
Camera data is logged as encoded images using [`ImageEncodedHelper`](https://ref.rerun.io/docs/python/0.17.0/common/image_helpers).
```python
rr.log(f"world/ego_vehicle/{sensor_name}", rr.ImageEncoded(path=data_file_path))
rr.log(f"world/ego_vehicle/{sensor_name}", rr.ImageEncodedHelper(path=data_file_path))
```

### Radar data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def log_cameras(first_camera_tokens: list[str], nusc: nuscenes.NuScenes, max_tim
sensor_name = sample_data["channel"]
rr.set_time_seconds("timestamp", sample_data["timestamp"] * 1e-6)
data_file_path = nusc.dataroot / sample_data["filename"]
rr.log(f"world/ego_vehicle/{sensor_name}", rr.ImageEncoded(path=data_file_path))
rr.log(f"world/ego_vehicle/{sensor_name}", rr.ImageEncodedHelper(path=data_file_path))
current_camera_token = sample_data["next"]


Expand Down
2 changes: 1 addition & 1 deletion examples/python/nv12/nv12.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def main() -> None:
continue
rr.log(
"NV12",
rr.ImageEncoded(
rr.ImageEncodedHelper(
contents=bytes(bgr2nv12(frame)),
format=rr.ImageFormat.NV12((frame.shape[0], frame.shape[1])),
),
Expand Down
6 changes: 3 additions & 3 deletions examples/python/objectron/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Visualize the [Google Research Objectron](https://github.com/google-research-dat
</picture>

## Used Rerun types
[`Points3D`](https://www.rerun.io/docs/reference/types/archetypes/points3d), [`Boxes3D`](https://www.rerun.io/docs/reference/types/archetypes/boxes3d), [`Image`](https://ref.rerun.io/docs/python/0.14.1/common/image_helpers/#rerun.ImageEncoded)<sup>*</sup>, [`Transform3D`](https://www.rerun.io/docs/reference/types/archetypes/transform3d), [`Pinhole`](https://www.rerun.io/docs/reference/types/archetypes/pinhole)
[`Points3D`](https://www.rerun.io/docs/reference/types/archetypes/points3d), [`Boxes3D`](https://www.rerun.io/docs/reference/types/archetypes/boxes3d), [`ImageEncodedHelper`](https://ref.rerun.io/docs/python/0.17.0/common/image_helpers)<sup>*</sup>, [`Transform3D`](https://www.rerun.io/docs/reference/types/archetypes/transform3d), [`Pinhole`](https://www.rerun.io/docs/reference/types/archetypes/pinhole)

## Background

Expand Down Expand Up @@ -60,9 +60,9 @@ rr.log(
),
)
```
The input video is logged as a sequence of [`ImageEncoded`](https://ref.rerun.io/docs/python/0.14.1/common/image_helpers/#rerun.ImageEncoded) objects to the `world/camera` entity.
The input video is logged as a sequence of [`ImageEncodedHelper`](https://ref.rerun.io/docs/python/0.17.0/common/image_helpers) objects to the `world/camera` entity.
```python
rr.log("world/camera", rr.ImageEncoded(path=sample.image_path))
rr.log("world/camera", rr.ImageEncodedHelper(path=sample.image_path))
```

### Sparse point clouds
Expand Down
2 changes: 1 addition & 1 deletion examples/python/objectron/objectron/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def log_ar_frames(samples: Iterable[SampleARFrame], seq: Sequence) -> None:
rr.set_time_seconds("time", sample.timestamp)
frame_times.append(sample.timestamp)

rr.log("world/camera", rr.ImageEncoded(path=sample.image_path))
rr.log("world/camera", rr.ImageEncodedHelper(path=sample.image_path))
log_camera(sample.frame.camera)
log_point_cloud(sample.frame.raw_feature_points)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def log_calibrated_cameras(self, jpeg_quality: int | None) -> None:
with Image.open(self.path.parent / camera.uri) as img:
rr.log(entity + "/image/rgb", rr.Image(np.array(img)).compress(jpeg_quality=jpeg_quality))
else:
rr.log(entity + "/image/rgb", rr.ImageEncoded(path=self.path.parent / camera.uri))
rr.log(entity + "/image/rgb", rr.ImageEncodedHelper(path=self.path.parent / camera.uri))


def main() -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def read_and_log_sparse_reconstruction(dataset_path: Path, filter_output: bool,
rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)
rr.log("camera/image", rr.Image(rgb).compress(jpeg_quality=75))
else:
rr.log("camera/image", rr.ImageEncoded(path=dataset_path / "images" / image.name))
rr.log("camera/image", rr.ImageEncodedHelper(path=dataset_path / "images" / image.name))

rr.log("camera/image/keypoints", rr.Points2D(visible_xys, colors=[34, 138, 167]))

Expand Down
4 changes: 2 additions & 2 deletions rerun_py/docs/gen_common_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,14 @@ class Section:
class_list=[
"archetypes.DepthImage",
"archetypes.Image",
"ImageEncoded",
"ImageEncodedHelper",
"archetypes.SegmentationImage",
],
gen_page=False,
),
Section(
title="Image Helpers",
class_list=["ImageEncoded"],
class_list=["ImageEncodedHelper"],
show_tables=False,
),
Section(
Expand Down
2 changes: 1 addition & 1 deletion rerun_py/rerun_sdk/rerun/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
notebook as notebook,
)
from ._image import (
ImageEncoded as ImageEncoded,
ImageEncodedHelper as ImageEncodedHelper,
ImageFormat as ImageFormat,
)
from ._log import (
Expand Down
2 changes: 1 addition & 1 deletion rerun_py/rerun_sdk/rerun/_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def __init__(self, size_hint: tuple[int, int]) -> None:
ImageFormat.YUY2 = YUY2


class ImageEncoded(AsComponents):
class ImageEncodedHelper(AsComponents):
"""
A monochrome or color image encoded with a common format (PNG, JPEG, etc.).
Expand Down
2 changes: 1 addition & 1 deletion rerun_py/rerun_sdk/rerun/archetypes/image.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions rerun_py/rerun_sdk/rerun/archetypes/image_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from ..error_utils import _send_warning_or_raise, catch_and_log_exceptions

if TYPE_CHECKING:
from .._image import ImageEncoded
from .._image import ImageEncodedHelper
from ..components import TensorDataBatch
from ..datatypes import TensorDataArrayLike
from . import Image
Expand All @@ -22,9 +22,9 @@ class ImageExt:

JPEG_TYPE_ID = list(f.name for f in TensorBufferType().storage_type).index("JPEG")

def compress(self, *, jpeg_quality: int = 95) -> ImageEncoded | Image:
def compress(self, *, jpeg_quality: int = 95) -> ImageEncodedHelper | Image:
"""
Converts an `Image` to an [`rerun.ImageEncoded`][] using JPEG compression.
Converts an `Image` to an [`rerun.ImageEncodedHelper`][] using JPEG compression.
JPEG compression works best for photographs. Only RGB or Mono images are
supported, not RGBA. Note that compressing to JPEG costs a bit of CPU time,
Expand All @@ -40,7 +40,7 @@ def compress(self, *, jpeg_quality: int = 95) -> ImageEncoded | Image:

from PIL import Image as PILImage

from .._image import ImageEncoded
from .._image import ImageEncodedHelper
from . import Image

self = cast(Image, self)
Expand Down Expand Up @@ -77,7 +77,7 @@ def compress(self, *, jpeg_quality: int = 95) -> ImageEncoded | Image:
pil_image.save(output, format="JPEG", quality=jpeg_quality)
jpeg_bytes = output.getvalue()
output.close()
return ImageEncoded(contents=jpeg_bytes)
return ImageEncodedHelper(contents=jpeg_bytes)

# On failure to compress, still return the original image
return self
Expand Down
6 changes: 3 additions & 3 deletions rerun_py/tests/unit/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,13 @@ def test_image_compress() -> None:
image_data = np.asarray(rng.uniform(0, 255, (10, 20, 3)), dtype=np.uint8)

compressed = rr.Image(image_data).compress(jpeg_quality=80)
assert type(compressed) == rr.ImageEncoded
assert type(compressed) == rr.ImageEncodedHelper

# Mono Supported
image_data = np.asarray(rng.uniform(0, 255, (10, 20)), dtype=np.uint8)

compressed = rr.Image(image_data).compress(jpeg_quality=80)
assert type(compressed) == rr.ImageEncoded
assert type(compressed) == rr.ImageEncodedHelper

# RGBA Not supported
with pytest.warns(RerunWarning) as warnings:
Expand All @@ -127,7 +127,7 @@ def test_image_compress() -> None:
image.save(bin, format="jpeg")

# Jump through some hoops to make a pre-compressed image
img_encoded = rr.ImageEncoded(contents=bin)
img_encoded = rr.ImageEncodedHelper(contents=bin)
img = rr.Image(img_encoded.data)

with pytest.warns(RerunWarning) as warnings:
Expand Down
14 changes: 7 additions & 7 deletions rerun_py/tests/unit/test_image_encoded.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_image_encoded_png() -> None:
image = Image.new("RGBA", (300, 200), color=(0, 0, 0, 0))
image.save(file_path)

img = rr.ImageEncoded(path=file_path)
img = rr.ImageEncodedHelper(path=file_path)

assert img.data.shape[0].size == 200
assert img.data.shape[1].size == 300
Expand All @@ -27,7 +27,7 @@ def test_image_encoded_jpg() -> None:
image = Image.new("RGB", (300, 200), color=(0, 0, 0))
image.save(file_path)

img = rr.ImageEncoded(path=file_path)
img = rr.ImageEncodedHelper(path=file_path)

assert len(img.data.shape) == 3
assert img.data.shape[0].size == 200
Expand All @@ -43,7 +43,7 @@ def test_image_encoded_mono_jpg() -> None:
image = Image.new("L", (300, 200), color=0)
image.save(file_path)

img = rr.ImageEncoded(path=file_path)
img = rr.ImageEncodedHelper(path=file_path)

assert len(img.data.shape) == 3
assert img.data.shape[0].size == 200
Expand All @@ -58,7 +58,7 @@ def test_image_encoded_jpg_from_bytes() -> None:
image = Image.new("RGB", (300, 200), color=(0, 0, 0))
image.save(bin, format="jpeg")

img = rr.ImageEncoded(contents=bin)
img = rr.ImageEncodedHelper(contents=bin)

assert len(img.data.shape) == 3
assert img.data.shape[0].size == 200
Expand All @@ -67,7 +67,7 @@ def test_image_encoded_jpg_from_bytes() -> None:
assert img.data.buffer.kind == "jpeg"

bin.seek(0)
img = rr.ImageEncoded(contents=bin.read())
img = rr.ImageEncodedHelper(contents=bin.read())

assert len(img.data.shape) == 3
assert img.data.shape[0].size == 200
Expand All @@ -82,7 +82,7 @@ def test_image_encoded_mono_jpg_from_bytes() -> None:
image = Image.new("L", (300, 200), color=0)
image.save(bin, format="jpeg")

img = rr.ImageEncoded(contents=bin)
img = rr.ImageEncodedHelper(contents=bin)

assert len(img.data.shape) == 3
assert img.data.shape[0].size == 200
Expand All @@ -91,7 +91,7 @@ def test_image_encoded_mono_jpg_from_bytes() -> None:
assert img.data.buffer.kind == "jpeg"

bin.seek(0)
img = rr.ImageEncoded(contents=bin.read())
img = rr.ImageEncodedHelper(contents=bin.read())

assert len(img.data.shape) == 3
assert img.data.shape[0].size == 200
Expand Down
4 changes: 2 additions & 2 deletions tests/python/chroma_downsample_image/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ def main() -> None:

rr.log(
"img_nv12",
rr.ImageEncoded(
rr.ImageEncodedHelper(
contents=bytes(bgra2nv12(img_bgra)),
format=rr.ImageFormat.NV12((img_bgra.shape[0], img_bgra.shape[1])),
),
)
rr.log(
"img_yuy2",
rr.ImageEncoded(
rr.ImageEncodedHelper(
contents=bytes(bgra2yuy2(img_bgra)),
format=rr.ImageFormat.YUY2((img_bgra.shape[0], img_bgra.shape[1])),
),
Expand Down

0 comments on commit 0634bab

Please sign in to comment.