IntrinsicCalibrator
SUMMARY
IntrinsicCalibrator recovers a single camera's intrinsic matrix and distortion coefficients from a stack of calibration-board images. One class dispatches on whichever target you pass it, no separate class per board type.
The Skill
from telekinesis.axon import IntrinsicCalibrator, IntrinsicOptionsThe Code
from telekinesis.axon import IntrinsicCalibrator, IntrinsicOptions
from telekinesis.axon.targets import CharucoTarget
target = CharucoTarget(squares_x=6, squares_y=9, square_length=0.012, marker_length=0.009)
options = IntrinsicOptions()
options.per_view_error_threshold = 0.8
calibrator = IntrinsicCalibrator(target, options)
result = calibrator.calibrate(images)
result.ok # bool
result.intrinsic_matrix # (3, 3) np.ndarray
result.distortion_coefficients
result.reprojection_error
result.successful_indices
result.low_view_error_indicesBackground
The pinhole model

IntrinsicCalibrator fits a pinhole camera model: a 3x3 intrinsic matrix K (focal lengths fx, fy and principal point cx, cy) plus a set of radial and tangential distortion coefficients that describe how the real lens deviates from an ideal pinhole. Given a set of images of a target with known geometry, cv::calibrateCamera solves for K, the distortion coefficients, and a per-view extrinsic pose (rvec, tvec) jointly, by minimizing the reprojection error: the pixel distance between each detected corner and where the fitted model predicts that corner should land.
Reading the fit
reprojection_error (the mean over all views) and per_view_errors (one value per view) are the two numbers that tell you how well the model fits, see Best Practices for how to read them.
Initialization
IntrinsicCalibrator(target, options=IntrinsicOptions())| Parameter | Type | Description |
|---|---|---|
target | ChessboardTarget | CharucoTarget | ArucoTarget | Calibration target, see All Supported Targets. |
options | IntrinsicOptions | Solver tunables, see IntrinsicOptions. |
Related Skills
| Skill | Description |
|---|---|
| Calibrate | Detect the target in every image and run cv::calibrateCamera. |
| Find Corners | Detect the target in a set of images with no calibration solve. |
See also IntrinsicCalibrator State to read back the target, options, and detections of the last calibrate() call.
Best Practices
Collecting a good dataset
| Do this | Why |
|---|---|
| Capture 15-20+ views | Fewer under-constrains the distortion coefficients; beyond ~20-25 good views, additional frames give diminishing returns unless you're specifically trying to cover more of the frame |
| Cover the whole frame, not just the center | Distortion is smallest near the principal point and largest toward the edges and corners; a board that only ever appears centered fits K reasonably but leaves distortion poorly constrained |
| Vary tilt, not just position | A set of fronto-parallel views (board always facing the camera) is close to degenerate for separating focal length from distance |
| Vary distance too, within your operating range | Calibrating at one working distance doesn't generalize to another |
Common pitfalls
| Watch for | Why |
|---|---|
| Motion blur and inconsistent exposure | A blurred or poorly-exposed corner detection is worse than a missing one; per_view_error_threshold in IntrinsicOptions and the resulting low_view_error_indices help you find and exclude these after the fact |
A gap between reprojection_error and individual per_view_errors | A low mean with one or two much higher outliers usually means a bad detection on those frames (motion blur, glare, partial occlusion) rather than a systemic problem; drop them and recalibrate rather than accepting a mean pulled down by otherwise-good views |