Skip to content

A QR code as a survey point

S edited this page Aug 20, 2026 · 3 revisions

A QR code as a survey point

Most location-based web experiences already involve a QR code: it is how a person standing in a place gets from "there is a sign here" to "I am in the experience", without an install.

The interesting observation is that the same square of ink can do a second job entirely — if you put it somewhere whose real-world position you have measured.

Two jobs, one code

Job one is onboarding. Point the phone camera at the code, tap the notification, the AR scene opens in the browser. No store, no download, no account.

Job two is localisation. A QR code is a planar target of known shape. Detect it in the camera feed, solve its 6-DoF pose relative to the camera, and you know exactly where the camera sits relative to the code. If you also know where the code sits in the world — because you surveyed it when you mounted it — you know where the camera is in the world, from a single frame.

That is a position fix of a quality GNSS cannot approach, available before the user has taken a step.

Not a replacement for GPS — a seed for it

The tempting design is to treat the marker as ground truth and ignore GPS. It is the wrong one, because the user walks away from the marker and the marker stops being visible almost immediately.

The better design feeds the marker-derived position into the same fusion pipeline as GPS, as an observation with much higher confidence:

  • At the first frame, the marker pins the GPS↔AR alignment correctly, with no waiting for the estimator to accumulate evidence from walking.
  • As the user walks away, ordinary GPS observations keep arriving and keep refining the fit, so the alignment stays honest as they roam far past the marker.
  • The marker never has to be seen again — its contribution is already in the estimate.

buildQrGpsVotes is exactly this step: turn a solved marker pose plus the marker's known geo-pose into GPS-shaped observations the fusion consumes. The alignment code does not need a special case for markers; it needs good observations, and this produces them.

Status, stated plainly: this is a set of tested building blocks, not a feature you can switch on today. Detection, the pose solver, the size measurement from depth, the stability window and the vote builder all exist and are covered by tests. What does not exist is an app that wires them together — the QR demo is deliberately geo-less and casts no GPS vote, and no other consumer calls the vote builder. If you want marker-seeded alignment in your own app, the parts are there and the assembly is yours. That is a fair thing to offer and an unfair thing to imply is finished, so: it is the former.

The precondition people skip

This only works if the code is at a known, surveyed spot. That is a real constraint and it is worth being blunt about, because it decides whether you get the feature at all:

  • A code mounted at the trailhead, whose position you measured once when you installed it: a valid survey point. Use it.
  • A code printed on a flyer the user is carrying: worthless as an anchor. It is wherever their hands are. Use it to open the experience and skip marker anchoring entirely.
  • A code on a poster someone may reposition: dangerous. A stale survey point is confidently wrong, which is worse than no anchor.

So the choice is per experience, and the framework's pieces are arranged that way: you can use the code purely for onboarding and rely on GPS+SLAM for grounding, or — with the assembly work described above — use it for both.

The other cost: battery

Running QR detection continuously means processing camera frames continuously, which is not free on a phone that is also running an AR session outdoors. If a code carries no reliable pose, detection is pure cost.

That is the second reason the two modes are separate. An experience that only needs the code to open should not pay to keep looking for it.

What it takes to make it work

Solving a marker pose accurately in practice needs more than a detector:

  • The code's physical size must be known — and it can be measured from the depth map rather than hard-coded, which removes an entire class of "we printed it at 90 % scale" errors.
  • The solved pose must be stabilised across frames, because a single detection has noise in its corner positions.
  • Implausible poses must be rejected against the reconstructed surface of the room.
  • Detection must run on a duty cycle, not every frame.

There is also the pose solver itself, which turned out to need no computer-vision dependency at all. Together they are why "just detect a QR code" is more work than it sounds — and why having it in a framework is worth more than the sum of its parts.

Clone this wiki locally