You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 17:37:01