Skip to content

Integrate the WebARKit OCVT tracker line: dev → master#60

Merged
kalwalt merged 167 commits into
masterfrom
dev
Jun 21, 2026
Merged

Integrate the WebARKit OCVT tracker line: dev → master#60
kalwalt merged 167 commits into
masterfrom
dev

Conversation

@kalwalt

@kalwalt kalwalt commented Jun 21, 2026

Copy link
Copy Markdown
Member

Integration of the dev branch (the WebARKit OCVT planar-tracker line) into master. 167 commits ahead of the merge base; master has 13 of its own (the NFT/AR vendored side). The two lines touch disjoint subsystems, so this is a clean integration rather than a conflict-heavy merge.

Merge mechanics (verified)

  • git merge-tree reports zero conflicts — the textual merge is clean.
  • Disjoint subsystems: dev = WebARKit/ (the OCVT tracker); master = vendored AR / NFT / KPM / luma (lib/SRC, include/AR). dev touches nothing under lib/SRC/include/AR.
  • Two version lineages coexist (by design, not a conflict):
    • include/AR/config.h1.7.6 (ARToolKit5 / NFT, consumed by jsartoolkitNFT) — from master.
    • WebARKit/.../WebARKitConfig.cpp0.8.0 (the OCVT tracker) — from dev.

Please merge as a merge commit (--no-ff), not squash, to preserve the 167-commit history.

What dev brings (the OCVT tracker, WebARKit/)

Pose / projection / handedness

Tracking robustness & performance

Examples

Code health & docs

Validation

  • CI (test.yml gtest) runs on this PR — covers the OCVT side (already green on dev).
  • Downstream after merge: jsartoolkitNFT build (exercises master's vendored AR/luma/KPM changes) + a webarkit-testing submodule bump to master + rebuild/examples (OCVT WASM).

🤖 Generated with Claude Code

WebARKitOrbTracker classes.
Now only WebARKitTracker is necessary.
- fix for issue webarkit/webarkit-testing#11
- new WebARKitManager class to be improved
kalwalt and others added 15 commits June 16, 2026 18:04
Add an opt-in option so the tracked pose origin is the marker centre instead of the reference image's top-left corner -- AR content at (0,0,0) then sits in the middle of the marker. Default OFF (matches ArtoolkitX, which never centres at any layer, and preserves existing behaviour).

When enabled, the 3D object points are offset by (_pattern.size/2) just before solvePnP: this moves only the solved translation, leaves the rotation unchanged, and the 2D matching/template/homography paths untouched. Exposed as setOriginCentered(bool) via the tracker and manager.

Refs webarkit/webarkit-testing#38

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Restore ArtoolkitX-style detection-side pyramid downsampling: feature
detection now runs on a pyrDown'd copy of the live frame (the
"detectionFrame"), and matched frame keypoints are scaled back to
full-frame coordinates before the homography fit.

- initialize(): compute _featureDetectPyrLevel from featureImageMinSize
  (clamped >= 0) and the exact cv::pyrDown scale factor via the iterative
  (x+1)/2 rounding, so the keypoint rescale is sub-pixel accurate.
- processFrame(): build detectionFrame via _featureDetectPyrLevel pyrDown
  steps; run createFeatureMask/extractFeatures on it.
- MatchFeatures(): rescale matched frame keypoints by
  _featureDetectScaleFactor before getHomographyInliers.
- createFeatureMask(): divide the warped bbox by the scale factor so the
  tracked-marker exclusion lands in downsampled coordinates.

Level 0 (frame <= featureImageMinSize, e.g. 640x480) => detectionFrame ==
frame and factor 1.0, so that path is byte-identical to full-res detection.
The reference image stays detected at full resolution (initTracker), only
the live frame is downsampled, matching ArtoolkitX OCVT.

This is part A of #44. The "skip detection while tracking" guard is a
separate follow-up (part B).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Guard the per-frame feature detection (extractFeatures + descriptor
matching) with `if (!_isTracking)`. Once optical flow holds a lock,
detection is skipped and the pose is maintained by optical flow + template
matching; when the marker is lost (_isTracking cleared in runOpticalFlow /
RunTemplateMatching), detection resumes on the next frame to re-acquire.

Detection is the dominant per-frame cost, so skipping it in the steady
tracking state is a large win: at 640x480 the webcam example goes from
~10-15 fps (detecting every frame) to ~45 fps while tracking. This is
part B of #44; part A (detection-side pyramid downsampling) landed in #52.

The guard is on _isTracking rather than ArtoolkitX's
`_currentlyTrackedMarkers < _maxNumberOfMarkersToTrack`: _isDetected is
reset to false every frame, and optical flow is skipped on the first
detection frame (_frameCount == 0), so a counter-based guard would skip
both detection and optical flow on the following frame and freeze (this
bites the static-image example, which feeds the same frame repeatedly).
Gating on _isTracking re-detects until optical flow actually holds a lock.

The optical-flow/template/pose paths (gated on _isDetected || _isTracking)
and #46 tracking-loss are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
getPoseMatrix() returned a zero matrix: it reads _patternTrackingInfo.pose3d,
which the live tracking path never wrote (the pose flows _pose -> transMat ->
trans; pose3d was touched only by the dead computePose). cameraPoseFromPoints
now also builds pose3d (the raw 4x4 OpenCV-convention pose) from the same
rMat/tvec, so the CV getter reflects the current frame.

Rename the two pose getters so the distinction is explicit (they differ in
both convention and shape, which the "2" suffix hid):
  getPoseMatrix  -> getPoseMatrixCV  (raw OpenCV 4x4 pose)
  getPoseMatrix2 -> getPoseMatrixGL  (right-handed / GL-corrected pose, trans)

Hard rename across WebARKitManager + WebARKitTracker (decls, inner impl, outer
wrapper). The matching emscripten bindings / controller live in webarkit-testing.

Verified: static (1920x1440) and webcam (640x480) examples both track (1000
matches); getPoseMatrixCV() now returns a valid [R|t;0001] (was all zeros).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
update() was declared in the header but never defined or called (the live
per-frame path is processFrameData()). It only linked because nothing
referenced it; calling it would have been a link error. Not scaffolding --
a future update() would be declared with its implementation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
im_gray() was a fully commented-out grayscale routine in WebARKitUtils.h,
superseded by convert2Grayscale(). Pure dead text (git history retains it).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Remove the commented-out multi-marker _trackables[...] lines (the old
artoolkitX-style forms left beside their live single-marker replacements)
and the commented getPoseMatrix3 declarations. Comment-only; the live code
and explanatory comments are untouched, so the compiled output is identical.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…Matrix()

These were WebARKit's own pose-math path, superseded by cameraPoseFromPoints +
the #55 pose3d fix:
- computePose() -- its only call site was already commented out; cameraPoseFromPoints
  is the live pose solve.
- invertPose() -- only ever called by computePose().
- computeGLviewMatrix() (no-arg) -- uncalled; the live path uses the
  computeGLviewMatrix(cv::Mat&) overload (kept).

Also drops the dangling commented computePose call in WebARKitTracker.cpp.
Behavior-neutral; the live pose/GL-view path (cameraPoseFromPoints,
getTrackablePose, updateTrackable, computeGLviewMatrix(cv::Mat&)) is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
README: replace the stub with a developer-oriented map — the two lineages
(WebARKit/ = ArtoolkitX-OCVT-derived active code vs vendored lib/SRC + include/AR
= old ARToolKit5, built by jsartoolkitNFT; ARnft consumes jsartoolkitNFT as an npm
module), code layout, pose pipeline, who-builds-what (webarkit-testing builds
WebARKit/ to WASM via makem.js, CMake migration planned), the gtest/CMake tests,
and the contribution path.

version: 0.8.0 (was 1.0.0) -- 1.0.0 should denote a complete/LTS release, which
this isn't yet. Updates WEBARKIT_HEADER_VERSION_STRING + MAJOR/MINOR.

Refs #51.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The version bump (1.0.0 -> 0.8.0) broke the gtest version checks:
WEBARKIT_HEADER_VERSION_STRING and getWebARKitVersion() are now "0.8.0".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Note in the Building section that WebARKit/CMakeLists.txt can already build
WebARKitLib as a static library today; the "planned" migration is specifically
webarkit-testing moving its WASM build off tools/makem.js onto it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…dency

Clarify the CMake static-lib build: it targets both WASM (emscripten) and native
Linux via EMSCRIPTEN_COMP, and depends on a prebuilt OpenCV from webarkit/opencv-em
(emscripten opencv-js build for WASM, native build for Linux), fetched via FetchContent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributing section now requires commit messages to follow Conventional
Commits and links to ./CONTRIBUTING.md (to be added) for the full guidelines.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add contribution guidelines: branch-from-dev / PR-to-dev, signed commits,
Conventional Commits (with examples), what may/may not change (WebARKit/ vs the
vendored old-ARToolKit5 lib/SRC), the cross-repo PR-pair flow, and build/test
(CMake static lib for WASM/Linux via opencv-em; gtest). README already links here.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Note that the cross-repo PR-pair flow applies to WebARKit/ folder changes consumed
by the webarkit-testing repo as WASM; vendored lib/SRC + include/AR (old ARToolKit5)
changes instead flow through jsartoolkitNFT and don't use it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kalwalt kalwalt self-assigned this Jun 21, 2026
@kalwalt kalwalt added documentation Improvements or additions to documentation enhancement New feature or request C/C++ code concerning the C/C++ code design and improvements Emscripten labels Jun 21, 2026
@kalwalt kalwalt moved this from To do to Review in progress in New markerless image tracking Jun 21, 2026
@kalwalt kalwalt added this to the Markerless tracking milestone Jun 21, 2026
@kalwalt kalwalt moved this from Review in progress to Reviewer approved in New markerless image tracking Jun 21, 2026
@kalwalt kalwalt merged commit ce5c280 into master Jun 21, 2026
1 check passed
@github-project-automation github-project-automation Bot moved this from Reviewer approved to Done in New markerless image tracking Jun 21, 2026
kalwalt added a commit to webarkit/webarkit-testing that referenced this pull request Jun 21, 2026
Point the submodule at WebARKitLib's master tip (the dev->master integration,
webarkit/WebARKitLib#60) instead of dev, and rebuild build/ + dist/. master now
contains the full OCVT tracker line (== dev) plus the vendored AR/NFT side.

Verified: rebuilt cleanly; static + webcam Teblid examples track (v0.8.0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
kalwalt added a commit to webarkit/webarkit-testing that referenced this pull request Jun 21, 2026
Point the submodule at WebARKitLib's master tip (the dev->master integration,
webarkit/WebARKitLib#60) instead of dev, and rebuild build/ + dist/. master now
contains the full OCVT tracker line (== dev) plus the vendored AR/NFT side.

Verified: rebuilt cleanly; static + webcam Teblid examples track (v0.8.0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C/C++ code concerning the C/C++ code design and improvements documentation Improvements or additions to documentation Emscripten enhancement New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant