使用4个标记点无法获取物体Pose并绘制坐标轴求助
问题分析与解决方案
核心遗漏步骤
你代码中最关键的遗漏是没有调用cv2.solvePnP计算旋转向量(rotation_vector)和平移向量(translation_vector)——这两个变量是projectPoints的必要输入,但你直接使用了它们却没有生成。除此之外还有几个细节需要调整:
具体修正步骤
1. 补充姿态求解(solvePnP)
在调用projectPoints之前,必须先通过cv2.solvePnP计算相机与物体之间的旋转和平移关系:
# 计算旋转向量与平移向量 success, rotation_vector, translation_vector = cv2.solvePnP( object_points, image_points, mtx, dist, flags=cv2.SOLVEPNP_ITERATIVE ) # 检查求解是否成功 if not success: print("姿态求解失败") # 后续处理逻辑
2. 对齐物体点与图像点的对应关系
你指定Point_C为原点,但当前object_points中没有对应(0,0,0)的点,需要调整物体点坐标,确保每个图像点和物理点一一对应:
根据你给出的标记点顺序(A→B→C→D),结合你希望C为原点的需求,重新定义物体点(示例基于你原有的相对尺寸调整):
# 以Point_C为原点(0,0,0),其他点为相对C的物理坐标(单位根据实际测量调整) object_points = np.array([ (23, -16, 0), # Point_A 对应原(80,56,0),相对C(57,72,0)的偏移:80-57=23,56-72=-16 (23, 0, 0), # Point_B 对应原(80,72,0),相对C的偏移:80-57=23,72-72=0 (0, 0, 0), # Point_C 原点 (0, 16, 0) # Point_D 对应原(57,88,0),相对C的偏移:57-57=0,88-72=16 ], dtype=np.float32).reshape((4,1,3))
注意:物理坐标的单位(如mm/cm)不影响姿态求解,但要保证所有点的单位统一。
3. 补充坐标系绘制代码
你只做了投影计算,但没有将坐标系绘制到图像上,添加绘制函数并调用:
def draw_object_axis(img, imgpts): # 获取原点的像素坐标 origin = tuple(imgpts[0].ravel().astype(int)) # 绘制X轴(红色)、Y轴(绿色)、Z轴(蓝色) img = cv2.line(img, origin, tuple(imgpts[1].ravel().astype(int)), (0,0,255), 5) img = cv2.line(img, origin, tuple(imgpts[2].ravel().astype(int)), (0,255,0), 5) img = cv2.line(img, origin, tuple(imgpts[3].ravel().astype(int)), (255,0,0), 5) return img # 投影物体坐标系到图像 imgpts, jac = cv2.projectPoints(axis, rotation_vector, translation_vector, mtx, dist) # 绘制坐标系到图像 img = draw_object_axis(img, imgpts)
4. 检查其他细节
- 你代码中
Points[3]写的是(x4,y5),属于笔误,应修正为(x4,y4),确保图像点顺序正确。 - 确认所有标记点在物理空间中共面(你已将Z设为0,需保证实际标记确实在同一平面),否则会影响姿态求解精度。
完整流程总结
- 检测图像中的四个标记点,得到
image_points。 - 定义与图像点一一对应的
object_points(以C为原点)。 - 调用
cv2.solvePnP计算旋转、平移向量。 - 定义物体坐标系轴点
axis,调用cv2.projectPoints投影到图像。 - 绘制投影后的坐标系到图像。
内容的提问来源于stack exchange,提问作者AqibF
相关产品推荐
相关产品推荐

