S2.44: confidence on the Roto Brush span bar

Frames a tracker followed are coloured by its confidence (green, amber, red;
slate where the object was absent) and drawn taller; roto_trust reports them.
Not checked visually: no headless way to track without weights in a snapshot.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Kristian Myram
2026-10-30 08:43:31 +01:00
co-authored by Claude Sonnet 5.5
parent 0e0db685bf
commit 1ae5bb9839
3 changed files with 67 additions and 3 deletions
+19
View File
@@ -838,6 +838,25 @@ impl Session {
changed
}
/// How far to trust the frames a tracker followed (SAM 2), by layer frame: its confidence and
/// whether the object was absent. Frames the classic engine made have no entry.
pub fn roto_trust(&self, comp: ItemId, layer: LayerId, effect: Uid) -> BTreeMap<i64, fx::FrameTrust> {
let mut out = BTreeMap::new();
let Some(c) = self.project.comp(comp) else { return out };
let Some(l) = c.layer(layer) else { return out };
let Some(g) = l.props.find_group(effect) else { return out };
if is_object_matte(g) {
return out;
}
let ch = fx::Chain::new(&params_static(g), layer_size(&self.project, c, l), c.frame_rate.as_f64(), 1.0);
for f in ch.keys.keys() {
if let Some(t) = ch.trust_at(*f) {
out.insert(*f, t);
}
}
out
}
/// The computed frames of an instance (full resolution), by layer frame.
pub fn roto_computed(&self, comp: ItemId, layer: LayerId, effect: Uid) -> BTreeMap<i64, bool> {
let mut out = BTreeMap::new();
+7 -1
View File
@@ -977,7 +977,9 @@ impl effectcraft_segment::ObjectTracker for Recorder {
/// corrected frame; the frames before it keep their tracked results.
#[test]
fn a_correction_re_tracks_only_the_frames_it_changes() {
let (mut s, clip, _) = painted(center, "disk-retrack.mov");
let (mut s, clip, uid) = painted(center, "disk-retrack.mov");
let cid = s.active_comp_id().unwrap();
assert!(s.roto_trust(cid, clip, uid).is_empty(), "no tracker data before tracking");
let rec = std::sync::Arc::new(Recorder::default());
effectcraft_effects::roto::set_model(Some(rec.clone()));
let run = |s: &mut Session| s.execute_checked("roto.propagate", json!({"layer": clip.0, "direction": "forward", "wait": true}));
@@ -1000,4 +1002,8 @@ fn a_correction_re_tracks_only_the_frames_it_changes() {
let st = s.execute("roto.status", json!({"layer": clip.0, "frame": 3})).unwrap();
assert_eq!(st["source"], "tracker", "{st}");
assert_eq!(st["tracker"]["frames"].as_object().unwrap().len(), 21, "{st}");
// The span bar's data: the tracker's confidence for every tracked frame.
let trust = s.roto_trust(cid, clip, uid);
assert_eq!(trust.len(), 21);
assert!(trust.values().all(|t| t.confidence > 0.9 && !t.occluded));
}