目录
逆透视投影 torch版本
import torch
def inverse_perspective_projection(points, K, distance):
"""
这个函数计算给定估计距离的点集的逆透视投影。
参数:
points (bs, N, 2): 2D 图像上的点(每个批次有 N 个 2D 点)
K (bs, 3, 3): 相机的内参矩阵(每个批次一个 3x3 的矩阵)
distance (bs, N, 1): 3D 世界中每个点的距离
类似于:
- pts_l_norm = cv2.undistortPoints(np.expand_dims(pts_l, axis=1), cameraMatrix=K_l, distCoeffs=None)
"""
# 第一步:将 2D 点转化为齐次坐标(在每个点的最后添加一个 1)
points = torch.cat([points, torch.ones_like(points[..., :1])], -1)
# points 的形状变为 (bs, N, 3),此时最后一维是齐次坐标
# 第二步:应用相机内参 K,计算归一化的图像坐标
points = torch.einsum("bij,bkj->bki", torch.inverse(K), points)
# 通过 K 的逆矩阵将点从像素坐标系转换到归一化相机坐标系
# 第三步:如果没有给定距离参数,直接返回归一化后的坐标
if distance == None:
return points
# 第四步:将归一化坐标乘以距离,恢复到实际的 3D 空间坐标
points = points * distance
return points
代码解释:
-
输入参数:
-
points (bs, N, 2)
:包含bs
批次,每个批次N
个 2D 图像点。每个点是一个二维坐标。 -
K (bs, 3, 3)
:相机内参矩阵,每个批次对应一个 3x3 的矩阵。相机的内参矩阵通常包含焦距和主点坐标。 -
distance (bs, N, 1)
:每个点在 3D 空间中的距离。
-
-
第一步:将 2D 点扩展为齐次坐标。
-
points = torch.cat([points, torch.ones_like(points[..., :1])], -1)
将每个 2D 点添加一个 1,变成(x, y, 1)
形式,这样可以进行齐次坐标变换。
-
-
第二步:应用相机的内参矩阵
K
的逆,将 2D 图像点从像素坐标系转换为归一化的相机坐标系。-
使用
torch.einsum("bij,bkj->bki", torch.inverse(K), points)
计算逆透视变换。torch.inverse(K)
是相机内参的逆矩阵,然后使用爱因斯坦求和约定将其与点坐标进行相乘,得到归一化的 3D 坐标。
-
-
第三步:如果没有给定距离
distance
,直接返回归一化后的点坐标。 -
第四步:如果给定了每个点的
distance
,则将归一化的坐标乘以该点的距离,得到实际的 3D 空间坐标。
主要目的:
-
该函数通过逆透视投影,将 2D 图像上的点转换为 3D 空间中的坐标。这种方法通常用于从 2D 图像恢复 3D 空间中的物体位置,前提是知道每个点到相机的距离(
distance
)。