cv2.solvePnP 报错 求相机位姿

目录

报错信息及解决:

[cv2.solvePnP 使用例子:](#cv2.solvePnP 使用例子:)

设置初始值效果也不好

[cv2.projectPoints 函数效果不好](#cv2.projectPoints 函数效果不好)


报错信息及解决:

File "/shared_disk/users/lbg/project/human_4d/nlf_pose/render_demo_pkl2_cal.py", line 236, in <module> success, rotation_vector, translation_vector = cv2.solvePnP(vertices, vertices2d, camera_matrix, dist_coeffs) cv2.error: OpenCV(4.10.0) /io/opencv/modules/calib3d/src/solvepnp.cpp:823: 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'

解决方法:

把所有数据都astype(np.float32)

cv2.solvePnP 使用例子:

python 复制代码
import cv2
import numpy as np

# 三维物体点在世界坐标系中的坐标
object_points = np.array([
    [0, 0, 0],
    [0, 1, 0],
    [1, 1, 0],
    [1, 0, 0]
]).astype(np.float32)

# 这些三维点在图像平面上对应的二维像素坐标
image_points = np.array([
    [100, 100],
    [100, 200],
    [200, 200],
    [200, 100]
], dtype=np.float64)

# 相机的内参矩阵
camera_matrix = np.array([
    [1000, 0, 320],
    [0, 1000, 240],
    [0, 0, 1]
], dtype=np.float64)

# 相机的畸变系数
dist_coeffs = np.zeros((5, 1), dtype=np.float32)

# 求解PnP问题
success, rotation_vector, translation_vector = cv2.solvePnP(object_points, image_points, camera_matrix, dist_coeffs)

if success:
    print("旋转向量:")
    print(rotation_vector)
    print("平移向量:")
    print(translation_vector)
else:
    print("求解失败")

设置初始值效果也不好

python 复制代码
import cv2
import numpy as np

# 假设 vertices 和 vertices2d 已经准备好了
# vertices 是 3D 点集合 (Nx3)
# vertices2d 是对应的 2D 点集合 (Nx2)
# camera_matrix 是相机内参矩阵
# dist_coeffs 是畸变系数(如果有)

# 相机的内参矩阵
f_x = 1000  # 焦距 fx
f_y = 1000  # 焦距 fy
c_x = 640   # 主点 cx
c_y = 360   # 主点 cy
camera_matrix = np.array([
    [f_x, 0, c_x],
    [0, f_y, c_y],
    [0, 0, 1]
])

# 畸变系数(假设无畸变)
dist_coeffs = np.zeros(5)

# 初始旋转向量(设为零)
rvec_init = np.zeros(3)  # 初始旋转为零(单位向量)
tvec_init = np.zeros(3)  # 初始平移为零

# 使用 solvePnP 计算平移并强制旋转为零
success, rvec, tvec = cv2.solvePnP(
    vertices,        # 3D 点
    vertices2d,      # 对应的 2D 点
    camera_matrix,   # 相机内参矩阵
    dist_coeffs,     # 畸变系数
    rvec_init,       # 初始旋转向量(零)
    tvec_init,       # 初始平移向量(零)
    useExtrinsicGuess=True  # 使用提供的初始旋转和平移
)

# 输出计算结果
print(f"旋转向量 (rvec): {rvec}")
print(f"平移向量 (tvec): {tvec}")

cv2.projectPoints 函数效果不好

复制代码
import cv2
import numpy as np
from scipy.optimize import least_squares

def project_without_rotation(t, object_points, camera_matrix, dist_coeffs):
    rvec = np.zeros((3, 1))  # 零旋转
    tvec = t.reshape(3, 1)
    projected, _ = cv2.projectPoints(object_points, rvec, tvec, camera_matrix, dist_coeffs)
    return projected.reshape(-1, 2)

def residual(t, object_points, image_points, camera_matrix, dist_coeffs):
    projected = project_without_rotation(t, object_points, camera_matrix, dist_coeffs)
    return (projected - image_points).ravel()

# 输入数据:3D点、2D点、相机矩阵、畸变系数
vertices = np.array([...], dtype=np.float32)  # 替换为实际3D点
vertices2d = np.array([...], dtype=np.float32)  # 替换为实际2D点
camera_matrix = np.array([...], dtype=np.float32)  # 替换为实际相机矩阵
dist_coeffs = np.array([...], dtype=np.float32)  # 替换为实际畸变系数,可为None

# 初始猜测,例如零平移
t_initial = np.zeros(3)

# 可选:使用线性解法获取更好的初始值(见注释部分)

# 非线性优化
result = least_squares(residual, t_initial, args=(vertices, vertices2d, camera_matrix, dist_coeffs))
t_opt = result.x

print("优化后的平移向量:", t_opt)
相关推荐
a11177612 分钟前
工业视觉软件入门:VisionMaster(VM)、HALCON、VisionPro
嵌入式硬件·数码相机
埃科光电1 天前
极速扫描 多元散热:8K高阶TDI线阵相机 阵容升级
图像处理·人工智能·数码相机·计算机视觉·制造
黑马水牛1 天前
Carla仿真系列:5_Carla 四路相机标定与BEV环视拼接
数码相机
在世修行2 天前
从零打造 C# 工业视觉检测系统(五):相机连接、连续取流与双路实时预览
数码相机·c#·视觉检测
格林威3 天前
多相机微秒级对齐:硬件触发 vs PTP(IEEE 1588)方案实战对比
开发语言·人工智能·数码相机·机器学习·计算机视觉·视觉检测·机器视觉
xcLeigh3 天前
Unity基础:Camera相机组件详解——透视投影与正交投影的区别
数码相机·unity·游戏引擎
在世修行3 天前
从零打造 C# 工业视觉检测系统(四):海康威视 MVS SDK 入门与相机枚举实战
数码相机·c#·视觉检测
m0_749492223 天前
2026平价运动相机选择指南:科美锐(Komery)PX3与另外两款相机的功能取舍拆解
数码相机
沐梯子3 天前
AI视频工具大战升级!PixPix首发接入MiniMaxH3大战Seedance
数码相机
c#上位机3 天前
线扫相机的帧触发
数码相机