{"record":{"id":"e9fe9fc7c6b47710","repo":"ruvnet/RuView","slug":"solvepnp-failed","errorCode":null,"errorMessage":"solvePnP failed","messagePattern":"solvePnP failed","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"scripts/calibration_lib.py","lineNumber":224,"sourceCode":"def solve_extrinsics(\n    room_points: np.ndarray,\n    image_points: np.ndarray,\n    camera_matrix: np.ndarray,\n    dist_coeffs: np.ndarray,\n) -> dict:\n    \"\"\"Solve the camera->room rigid transform from 3D room-frame points and\n    their 2D pixel observations.\n\n    NOTE: the corner grid of a single planar checkerboard is centrosymmetric,\n    so the corner ordering returned by findChessboardCorners (which may\n    enumerate from either board end) cannot be disambiguated from one board\n    alone -- the reversed ordering fits a ghost pose with identical\n    reprojection error. Use solve_two_board_extrinsics for the full\n    two-checkerboard procedure, where the joint point set breaks the symmetry.\n    \"\"\"\n    ext = _solve_pnp(room_points, image_points, camera_matrix, dist_coeffs)\n    if ext is None:\n        raise RuntimeError(\"solvePnP failed\")\n    return ext\n\n\ndef solve_two_board_extrinsics(\n    wall_room: np.ndarray,\n    wall_image: np.ndarray,\n    floor_room: np.ndarray,\n    floor_image: np.ndarray,\n    camera_matrix: np.ndarray,\n    dist_coeffs: np.ndarray,\n) -> dict:\n    \"\"\"Joint camera->room solve over both checkerboards (the ADR-152 S2.1.3\n    two-checkerboard method).\n\n    Tries all 4 per-board corner-ordering combinations: each board's ordering\n    is individually ambiguous (centrosymmetric grid), but the combined\n    wall+floor point set is not, so exactly one combination reaches minimal\n    reprojection error. Returns the solve_extrinsics dict plus","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/scripts/calibration_lib.py#L206-L242","documentation":"The single-board extrinsics wrapper calls cv2.solvePnP (via _solve_pnp); a None return means OpenCV could not fit a camera pose to the 3D room points and 2D pixel observations, and the wrapper raises RuntimeError. The docstring warns that one planar checkerboard is centrosymmetric — corner ordering from findChessboardCorners is ambiguous from a single board — so the two-board procedure (solve_two_board_extrinsics) is the supported path.","triggerScenarios":"Calling the single-board solve with degenerate inputs: too few or collinear points, object points mismatched to the detected corners (wrong cols/rows/square_size), or intrinsics from a different camera/resolution.","commonSituations":"Blurry or glare-affected checkerboard photos; cols and rows swapped when generating board_object_points; square size entered in cm while room points are meters.","solutions":["Use solve_two_board_extrinsics (wall + floor, the ADR-152 S2.1.3 procedure) instead of the single-board solve","Check len(room_points) == len(image_points) and that ordering matches findChessboardCorners (cols varies fastest)","Verify board_object_points used the correct cols, rows, and square_size in meters","Recapture sharper, evenly lit photos and confirm the intrinsics match the capture camera"],"exampleFix":"# before\next = solve_board_extrinsics(room_points, image_points, K, D)  # RuntimeError\n\n# after\next = solve_two_board_extrinsics(\n    wall_room, wall_image, floor_room, floor_image, K, D\n)","handlingStrategy":"try-catch","validationCode":"assert len(room_points) == len(image_points) >= 6, \\\n    \"need matching 3D/2D point sets of at least 6 corners\"\n# single planar boards are ambiguous; prefer the two-board solve","typeGuard":null,"tryCatchPattern":"try:\n    ext = solve_board_extrinsics(room, image, K, D)\nexcept RuntimeError:\n    # single-board failure/ambiguity — fall back to the two-board procedure\n    ext = solve_two_board_extrinsics(\n        wall_room, wall_image, floor_room, floor_image, K, D\n    )","preventionTips":["Default to the two-checkerboard ADR-152 procedure for extrinsics","Verify point counts, ordering, and units (meters) before any PnP call","Log reprojection RMSE per candidate to catch bad detections early"],"tags":["opencv","calibration","pnp","geometry","computer-vision"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}