如何用Python和点云转2D坐标为3D?求3D两人距离计算方案
基于3D点云计算目标间空间距离的实现方案
1. 补全3D坐标转换函数的核心逻辑
你提供的reconstruct_3D函数仅生成了图像像素坐标矩阵u和v,缺少针孔相机模型的核心转换步骤。完整实现如下:
import numpy as np def reconstruct_3D(depth, f): """ Reconstruct depth to 3D pointcloud with the provided focal length. Args: depth: HxW array, depth map(单位:真实物理长度,比如米) f: 相机焦距(像素单位,可从相机内参获取) Return: pcd: N X 3 array, point cloud(每行对应一个像素的3D坐标,单位与depth一致) """ cu = depth.shape[1] / 2 # 图像主点x坐标(像素中心) cv = depth.shape[0] / 2 # 图像主点y坐标(像素中心) height, width = depth.shape # 生成全图像素的u、v坐标矩阵 u = np.tile(np.arange(width), (height, 1)) v = np.tile(np.arange(height), (width, 1)).T # 针孔相机模型逆投影:将像素坐标+深度转为3D世界坐标 x = (u - cu) * depth / f y = (v - cv) * depth / f z = depth # 把HxW的3通道矩阵转为Nx3的点云格式 pcd = np.stack([x, y, z], axis=-1).reshape(-1, 3) return pcd
关键说明:
- 输入的
depth必须是真实物理单位的深度图(比如米),如果是模型输出的归一化深度,需要先还原为真实值 f是相机的焦距(像素单位),可从相机内参文件或标定结果中获取
2. 从YOLO检测结果映射到3D坐标
结合你已掌握的YOLO质心计算方法,步骤如下:
- 用YOLO检测图像中的两个人,得到各自的bounding box(x1,y1,x2,y2)
- 计算每个目标的2D质心坐标:
u = (x1 + x2)/2,v = (y1 + y2)/2(注意转换为整数像素索引) - 从深度图中提取该质心位置的深度值
z:z = depth[int(v), int(u)] - 单独计算该点的3D坐标(无需生成全图点云,提升效率):
def pixel_to_3d(u, v, z, f, cu, cv): x = (u - cu) * z / f y = (v - cv) * z / f return np.array([x, y, z])
3. 计算3D空间中两人的真实距离
得到两个人的3D坐标P1=(x1,y1,z1)和P2=(x2,y2,z2)后,直接用欧几里得距离公式计算真实空间距离:
def calculate_3d_distance(p1, p2): return np.sqrt((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2 + (p1[2]-p2[2])**2)
对比2D方法的优势:
- 2D方法计算的是图像平面的像素距离,需要结合人体高度等先验知识估算真实距离,误差较大
- 3D方法直接计算物理空间中的直线距离,无需额外先验,精度取决于深度图的准确性
内容的提问来源于stack exchange,提问作者user44840
相关产品推荐
相关产品推荐

