From 9f48f09dd2c2aeca2fefdb3b1ed103332118dc5c Mon Sep 17 00:00:00 2001 From: Walter Perdan Date: Sat, 13 Jun 2026 17:12:57 +0200 Subject: [PATCH] fix(tracker): declare tracking lost when the marker leaves the frame Two coupled changes so the tracker stops emitting 'found' with a stale pose after the marker is gone: 1. Run the optical-flow + template-match path on (_isDetected || _isTracking), not only _isDetected. WebARKit resets _isDetected every frame and detects every frame, so once the marker leaves, MatchFeatures fails (_isDetected=false) and the track/validate path was skipped entirely -- loss was never evaluated. (ArtoolkitX gets this for free because its _isDetected persists and detection is guarded.) 2. Reset _valid in RunTemplateMatching's failure path. Template matching is the appearance check; on a static background optical flow keeps the points (no failure) but the marker template no longer matches, so updateTrackableHomography fails. runOpticalFlow's failure path already cleared _valid; RunTemplateMatching's did not, so isValid() stayed true and getMarker kept firing. ArtoolkitX has no _valid and treats !_isDetected && !_isTracking as not-visible (IsTrackableVisible). Fixes webarkit/WebARKitLib#46 Co-Authored-By: Claude Opus 4.8 --- .../WebARKitTracker.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/WebARKit/WebARKitTrackers/WebARKitOpticalTracking/WebARKitTracker.cpp b/WebARKit/WebARKitTrackers/WebARKitOpticalTracking/WebARKitTracker.cpp index 2d4df3a..bfd8933 100644 --- a/WebARKit/WebARKitTrackers/WebARKitOpticalTracking/WebARKitTracker.cpp +++ b/WebARKit/WebARKitTrackers/WebARKitOpticalTracking/WebARKitTracker.cpp @@ -297,6 +297,14 @@ class WebARKitTracker::WebARKitTrackerImpl { // _trackables[trackableId]._isDetected = false; _isTracking = false; _isDetected = false; + // WebARKitLib#46: template matching is the appearance check -- if it fails + // (the tracked region no longer looks like the marker, e.g. the marker + // left the frame and optical flow drifted onto static background), the + // marker is lost. Clear _valid too so isValid() turns false and the + // tracker reports 'not found'. runOpticalFlow's failure path already does + // this; ArtoolkitX has no _valid and treats !isDetected && !isTracking as + // "not visible" (IsTrackableVisible). + this->_valid = false; _currentlyTrackedMarkers--; } if (_trackVizActive) { @@ -344,7 +352,15 @@ class WebARKitTracker::WebARKitTrackerImpl { MatchFeatures(frameKeyPts, frameDescr); } int i = 0; - if (_isDetected) { + // WebARKitLib#46: also run optical flow while tracking, not only on a fresh + // detection. When the marker leaves the frame, MatchFeatures fails + // (_isDetected = false) but _isTracking is still true; running optical flow + // here lets it fail on the now-absent marker and clear _isTracking/_valid + // (via updateTrackableHomography), so isValid() turns false and the tracker + // reports 'not found' instead of staying stuck on a stale pose. It also + // bridges momentary detection dropouts with a fresh pose while the marker is + // still present. + if (_isDetected || _isTracking) { WEBARKIT_LOGd("Start tracking!\n"); if (_frameCount > 0 && _prevPyramid.size() > 0) { // if (_prevPyramid.size() > 0) {