From 4e2afe5d942333256b0b38b0305213c27fc074c9 Mon Sep 17 00:00:00 2001 From: Juan Pablo Pino Bravo Date: Thu, 27 Aug 2026 21:17:32 +0200 Subject: [PATCH 1/3] feat: add mask_box anchor to SegmentationMask The mask bitmap covers mask_box (the raw detection position), while ObjectDetection.bounding_box may be smoothed by tracking. Clients should scale the mask to mask_box, falling back to bounding_box when unset. Counts stay packed uint16 LE: runs longer than 65535 are split with zero-length runs of the opposite class. Co-Authored-By: Claude Fable 5 --- protobuf_definitions/message_formats.proto | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/protobuf_definitions/message_formats.proto b/protobuf_definitions/message_formats.proto index 1371d433..331bc0a8 100644 --- a/protobuf_definitions/message_formats.proto +++ b/protobuf_definitions/message_formats.proto @@ -1711,21 +1711,31 @@ message BoundingBox { uint32 height = 4; // Height of the bounding box (px). } -// RLE-encoded binary segmentation mask relative to the bounding box. +// RLE-encoded binary segmentation mask with its own anchor box. // // The mask bitmap has dimensions (mask_width x mask_height) covering the -// detection's bounding box area. The counts field stores run-length encoded -// data as packed uint16 little-endian: alternating background/foreground -// pixel runs starting with background. +// mask_box region of the camera image. The counts field stores run-length +// encoded data as packed uint16 little-endian: alternating +// background/foreground pixel runs starting with background. Runs longer +// than 65535 pixels are split by inserting a zero-length run of the +// opposite class (e.g. 70000 becomes 65535, 0, 4465), so decoders need no +// special handling — a zero-length run just toggles the class. +// +// Scale the mask to mask_box, not to the detection's bounding_box: the +// bounding box may be smoothed by tracking, while mask_box is pinned to the +// raw detection position, so the mask stays on the actual object pixels. +// If mask_box is unset (all zero — messages from older drone versions), +// fall back to scaling the mask to the detection's bounding_box. message SegmentationMask { uint32 mask_width = 1; // Width of the RLE bitmap. uint32 mask_height = 2; // Height of the RLE bitmap. bytes counts = 3; // RLE counts as packed uint16 little-endian. + BoundingBox mask_box = 4; // Image region the mask bitmap covers (raw detection position, not the tracking-smoothed bounding box). } // A single object detection from a computer vision model. message ObjectDetection { - BoundingBox bounding_box = 1; // Bounding box of the detected object. + BoundingBox bounding_box = 1; // Bounding box of the detected object (may be smoothed by tracking). float confidence = 2; // Detection confidence score (0..1). uint32 class_id = 3; // Numeric class identifier from the model. string class_name = 4; // Human-readable class name. From 0652f1d124a9f326282bbad4df91220508c173c9 Mon Sep 17 00:00:00 2001 From: Juan Pablo Pino Bravo Date: Thu, 27 Aug 2026 21:31:54 +0200 Subject: [PATCH 2/3] docs: drop the mask_box fallback note No deployed drones publish masks without mask_box, so clients should always scale the mask to mask_box. Co-Authored-By: Claude Fable 5 --- protobuf_definitions/message_formats.proto | 2 -- 1 file changed, 2 deletions(-) diff --git a/protobuf_definitions/message_formats.proto b/protobuf_definitions/message_formats.proto index 331bc0a8..d3115aae 100644 --- a/protobuf_definitions/message_formats.proto +++ b/protobuf_definitions/message_formats.proto @@ -1724,8 +1724,6 @@ message BoundingBox { // Scale the mask to mask_box, not to the detection's bounding_box: the // bounding box may be smoothed by tracking, while mask_box is pinned to the // raw detection position, so the mask stays on the actual object pixels. -// If mask_box is unset (all zero — messages from older drone versions), -// fall back to scaling the mask to the detection's bounding_box. message SegmentationMask { uint32 mask_width = 1; // Width of the RLE bitmap. uint32 mask_height = 2; // Height of the RLE bitmap. From 6fab2aa951f7a3c286c9e45499c05e2ba5895f40 Mon Sep 17 00:00:00 2001 From: Juan Pablo Pino Bravo Date: Thu, 27 Aug 2026 21:33:06 +0200 Subject: [PATCH 3/3] style: keep the mask_box comment within the line limit Co-Authored-By: Claude Fable 5 --- protobuf_definitions/message_formats.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protobuf_definitions/message_formats.proto b/protobuf_definitions/message_formats.proto index d3115aae..32b3ea61 100644 --- a/protobuf_definitions/message_formats.proto +++ b/protobuf_definitions/message_formats.proto @@ -1728,7 +1728,7 @@ message SegmentationMask { uint32 mask_width = 1; // Width of the RLE bitmap. uint32 mask_height = 2; // Height of the RLE bitmap. bytes counts = 3; // RLE counts as packed uint16 little-endian. - BoundingBox mask_box = 4; // Image region the mask bitmap covers (raw detection position, not the tracking-smoothed bounding box). + BoundingBox mask_box = 4; // Image region the mask bitmap covers (raw detection position, never smoothed). } // A single object detection from a computer vision model.