Files
dora-image-view/dora-node.yml
T
cristhian 8a7bda5867 use std/media/v1/Image for image and depth
Both inputs now declare dora's Arrow struct {width, height, encoding, data}
rather than a flat buffer plus loose metadata. The payload describes itself, so
nothing about its shape has to be agreed out of band, and the frame travels as
one Arrow value instead of a buffer whose meaning lives in a sidecar dict.

Depth uses the same type. dora's registry has no depth type, and a depth map is
an image whose pixels are distances -- the reading ROS takes as well -- so it
arrives with a single-channel encoding: 32FC1/float32 or 16UC1/mono16/uint16.
`units` stays in message metadata because the struct has no field for it.

decode.IMAGE_TYPE is the single definition of the struct; the example source
and the tests build payloads from it rather than respelling the schema.

The older shapes are still decoded -- a flat UInt8 buffer with
width/height/encoding for image, a flat Float32 buffer with shape/units for
depth -- so a producer's payload can move before its manifest does. That is
only half a migration path: type compatibility is directional, so a producer
still declaring std/core/v1/UInt8 fails validate against an
std/media/v1/Image input regardless of what it sends, and has to update its
manifest too.

Verified: 41 tests, validate clean with 4 contracts injected, the dataflow runs
to a clean exit, and a composite rendered through the struct path is identical
to the one rendered before the migration.
2026-09-15 05:27:40 -03:00

99 lines
4.1 KiB
YAML

# Node manifest: the typed contract a consumer wires against.
#
# No source package is shared between node repositories, so this file and its
# type URNs are the only contract a consumer has. `dora validate` checks a
# dataflow against it without running the node, so CI needs neither OpenCV nor
# a display.
apiVersion: 1
name: dora-image-view
namespace: liria
description: Displays an image and a depth map side by side in an OpenCV window, with bounding box, text and camera intrinsics overlays
categories: [visualization, debug]
keywords: [opencv, view, bbox, bounding-box, image, depth, intrinsics, camera-info, visualization, object-detection]
runtime: python
entrypoint: dora-image-view
# `dora build --uv` / `dora run --uv` rewrites this to `uv pip install .` and
# gives the node its own managed venv under `.dora/python-envs/`, so the
# dependencies it sees at runtime are the ones installed here.
build: pip install .
dora: ">=1.0"
inputs:
image:
type: std/media/v1/Image
required: false
description: >-
Base image to draw on: an Arrow struct {width, height, encoding, data}.
Supported encodings: bgr8, rgb8, jpeg/jpg/jpe/bmp/webp/png (encoded
bytes), yuv420, avif. Receiving this input triggers a redraw and display.
A flat UInt8 buffer described by {width, height, encoding} metadata is
still decoded, for producers that have not moved to the struct.
bbox:
required: false
description: >-
Bounding boxes to overlay: an Arrow struct with fields {bbox, conf,
labels} and metadata {format}. Supported formats: xyxy, xywh. Stored and
drawn on the next image redraw. Deliberately untyped — senders differ in
whether the numeric fields are 32- or 64-bit, and the node casts either.
text:
type: std/core/v1/String
required: false
description: >-
Text string to overlay at the top-left corner. Stored and drawn on the
next image redraw.
camera_info:
type: std/core/v1/Float32
required: false
description: >-
The pinhole model the depth map is interpreted through: [fx, fy, cx, cy],
or a nine-element row-major K as ROS spells it in sensor_msgs/CameraInfo.
Distortion coefficients are read from the `distortion` metadata. Stored
and displayed, and held for readers that turn depth into 3D. A sender
that also puts fx/fy/cx/cy in each frame's metadata does not need to wire
this input -- they are picked up from there, which is what covers a
camera that published its intrinsics before this node started.
depth:
type: std/media/v1/Image
required: false
description: >-
Depth map as an Arrow struct {width, height, encoding, data}, one channel
per pixel. Supported encodings: 32FC1/float32 and 16UC1/mono16/uint16 --
dora has no depth type, and a depth map is an image whose pixels are
distances, which is how ROS spells it too. Millimetres unless the `units`
metadata says `m`; 0 and non-finite values are missing depth and draw
black. Colour-mapped into its own panel, which receiving this input
redraws. A flat Float32 buffer with {shape, units} metadata is still
decoded, for producers that have not moved to the struct.
outputs: {}
env:
VIEW_DEPTH_MIN_MM:
type: float
description: >-
Pin the near end of the depth colour range, in millimetres. Each end is
auto-ranged over the valid pixels of the current frame when it is unset.
VIEW_DEPTH_MAX_MM:
type: float
description: Pin the far end of the depth colour range, in millimetres.
VIEW_WIDTH:
type: int
description: Resize the displayed frame to this width (pixels). Defaults to the image input width.
VIEW_HEIGHT:
type: int
description: Resize the displayed frame to this height (pixels). Defaults to the image input height.
example: |
- id: view
git: ssh://git@gitea.liria.cl:5001/liria/dora-image-view.git
tag: v0.1.0
build: pip install .
path: dora-image-view
inputs:
image: camera/image_bgr
depth: camera/depth
camera_info: camera/camera_info
bbox: detector/bbox
text: detector/text