中文 | English
Screen AprilGrid is a cross-platform Electron application that displays a
pixel-aligned 6 x 6 AprilGrid. It uses AprilTag 36h11 IDs 0 through 35 with
a tag spacing ratio of 0.30, and can export a Kalibr target YAML.
Two tag raster specifications are available. The default Kalibr specification
uses a 6 x 6 data area and a two-module black border on every side, producing
a complete 10 x 10 tag compatible with the default blackTagBorder=2 setting
in Kalibr's ethz_apriltag2. It also includes the official symmetric black
corner patches in each 0.30 tag-spacing gap. The OpenCV specification uses a
one-module border and produces the conventional 8 x 8 OpenCV raster.
The same frontend can still run as a local static page. Browser mode requires no server or network connection. Electron mode adds a dedicated application window, a native save dialog, window-level fullscreen, and multi-display information.
Node.js 22.12.0 or newer is required. With nvm:
source ~/.nvm/nvm.sh
nvm use
npm install
npm startBecause nvm is not loaded from ~/.bashrc, run the source command once in
each newly opened terminal before using nvm.
You can also open src/renderer/index.html directly in a browser. Both modes use
the same AprilGrid calculations and rendering code.
First select the target specification that matches the detector. Enter the active display width and switch to fullscreen. Measure the outer black edge of any displayed tag with a ruler or caliper, enter the measurement, and save the Kalibr target YAML. A measured tag size takes precedence over the size estimated from display width and current display-mode pixels.
| Target specification | Complete tag | Black border | Tag order | Detector |
|---|---|---|---|---|
Kalibr / ethz_apriltag2 (default) |
10 x 10 modules |
2 modules | ID 0 at bottom left, rows increase upward | Stock Kalibr with blackTagBorder=2 |
| OpenCV AprilTag 36h11 | 8 x 8 modules |
1 module | ID 0 at top left, rows increase downward | OpenCV AprilTag detector |
Both specifications use the same 36h11 code data, but their border width, tag
orientation, and row direction differ. Kalibr mode follows the official target's
corner orientation and bottom-up ID rows. Adding one black ring around the
OpenCV raster while retaining its old ID arrangement is therefore insufficient
for a geometrically correct Kalibr target.
Changing Kalibr's detector to blackTagBorder=1 is a separate custom format: it
still needs Kalibr's official rotation and bottom-up ID rows. The OpenCV mode in
this application is intended for an OpenCV detector and is not that custom
Kalibr format.
The Kalibr YAML records tag rows, columns, outer black-edge size, and spacing. It
does not encode the black-border width. Selecting the wrong displayed raster
cannot be corrected in YAML; use the default 10 x 10 specification with an
unmodified Kalibr detector. The two modes use distinct suggested filenames,
although their YAML geometry fields can be identical.
Display APIs cannot reliably report a panel's physical width and may not expose its hardware-native resolution under scaled display modes. The detected pixel width therefore remains editable.
Changing the target specification clears the measured tag size and latest
fullscreen record so values from one raster are not reused for the other.
Auto-fit can produce different tag sizes in a normal window and in fullscreen.
The application records the latest stable fullscreen output; after leaving
fullscreen, the output mode reads 最近全屏 and YAML still uses that fullscreen
size. Moving to another display clears the old physical-width and measured-tag
values. Resolution, scale, or rotation changes also invalidate the old measured
tag value.
| Capability | Browser | Electron |
|---|---|---|
| YAML output | Browser download | Native Save As dialog |
| Fullscreen | Web Fullscreen API | Window fullscreen with F11 and Esc |
| Display data | window.screen and DPR |
Display size, scale factor, and display-change events |
| Runtime | Installed browser | Bundled, fixed Chromium version |
The renderer has no Node.js access. The preload bridge exposes only YAML saving,
fullscreen control, and display information. The main process validates IPC
arguments and blocks new windows, external navigation, and permission requests.
Desktop resources are served through a restricted custom protocol instead of
file://. Release packages disable RunAsNode, NODE_OPTIONS, and extra file
protocol privileges, and enable ASAR integrity validation.
screen_aprilgrid/
├── src/
│ ├── main/main.cjs
│ ├── preload/preload.cjs
│ ├── renderer/
│ │ ├── index.html
│ │ ├── styles.css
│ │ └── app.js
│ └── shared/core.js
├── assets/
├── scripts/generate-icons.cjs
├── tests/
│ ├── core.test.cjs
│ ├── static-page.smoke.cjs
│ ├── electron.smoke.cjs
│ └── fixtures/static-page-main.cjs
├── package.json
└── package-lock.json
npm run check
npm run test:static
npm run test:electron
npm run test:electron:desktopThe first command runs syntax checks and unit tests. The static-page smoke test
loads src/renderer/index.html without a preload bridge and verifies the browser
fallback. npm run test:electron launches the Electron application and verifies
the preload bridge, target rendering, IPC, and fullscreen state; it is safe to
run under xvfb-run on a headless Linux CI host. The desktop variant additionally
checks native fullscreen geometry and Escape handling, so run it in a real
Linux, Windows, or macOS desktop session before a release or after changing
fullscreen and display behavior.
Regenerate the deterministic application icons with npm run icons.
Build on the corresponding host operating system:
npm run dist:linux # AppImage and .deb
npm run dist:win # NSIS .exe installer
npm run dist:mac # .dmg and .zipArtifacts are written to dist/. The repository workflow
.github/workflows/screen-aprilgrid-build.yml builds unsigned packages on
Windows, macOS, and Linux when run manually or when a v* tag
is pushed. Packaging commands build files only; the workflow uploads them as
GitHub Actions artifacts, so they do not require a GitHub publishing token.
Public distribution should add Windows code signing and macOS Developer ID signing and notarization. Unsigned packages are suitable for testing but may trigger operating-system warnings.
Kalibr tags contain 10 x 10 modules, while OpenCV tags contain 8 x 8 modules.
Kalibr mode also draws the official symmetric black corner patches in the gaps.
The application chooses a pixel quantum for the active specification so tag
modules, corner patches, and the 0.30 inter-tag gap remain on integer
device-pixel boundaries. Chromium page zoom is fixed at 100 percent. Use the same
fullscreen state, display mode, system scale, and physical display for
measurement and capture.
This screen target is useful for checking Kalibr detection, recording, and calibration workflows, and for preliminary calibration. A measured, matte, rigid printed target remains preferable for final stereo and camera-IMU calibration.
