Skip to content

Commit

Permalink
C++ examples & roundtrip tests for image/segmentation-image/depth-ima…
Browse files Browse the repository at this point in the history
…ge/tensor (#3899)

### What

* Fixes #3380
* Part of #2919

commit history is a bit messy because this was based on the annotation
context example pr. Speaking off, I made those a bit nicer on the way


### 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/3899) (if
applicable)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG

- [PR Build Summary](https://build.rerun.io/pr/3899)
- [Docs
preview](https://rerun.io/preview/c324163602dfdde33684cae0f9365fd72b177ad3/docs)
<!--DOCS-PREVIEW-->
- [Examples
preview](https://rerun.io/preview/c324163602dfdde33684cae0f9365fd72b177ad3/examples)
<!--EXAMPLES-PREVIEW-->
- [Recent benchmark results](https://ref.rerun.io/dev/bench/)
- [Wasm size tracking](https://ref.rerun.io/dev/sizes/)
  • Loading branch information
Wumpf authored Oct 18, 2023
1 parent e664c74 commit 582f2fd
Show file tree
Hide file tree
Showing 34 changed files with 893 additions and 195 deletions.
3 changes: 2 additions & 1 deletion crates/re_types/definitions/rerun/archetypes/depth_image.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ namespace rerun.archetypes;
/// \example depth_image_simple !api title="Simple example" image="https://static.rerun.io/depth_image_simple/9598554977873ace2577bddd79184ac120ceb0b0/1200w.png"
/// \example depth_image_3d title="Depth to 3D example" image="https://static.rerun.io/depth_image_3d/f78674bdae0eb25786c6173307693c5338f38b87/1200w.png"
table DepthImage (
"attr.rust.derive": "PartialEq"
"attr.rust.derive": "PartialEq",
"attr.cpp.no_field_ctors"
) {
// --- Required ---

Expand Down
3 changes: 2 additions & 1 deletion crates/re_types/definitions/rerun/archetypes/image.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ namespace rerun.archetypes;
///
/// \example image_simple image="https://static.rerun.io/image_simple/06ba7f8582acc1ffb42a7fd0006fad7816f3e4e4/1200w.png"
table Image (
"attr.rust.derive": "PartialEq"
"attr.rust.derive": "PartialEq",
"attr.cpp.no_field_ctors"
) {
// --- Required ---

Expand Down
2 changes: 1 addition & 1 deletion crates/re_types/src/archetypes/image_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl Image {
assign_if_none(&mut data.shape[non_empty_dim_inds[1]].name, "width");
}
3 => match data.shape[non_empty_dim_inds[2]].size {
3 | 4 => {
1 | 3 | 4 => {
assign_if_none(&mut data.shape[non_empty_dim_inds[0]].name, "height");
assign_if_none(&mut data.shape[non_empty_dim_inds[1]].name, "width");
assign_if_none(&mut data.shape[non_empty_dim_inds[2]].name, "depth");
Expand Down
3 changes: 2 additions & 1 deletion crates/re_types/src/archetypes/tensor.rs

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

2 changes: 1 addition & 1 deletion crates/re_types/src/archetypes/tensor_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl Tensor {
///
/// If too many, or too few names are provided, this function will warn and only
/// update the subset of names that it can.
pub fn with_names(self, names: impl IntoIterator<Item = impl Into<ArrowString>>) -> Self {
pub fn with_dim_names(self, names: impl IntoIterator<Item = impl Into<ArrowString>>) -> Self {
let names: Vec<_> = names.into_iter().map(|x| Some(x.into())).collect();
if names.len() != self.data.0.shape.len() {
re_log::warn_once!(
Expand Down
17 changes: 7 additions & 10 deletions docs/code-examples/annotation_context_segmentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include <rerun.hpp>

#include <algorithm>

int main() {
auto rec = rerun::RecordingStream("rerun_example_annotation_context_connections");
rec.connect("127.0.0.1:9876").throw_on_failure();
Expand All @@ -19,17 +21,12 @@ int main() {
const int HEIGHT = 8;
const int WIDTH = 12;
std::vector<uint8_t> data(WIDTH * HEIGHT, 0);
for (auto y = 0; y < 4; ++y) { // top half
auto row = data.begin() + y * WIDTH;
std::fill(row, row + 6, 1); // left half
for (auto y = 0; y < 4; ++y) { // top half
std::fill_n(data.begin() + y * WIDTH, 6, 1); // left half
}
for (auto y = 4; y < 8; ++y) { // bottom half
auto row = data.begin() + y * WIDTH;
std::fill(row + 6, row + 12, 2); // right half
for (auto y = 4; y < 8; ++y) { // bottom half
std::fill_n(data.begin() + y * WIDTH + 6, 6, 2); // right half
}

rec.log(
"segmentation/image",
rerun::SegmentationImage(rerun::TensorData({HEIGHT, WIDTH}, std::move(data)))
);
rec.log("segmentation/image", rerun::SegmentationImage({HEIGHT, WIDTH}, std::move(data)));
}
35 changes: 35 additions & 0 deletions docs/code-examples/depth_image_3d.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Create and log a depth image.

#include <rerun.hpp>

#include <algorithm>

int main() {
auto rec = rerun::RecordingStream("rerun_example_depth_image");
rec.connect("127.0.0.1:9876").throw_on_failure();

// Create a synthetic depth image.
const int HEIGHT = 8;
const int WIDTH = 12;
std::vector<uint16_t> data(WIDTH * HEIGHT, 65535);
for (auto y = 0; y < 4; ++y) { // top half
std::fill_n(data.begin() + y * WIDTH, 6, 20000); // left half
}
for (auto y = 4; y < 8; ++y) { // bottom half
std::fill_n(data.begin() + y * WIDTH + 6, 6, 45000); // right half
}

// If we log a pinhole camera model, the depth gets automatically back-projected to 3D
rec.log(
"world/camera",
rerun::Pinhole::focal_length_and_resolution(
{20.0f, 20.0f},
{static_cast<float>(WIDTH), static_cast<float>(HEIGHT)}
)
);

rec.log(
"world/camera/depth",
rerun::DepthImage({HEIGHT, WIDTH}, std::move(data)).with_meter(10000.0)
);
}
23 changes: 23 additions & 0 deletions docs/code-examples/depth_image_simple.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Create and log a depth image.

#include <rerun.hpp>

#include <algorithm>

int main() {
auto rec = rerun::RecordingStream("rerun_example_depth_image");
rec.connect("127.0.0.1:9876").throw_on_failure();

// create a synthetic depth image.
const int HEIGHT = 8;
const int WIDTH = 12;
std::vector<uint16_t> data(WIDTH * HEIGHT, 65535);
for (auto y = 0; y < 4; ++y) { // top half
std::fill_n(data.begin() + y * WIDTH, 6, 20000); // left half
}
for (auto y = 4; y < 8; ++y) { // bottom half
std::fill_n(data.begin() + y * WIDTH + 6, 6, 45000); // right half
}

rec.log("depth", rerun::DepthImage({HEIGHT, WIDTH}, std::move(data)).with_meter(10000.0));
}
25 changes: 25 additions & 0 deletions docs/code-examples/image_simple.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Create and log a image.

#include <rerun.hpp>

int main() {
auto rec = rerun::RecordingStream("rerun_example_image_simple");
rec.connect("127.0.0.1:9876").throw_on_failure();

// Create a synthetic image.
const int HEIGHT = 8;
const int WIDTH = 12;
std::vector<uint8_t> data(WIDTH * HEIGHT * 3, 0);
for (size_t i = 0; i < data.size(); i += 3) {
data[i] = 255;
}
for (auto y = 0; y < 4; ++y) { // top half
auto row = data.begin() + y * WIDTH * 3;
for (auto i = 0; i < 6 * 3; i += 3) { // left half
row[i] = 0;
row[i + 1] = 255;
}
}

rec.log("image", rerun::Image({HEIGHT, WIDTH, 3}, std::move(data)));
}
5 changes: 0 additions & 5 deletions docs/code-examples/roundtrips.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,11 @@
"any_values": ["cpp", "rust"], # Not yet implemented
"asset3d_out_of_tree": ["cpp"], # TODO(#2919): Not yet implemented in C++
"custom_data": ["cpp"], # TODO(#2919): Not yet implemented in C++
"depth_image_3d": ["cpp"], # TODO(#2919): Not yet implemented in C++
"depth_image_simple": ["cpp"], # TODO(#2919): Not yet implemented in C++
"extra_values": ["cpp", "rust"], # Missing examples
"image_advanced": ["cpp", "rust"], # Missing examples
"image_simple": ["cpp"], # TODO(#2919): Not yet implemented in C++
"log_line": ["cpp", "rust", "py"], # Not a complete example -- just a single log line
"quick_start_connect": ["cpp"], # TODO(#3870): Not yet implemented in C++
"scalar_multiple_plots": ["cpp"], # TODO(#2919): Not yet implemented in C++
"segmentation_image_simple": ["cpp"], # TODO(#2919): Not yet implemented in C++
"tensor_simple": ["cpp"], # TODO(#2919): Not yet implemented in C++
"text_log_integration": ["cpp"], # TODO(#2919): Not yet implemented in C++

# This is this script, it's not an example.
Expand Down
32 changes: 32 additions & 0 deletions docs/code-examples/segmentation_image_simple.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Create and log a segmentation image.

#include <rerun.hpp>

#include <algorithm>

int main() {
auto rec = rerun::RecordingStream("rerun_example_annotation_context_connections");
rec.connect("127.0.0.1:9876").throw_on_failure();

// Create a segmentation image
const int HEIGHT = 8;
const int WIDTH = 12;
std::vector<uint8_t> data(WIDTH * HEIGHT, 0);
for (auto y = 0; y < 4; ++y) { // top half
std::fill_n(data.begin() + y * WIDTH, 6, 1); // left half
}
for (auto y = 4; y < 8; ++y) { // bottom half
std::fill_n(data.begin() + y * WIDTH + 6, 6, 2); // right half
}

// create an annotation context to describe the classes
rec.log_timeless(
"/",
rerun::AnnotationContext({
rerun::AnnotationInfo(1, "red", rerun::Rgba32(255, 0, 0)),
rerun::AnnotationInfo(2, "green", rerun::Rgba32(0, 255, 0)),
})
);

rec.log("image", rerun::SegmentationImage({HEIGHT, WIDTH}, std::move(data)));
}
21 changes: 21 additions & 0 deletions docs/code-examples/tensor_simple.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Create and log a tensor.

#include <rerun.hpp>

#include <random>

int main() {
auto rec = rerun::RecordingStream("rerun_example_tensor_simple");
rec.connect("127.0.0.1:9876").throw_on_failure();

std::default_random_engine gen;
std::uniform_int_distribution<uint8_t> dist(0, 255);

std::vector<uint8_t> data(8 * 6 * 3 * 5);
std::generate(data.begin(), data.end(), [&] { return dist(gen); });

rec.log(
"tensor",
rerun::Tensor({8, 6, 3, 5}, data).with_dim_names({"batch", "channel", "height", "width"})
);
}
3 changes: 2 additions & 1 deletion docs/code-examples/tensor_simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut data = Array::<u8, _>::default((8, 6, 3, 5).f());
data.map_inplace(|x| *x = rand::random());

let tensor = rerun::Tensor::try_from(data)?.with_names(["batch", "channel", "height", "width"]);
let tensor =
rerun::Tensor::try_from(data)?.with_dim_names(["batch", "channel", "height", "width"]);
rec.log("tensor", &tensor)?;

rerun::native_viewer::show(storage.take())?;
Expand Down
17 changes: 7 additions & 10 deletions rerun_cpp/src/rerun/archetypes/annotation_context.hpp

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

60 changes: 58 additions & 2 deletions rerun_cpp/src/rerun/archetypes/depth_image.hpp

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

Loading

1 comment on commit 582f2fd

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Rust Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.25.

Benchmark suite Current: 582f2fd Previous: e664c74 Ratio
arrow/serialize/elem_count=1/arrow2 405 ns/iter (± 0) 320 ns/iter (± 1) 1.27

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.