调用cv2.solvePnP触发断言失败错误的排查求助
解决OpenCV solvePnP断言失败问题
问题背景
实现了一个调用OpenCV solvePnP的函数,用于计算相机外参:
def solvePnP(points_3d: list[list[float]], points_2d: list[list[int]], camera_mat: np.ndarray, dist_coeffs: np.ndarray): points_3d = np.array(points_3d) points_2d = np.array(points_2d) success, rvec, tvec = cv2.solvePnP(points_3d, points_2d, camera_mat, dist_coeffs) if success: return rvec, tvec
调用时传入的参数维度符合要求(12组3D/2D点、3x3内参、1x5畸变系数),但触发断言失败错误:
cv2.error: OpenCV(4.11.0) /Users/xperience/GHA-Actions-OpenCV/_work/opencv-python/opencv-python/opencv/modules/calib3d/src/solvepnp.cpp:824: error: (-215:Assertion failed) ( (npoints >= 4) || (npoints == 3 && flags == SOLVEPNP_ITERATIVE && useExtrinsicGuess) || (npoints >= 3 && flags == SOLVEPNP_SQPNP) ) && npoints == std::max(ipoints.checkVector(2, CV_32F), ipoints.checkVector(2, CV_64F)) in function 'solvePnPGeneric'
错误原因分析
断言失败的核心是2D点的数据类型不符合要求:
- OpenCV的
solvePnP要求2D点必须是float32或float64类型; - 传入的
points_2d是int类型数组,导致ipoints.checkVector(2, CV_32F)和ipoints.checkVector(2, CV_64F)都返回-1,max结果为-1,与实际点数量(12)不相等,触发断言。
解决方案
修改函数中2D点的转换代码,强制转换为浮点类型:
def solvePnP(points_3d: list[list[float]], points_2d: list[list[int]], camera_mat: np.ndarray, dist_coeffs: np.ndarray): points_3d = np.array(points_3d, dtype=np.float64) # 关键:将2D点转换为float32/float64类型 points_2d = np.array(points_2d, dtype=np.float32) success, rvec, tvec = cv2.solvePnP(points_3d, points_2d, camera_mat, dist_coeffs) if success: return rvec, tvec
额外检查项:
- 确保3D点和2D点的数量完全一致(当前为12组,符合要求);
- 确认内参矩阵和畸变系数的维度、类型正确(当前为浮点类型,无问题)。
内容的提问来源于stack exchange,提问作者Tommy Llewellyn
相关产品推荐
相关产品推荐

