Skip to content

feat: record matched tracker overlay video#2

Open
Jiu-xiao wants to merge 1 commit intomasterfrom
codex/overlay-recording-20260430
Open

feat: record matched tracker overlay video#2
Jiu-xiao wants to merge 1 commit intomasterfrom
codex/overlay-recording-20260430

Conversation

@Jiu-xiao
Copy link
Copy Markdown
Contributor

@Jiu-xiao Jiu-xiao commented Apr 30, 2026

Summary

  • record overlay.avi alongside raw.avi when record_raw is enabled
  • change tracker overlay default to show tracker center plus matched detector observation / matched EKF face, not all model-completed armor faces
  • add overlay.model_faces for explicit model-face debug rendering
  • add candidate_items.tsv so tracker-selected detector observations can be audited quantitatively

Validation

  • Ubuntu24 capturefile full run reached EOF
  • detector_unique_ts=813, target_rows=813, ekf_unique_ts=813, candidate_rows=813
  • target_tracking_rows=808/813
  • candidate_matched_rows=812/813
  • matched EF projection error p95=35.684px, max=115.781px
  • BSP capturefile and hik preset generate/build PASS with this branch

Artifacts: /root/codex/runs/visionpreview_matchedface_validate_20260430T0516Z and /root/codex/runs/visionpreview_hik_build_20260430T0520Z

Summary by Sourcery

Record a tracker overlay video alongside raw video and enrich tracker/detector visualization and logging for better debugging and quantitative analysis.

New Features:

  • Add recording of an overlay video with drawn detector and tracker information when raw recording is enabled.
  • Introduce a model_faces overlay option to render EKF model-completed armor faces separately from matched faces.
  • Log per-candidate item details to a new candidate_items.tsv file for auditing tracker-selected detector observations.

Enhancements:

  • Refine detector and tracker overlays to highlight tracker-matched detections and EKF faces, focusing the default view on matched observations and tracker center.
  • Factor out projection logic and add matched EKF face drawing with error annotations to improve interpretability of tracking performance.

Documentation:

  • Update README to document overlay video output, new overlay.model_faces option, recorded TSV files, and the color conventions used in the overlays.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 30, 2026

Reviewer's Guide

Adds recording of an overlay video alongside raw video when record_raw is enabled, changes overlay rendering to focus on tracker center and matched detector/EKF faces, introduces optional drawing of full model-completed faces, and records detailed candidate selection items to a new TSV for auditability.

Sequence diagram for frame processing and overlay video recording

sequenceDiagram
    participant Camera
    participant VisionPreview
    participant RawVideoWriter as RawVideo
    participant OverlayVideoWriter as OverlayVideo
    participant PreviewWindow as Preview

    Camera->>VisionPreview: OnImage(bgr, snapshot)
    alt RecordEnabled
        VisionPreview->>VisionPreview: WriteRawVideo(bgr)
        VisionPreview->>RawVideoWriter: write(raw.avi)
    end

    VisionPreview->>VisionPreview: RecordEnabled()
    VisionPreview->>VisionPreview: OverlayEnabled()
    alt !realtime_preview_enabled and not(RecordEnabled and OverlayEnabled)
        VisionPreview-->>Camera: return (no overlay, no preview)
    else proceed
        VisionPreview->>VisionPreview: DrawDetector(canvas, snapshot.detector, snapshot.candidate)
        VisionPreview->>VisionPreview: DrawTracker(canvas, snapshot.ekf, snapshot.detector, snapshot.candidate)
        VisionPreview->>VisionPreview: DrawStatus(canvas, timestamp_us, snapshot)

        alt RecordEnabled and OverlayEnabled
            VisionPreview->>VisionPreview: WriteOverlayVideo(canvas)
            VisionPreview->>OverlayVideoWriter: write(overlay.avi)
        end

        alt !realtime_preview_enabled
            VisionPreview-->>Camera: return (recording only)
        else preview_enabled
            VisionPreview->>VisionPreview: scale canvas if preview_scale != 1.0
            VisionPreview->>PreviewWindow: imshow(preview_window_name)
            PreviewWindow->>VisionPreview: waitKey(preview_wait_key_ms)
        end
    end
Loading

Class diagram for updated VisionPreview overlay recording and candidate logging

classDiagram
    class VisionPreview {
      +bool RecordEnabled()
      +bool OverlayEnabled()
      +void RegisterCallbacks()
      +void DrawDetector(cv::Mat& canvas, DetectorMessage& detector, CandidateDebugMessage* candidate)
      +void DrawTracker(cv::Mat& canvas, EkfPointsMessage& ekf, DetectorMessage* detector, CandidateDebugMessage* candidate)
      +void DrawMatchedEkfFaces(cv::Mat& canvas, EkfPointsMessage& ekf, DetectorMessage* detector, CandidateDebugMessage* candidate)
      +bool ProjectPoint(cv::Mat& canvas, LibXR::Position~double~& point, cv::Point2d& uv)
      +std::array~int, kMaxDetections~ MatchedFaces(CandidateDebugMessage* candidate)
      +void InitRecordFiles()
      +void WriteRawVideo(cv::Mat& bgr)
      +void WriteOverlayVideo(cv::Mat& bgr)
      +void WriteRecords(vector~DetectorMessage~& detector_records, vector~DetectorMetrics~& metrics_records, vector~TargetMessage~& target_records, vector~EkfPointsMessage~& ekf_records, vector~CandidateDebugMessage~& candidate_records)
      +void FlushRecordFiles()
      -std::string image_topic_name_
      -std::string output_dir_
      -std::string raw_video_name_
      -std::string overlay_video_name_
      -std::string preview_window_name_
      -std::ofstream detector_file_
      -std::ofstream metrics_file_
      -std::ofstream target_file_
      -std::ofstream ekf_file_
      -std::ofstream candidate_file_
      -std::ofstream candidate_items_file_
      -cv::VideoWriter raw_writer_
      -cv::VideoWriter overlay_writer_
      -bool raw_writer_ready_
      -bool overlay_writer_ready_
      -bool record_ready_
    }

    class OverlayConfig {
      +bool detector
      +bool tracker
      +bool candidate_debug
      +bool model_faces
    }

    class RuntimeParam {
      +OverlayConfig overlay
      +std::string_view output_dir
      +std::string_view raw_video_name
      +std::string_view overlay_video_name
      +std::string_view preview_window_name
      +double preview_scale
      +int preview_wait_key_ms
      +bool enabled
      +bool record_raw
      +bool realtime_preview
      +int record_fps
    }

    class CandidateDebugMessage {
      <<struct>>
      +static uint8_t kMaxDetections
      +static uint8_t kMaxItems
      +uint64_t image_timestamp_us
      +uint8_t count
      +uint8_t selected_index
      +uint8_t matched
      +uint8_t detection_count
      +uint8_t tracked_armors_num
      +CandidateItem items[kMaxItems]
    }

    class CandidateItem {
      <<struct>>
      +uint8_t armor_index
      +int8_t face_index
      +bool same_number
      +int32_t image_track_id
      +bool image_track_confirmed
      +uint8_t number
      +uint8_t type
      +float score
      +float position_diff
      +float yaw_diff
      +float center_x
      +float center_y
      +float predicted_yaw
      +float measured_yaw
    }

    class EkfPointsMessage {
      <<struct>>
      +uint8_t count
      +bool valid[5]
      +LibXR::Position~double~ center_cam
      +LibXR::Position~double~ armors_cam[4]
    }

    class DetectorMessage {
      <<struct>>
      +vector~ArmorDetection~ results
    }

    class ArmorDetection {
      <<struct>>
      +int color
      +std::array~cv::Point,4~ points
      +cv::Rect box
      +cv::Point2f center
      +int number
      +float confidence
    }

    VisionPreview --> OverlayConfig : uses overlay
    VisionPreview --> RuntimeParam : constructed_from
    VisionPreview --> CandidateDebugMessage : reads_for_debug
    CandidateDebugMessage --> CandidateItem : aggregates
    VisionPreview --> EkfPointsMessage : visualizes_tracker
    VisionPreview --> DetectorMessage : visualizes_detector
    DetectorMessage --> ArmorDetection : contains
Loading

File-Level Changes

Change Details Files
Record overlay preview frames to a separate video when raw recording is enabled, sharing the same gating as overlay rendering.
  • Add overlay_video_name runtime/config option and corresponding member field to VisionPreview.
  • Introduce OverlayEnabled() helper and update frame-processing path to still render overlays when only recording is enabled.
  • Implement WriteOverlayVideo() using cv::VideoWriter and call it when RecordEnabled and any overlay component is active.
  • Track overlay_writer_ state and ensure it is initialized lazily with MJPG codec and frame size from the first frame.
VisionPreview.hpp
README.md
Refine overlay drawing to emphasize tracker center and matched faces between detector and EKF, with configurable model-face debugging.
  • Extend OverlayConfig with model_faces flag and wire it through runtime configuration and README.
  • Add MatchedFaces() helper and change DrawDetector() to accept optional CandidateDebugMessage, highlight matched armors in magenta, and prepend M/index + face info to labels.
  • Refactor 3D-to-2D projection into ProjectPoint() helper and adjust tracker center annotation from T to TC.
  • Add DrawMatchedEkfFaces() to draw EKF projections for matched faces only, including pixel error to corresponding detector centers, and call it from DrawTracker().
  • Change DrawTracker() to accept optional detector/candidate data, separate matched-face rendering from generic model-face rendering, and only draw full model faces when overlay.model_faces is enabled, using updated colors and labels.
VisionPreview.hpp
README.md
Log per-candidate item details into a new TSV to allow quantitative auditing of tracker-selected observations.
  • Create candidate_items_file_ alongside existing TSV outputs, initialize it in OpenRecordFiles(), and include it in error handling and FlushRecordFiles().
  • Write a detailed header for candidate_items.tsv listing indices, matching flags, geometric deltas, and yaw information.
  • Extend WriteRecords() candidate loop to iterate items up to kMaxItems, emitting one row per item with all relevant fields to candidate_items.tsv.
  • Document candidate_items.tsv in README and clarify what gets recorded when record_raw is enabled.
VisionPreview.hpp
README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant