[McByte part 2] Feat/mcbyte mask manager#418
Conversation
There was a problem hiding this comment.
Pull request overview
Adds the initial McByte mask-management architecture (manager + generator/propagator abstractions) and wires it into McByteTracker with dummy backends, plus new unit tests to validate the basic temporal pipeline.
Changes:
- Introduces
MaskManager,MaskOutput,TrackletSnapshot, and mask generator/propagator base interfaces (with dummy implementations). - Integrates mask-management state into
McByteTracker(previous-frame buffering and per-frame mask update call). - Adds unit tests covering dummy mask generation, mask-manager lifecycle, and a basic McByte tracking sequence.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/core/test_mcbyte_tracker.py | Adds a basic McByteTracker smoke test using CMC + repeated detections. |
| tests/core/test_mcbyte_mask_manager.py | Adds unit tests for MaskManager behavior and dummy generator/propagator backends. |
| src/trackers/core/mcbyte/utils.py | Adds McByte lifecycle helper (get_alive_tracklets) and score fusion helper. |
| src/trackers/core/mcbyte/tracklet.py | Implements McByteTracklet with scale-aware noise and CMC application support. |
| src/trackers/core/mcbyte/tracker.py | Implements McByteTracker and integrates optional MaskManager pipeline state. |
| src/trackers/core/mcbyte/masks/base.py | Defines TrackletSnapshot, MaskOutput, and abstract generator/propagator interfaces. |
| src/trackers/core/mcbyte/masks/dummy.py | Adds dummy box-mask generator and identity propagator for scaffolding/tests. |
| src/trackers/core/mcbyte/masks/init.py | Re-exports mask components for convenient imports. |
| src/trackers/core/mcbyte/mask_manager.py | Adds MaskManager orchestration for init + propagation timing. |
| src/trackers/core/mcbyte/init.py | Exposes McByteTracker from the mcbyte subpackage. |
| if not self._initialized or self.mask_propagator is None: | ||
| mask_output = self.mask_generator.generate(previous_frame, previous_tracklets) | ||
| self._initialized = True | ||
|
|
||
| if self.mask_propagator is not None: | ||
| self.mask_propagator.initialize(previous_frame, mask_output) | ||
| propagated_output = self.mask_propagator.propagate(frame) | ||
| return propagated_output if propagated_output is not None else mask_output | ||
|
|
||
| return mask_output | ||
|
|
||
| propagated_output = self.mask_propagator.propagate(frame) | ||
| if propagated_output is not None: | ||
| return propagated_output | ||
|
|
||
| mask_output = self.mask_generator.generate(previous_frame, previous_tracklets) | ||
| self.mask_propagator.initialize(previous_frame, mask_output) | ||
| return mask_output |
| """ | ||
| self.tracks = [] | ||
| self.frame_id = 0 | ||
| McByteTracklet.count_id = 0 |
| self._previous_frame = None if frame is None else frame.copy() | ||
| self._previous_tracklets = [] | ||
|
|
||
| if detections.tracker_id is None: | ||
| return | ||
|
|
||
| for xyxy, tracker_id in zip(detections.xyxy, detections.tracker_id): | ||
| if tracker_id < 0: | ||
| continue | ||
| self._previous_tracklets.append( | ||
| TrackletSnapshot( | ||
| tracker_id=int(tracker_id), | ||
| xyxy=xyxy.copy(), | ||
| ) | ||
| ) | ||
|
|
| import numpy as np | ||
| import supervision as sv | ||
| from deprecate import deprecated | ||
| from scipy.optimize import linear_sum_assignment | ||
|
|
There was a problem hiding this comment.
It's kept consistent with the existing BoT-SORT and CMC deprecation style, which already imports deprecated from deprecate in runtime source files.
| class McByteTracker(BaseTracker): | ||
| tracker_id = "mcbyte" | ||
|
|
||
| def __init__( | ||
| self, | ||
| lost_track_buffer: int = 30, | ||
| frame_rate: float = 30.0, | ||
| track_activation_threshold: float = 0.7, | ||
| minimum_consecutive_frames: int = 2, | ||
| minimum_iou_threshold_first_assoc: float = 0.2, | ||
| minimum_iou_threshold_second_assoc: float = 0.5, | ||
| minimum_iou_threshold_unconfirmed_assoc: float = 0.3, | ||
| high_conf_det_threshold: float = 0.6, | ||
| enable_cmc: bool = True, | ||
| cmc_method: CMCMethod = "sparseOptFlow", | ||
| cmc_downscale: int = 2, | ||
| instant_first_frame_activation: bool = True, | ||
| state_estimator_class: type[BaseStateEstimator] = XCYCWHStateEstimator, | ||
| iou: BaseIoU | None = None, | ||
| enable_mask_manager: bool = False, | ||
| mask_manager: MaskManager | None = None, | ||
| ) -> None: | ||
| # Calculate maximum frames without update based on lost_track_buffer and |
5fdd43a to
e05fed6
Compare
f9ec49e to
c6843d0
Compare
| from trackers.core.mcbyte.masks.dummy import ( | ||
| DummyBoxMaskGenerator, | ||
| DummyIdentityMaskPropagator, | ||
| ) |
There was a problem hiding this comment.
It was used to see/demonstrate that implementations of MaskGenerator and MaskPropagator can be successfully imported and used.
Now, to make it cleaner, Dummy masks are limited to the explicit masks.dummy module import. Adjusted in 588b852.
Thanks for pointing it out!
What does this PR do?
Adds the initial mask manager infrastructure for McByte.
This PR introduces:
MaskManagerMaskOutputandTrackletSnapshotMcByteTrackerThe current implementation is intentionally lightweight and uses dummy mask generation/propagation to establish the architecture before integrating SAM/Cutie and mask-aware association logic.
The tracker integration is currently passive and focused on validating the temporal mask-management pipeline and interfaces.
Type of Change
Testing
Test details:
Added tests for:
Checklist
McByteTrackerclass code will provided when finalized. Currently still in development.Additional Context
This PR is part of a larger staged McByte integration effort.
The current implementation focuses on establishing clean abstractions and testable infrastructure before integrating external segmentation/mask propagation backends (SAM and Cutie).