Adds PersonTrack/PersonTrackArray msgs and a PersonReidNode that matches
individuals across camera views using HSV colour histogram appearance
features and cosine similarity, with EMA gallery update and 30s stale timeout.
New messages (saltybot_scene_msgs):
msg/PersonTrack.msg — track_id, camera_id, bbox, confidence,
first_seen, last_seen, is_stale
msg/PersonTrackArray.msg — array wrapper with header
New files (saltybot_bringup):
saltybot_bringup/_person_reid.py — pure kinematics (no ROS2 deps)
extract_hsv_histogram() 2-D HS histogram (H=16, S=8 → 128-dim, L2-norm)
cosine_similarity() handles zero/non-unit vectors
match_track() best gallery match above threshold (strict >)
TrackGallery add/update/match/mark_stale/prune_stale
TrackEntry mutable dataclass; EMA feature blend (α=0.3)
saltybot_bringup/person_reid_node.py
Subscribes /camera/color/image_raw + /saltybot/scene/objects (BEST_EFFORT)
Crops COCO person (class_id=0) ROIs; extracts features; matches gallery
Publishes PersonTrackArray on /saltybot/person_tracks at 5 Hz
Parameters: camera_id, similarity_threshold=0.75, stale_timeout_s=30,
max_tracks=20, publish_hz=5.0
test/test_person_reid.py — 50 tests, all passing
Modified:
saltybot_scene_msgs/CMakeLists.txt — register PersonTrack/Array msgs
saltybot_bringup/setup.py — add person_reid console_script
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
20 lines
866 B
Plaintext
20 lines
866 B
Plaintext
# PersonTrack.msg — stable cross-camera person identity track (Issue #322)
|
||
#
|
||
# track_id : monotonically-increasing track ID, stable across camera views
|
||
# camera_id : source camera label ("front", "right", "rear", "left")
|
||
# bbox : last-known bounding box in the source image (centre + size, pixels)
|
||
# confidence : cosine-similarity of the matched appearance feature (0–1);
|
||
# 1.0 for tracks created from a first-time observation
|
||
# first_seen : wall-clock time when this track was first created
|
||
# last_seen : wall-clock time of the most recent appearance observation
|
||
# is_stale : true when (now − last_seen) > stale_timeout_s
|
||
#
|
||
std_msgs/Header header
|
||
uint32 track_id
|
||
string camera_id
|
||
vision_msgs/BoundingBox2D bbox
|
||
float32 confidence
|
||
builtin_interfaces/Time first_seen
|
||
builtin_interfaces/Time last_seen
|
||
bool is_stale
|