@deluksic/opencv-calibration-wasm
v0.2.5
Published
Browser-ready OpenCV calibrateCameraRO WASM package
Maintainers
Readme
OpenCV Calibration WASM Build
Standalone npm package for browser camera calibration using OpenCV calibrateCameraRO (and related functions) compiled to WebAssembly.
API
Exports:
initCalibrator({ wasmPath })— loads the WASM module and returns a calibrator.CALIBRATION_FLAGS— OpenCV-compatible bitmasks.
The returned calibrator object:
calibrator.calibrateCameraRO(input)— intrinsics, extrinsics, andnewObjPointswhen object-release is active.calibrator.solvePnP(input)— estimates per-frame pose (rvec,tvec) from 2D/3D correspondences.calibrator.projectPoints(input)— projects 3D points to image space.calibrator.module— low-level Emscripten module (advanced use only).
The wrapper stays close to OpenCV: you pass multiview objectPoints and imagePoints; calibration optimizes the joint model OpenCV uses.
Each call to initCalibrator creates an independent calibrator instance bound to the provided wasmPath.
Basic usage
import {
initCalibrator,
CALIBRATION_FLAGS
} from "@deluksic/opencv-calibration-wasm";
import CALIBRATE_WASM_PATH from "@deluksic/opencv-calibration-wasm/wasm/calibrate.wasm?url";
const calibrator = await initCalibrator({ wasmPath: CALIBRATE_WASM_PATH });
const calib = calibrator.calibrateCameraRO({
objectPoints,
imagePoints,
imageSize: { width, height },
iFixedPoint: 1,
flags: CALIBRATION_FLAGS.CALIB_RATIONAL_MODEL,
criteria: { type: 3, maxCount: 30, epsilon: 1e-3 },
maxDistCoeffs: 14
});
const reproj = calibrator.projectPoints({
objectPoints: Array.from({ length: calib.viewCount }, () => calib.newObjPoints),
rvecs: calib.rvecs,
tvecs: calib.tvecs,
cameraMatrix: calib.cameraMatrix,
distortionCoefficients: calib.distortionCoefficients
});
const pose = calibrator.solvePnP({
objectPoints: objectPointsForOneFrame,
imagePoints: imagePointsForOneFrame,
cameraMatrix: calib.cameraMatrix,
distortionCoefficients: calib.distortionCoefficients
});Calibration flags
Use CALIBRATION_FLAGS instead of raw hex literals:
CALIB_USE_INTRINSIC_GUESSCALIB_FIX_ASPECT_RATIOCALIB_FIX_PRINCIPAL_POINTCALIB_ZERO_TANGENT_DISTCALIB_FIX_FOCAL_LENGTHCALIB_FIX_K1...CALIB_FIX_K6CALIB_RATIONAL_MODELCALIB_THIN_PRISM_MODELCALIB_FIX_S1_S2_S3_S4CALIB_TILTED_MODELCALIB_FIX_TAUX_TAUYCALIB_FIX_TANGENT_DIST
Important OpenCV behavior
When calibration runs in object-release mode (iFixedPoint > 0 and < pointsPerView - 1):
- The optimized model includes
newObjPoints, not only camera parameters. - Reprojection should use those optimized object points for consistency with solved poses.
- OpenCV asserts if
CALIB_USE_INTRINSIC_GUESSis combined with object-release mode in this path. The wrapper throws a clear JS error for this case.
Repository layout
src/native/wrapper.cpp- C++ WASM wrappersrc/index.ts- high-level TypeScript APIscripts/build-opencv.sh- macOS reproducible OpenCV buildscripts/build-wrapper.sh- WASM wrapper builddist/- package output for publish
Prerequisites (macOS)
third_party/opencvpresent- emsdk available via one of:
EMSDKenvironment variablethird_party/emsdkemcmakeonPATH
cmakeandninja
Setup emsdk from third_party/emsdk
If you use the vendored emsdk, install and activate it once:
cd third_party/emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh # or set PATH as instructedBuild
pnpm build:ts
pnpm build:opencv
pnpm build:wasmbuild:ts removes dist/index.js, dist/index.d.ts, then runs tsc. It does not touch dist/wasm/.
Artifacts:
dist/index.jsdist/index.d.tsdist/wasm/calibrate.jsdist/wasm/calibrate.wasm
Example usage (Node smoke test)
pnpm exampleBrowser / Vite
Use Vite's ?url import for the .wasm file and pass that URL to initCalibrator.
import { initCalibrator } from "@deluksic/opencv-calibration-wasm";
import CALIBRATE_WASM_PATH from "@deluksic/opencv-calibration-wasm/wasm/calibrate.wasm?url";
const calibrator = await initCalibrator({ wasmPath: CALIBRATE_WASM_PATH });
const result = calibrator.calibrateCameraRO(input);Provide the .wasm URL to initCalibrator({ wasmPath }) (for example via ?url in Vite).
