Class RoomCalibrationManager#

Nested Relationships#

Nested Types#

Class Documentation#

class RoomCalibrationManager

Multi-camera extrinsic (“room”) calibration via a shared ChArUco board.

Companion to CalibrationManager, which only handles single-camera intrinsics. A camera must already have a valid intrinsic CalibrationData (set_camera_intrinsics()) before its views can contribute to a solve — cv::solvePnP() needs real, non-identity intrinsics to produce a meaningful board pose.

Requires MOSAIC_HAVE_OPENCV — is_available() returns false otherwise.

Workflow
RoomCalibrationManager mgr;
mgr.set_board({7, 5, 40.0, 30.0});
for (int i = 0; i < cameraCount; ++i) mgr.set_camera_intrinsics(i,
settings.cameras[i].calibration);

// Repeat, moving the board through overlapping pairs of camera views:
mgr.feed_shot(simultaneousFrames);

const auto result = mgr.solve(cameraCount, /*referenceCameraIndex=*/0);
if (mgr.is_resolved(2)) { auto rt = mgr.extrinsic_for(2); ... }

std::array<double,3> planePoint, planeNormal;
mgr.use_shot_as_plane(lastShotIndex, 0, planePoint, planeNormal);

Public Functions

RoomCalibrationManager()
~RoomCalibrationManager()
void set_board(const BoardSpec &spec)

Call before the first feed_shot(). Changing the spec after capturing shots requires clear_shots() to discard incompatible data.

void set_camera_intrinsics(int cameraIndex, const CalibrationData &data)

Registers a camera’s already-computed intrinsic calibration (from CalibrationManager). Must be called once per camera before that camera’s frames in feed_shot() can be used — a camera with !data.calibrated is skipped by feed_shot() with a warning.

QVector<CameraShotResult> feed_shot(const QVector<VideoFrame> &frames)

Runs ChArUco detection + per-camera cv::solvePnP() on one simultaneous multi-camera shot. A camera missing from frames (the UI’s per-shot capture timed out waiting for it) or lacking prior intrinsics is simply absent from the accepted shot data, reported as found = false here. Returns one result per input frame, in order.

int shot_count() const
void clear_shots()
SolveResult solve(int cameraCount, int referenceCameraIndex)

Resolves every camera’s extrinsicRt (pose relative to referenceCameraIndex, which always resolves to identity) by BFS over the shared-shot graph accumulated so far (room_frame::bfs_resolve()). Also computes each directly-observed camera’s own reprojection RMS (its solvePnP fit quality, independent of any BFS chain length).

bool is_resolved(int cameraIndex) const
std::array<double, 16> extrinsic_for(int cameraIndex) const
double reprojection_rms_for(int cameraIndex) const
bool use_shot_as_plane(int shotIndex, int cameraIndex, std::array<double, 3> &outPoint, std::array<double, 3> &outNormal) const

Uses the board’s own pose from a specific (shot, camera) pair — where the board was presumably lying flat on the target surface — as the room’s reference plane. Both the shot’s camera detection and that camera’s own extrinsic resolution (solve() already called) must exist. outNormal is the board’s printed-face normal (its local Z axis) in room coordinates. Returns false if no matching detection exists or the camera is unresolved.

Public Static Functions

static bool is_available()
struct BoardSpec

ChArUco board geometry.

Public Members

int cols = 7

Number of squares, horizontally.

int rows = 5

Number of squares, vertically.

double squareLengthMm = 40.0

Physical side length of one square, in mm.

double markerLengthMm = 30.0

Physical side length of one ArUco marker, in mm.

struct CameraShotResult

Outcome of one camera’s board detection within a single shot.

Public Members

int cameraIndex = -1
bool found = false

true if enough ChArUco corners were found to solve a pose.

int cornerCount = 0
struct SolveResult

Outcome of a solve() call.

Public Members

std::vector<bool> resolved

index = cameraIndex

std::vector<double> reprojectionRmsPx

index = cameraIndex; -1 = never directly seen