深度转点云 点云着色
目录
depthanything 生成深度图,转点云着色
点云转深度图
depthanything 生成深度图,转点云着色
import numpy as np
import cv2
import open3d as o3d
def depth_to_point_cloud(depth_image, rgb_image, camera_intrinsics, camera_extrinsics=np.eye(4), scale=1.0):
# 获取图像尺寸
height, width = depth_image.shape
depth_image = 65535 - depth_image
# 创建网格坐标
x, y = np.meshgrid(np.arange(width), np.arange(height))
# 计算相机坐标系下的三维坐标
X = (x - camera_intrinsics[0, 2]) * depth_image / camera_intrinsics[0, 0]
Y = (y - camera_intrinsics[1, 2]) * depth_image / camera_intrinsics[1, 1]
Z = depth_image / scale
# 将三维坐标转换为点云数据
pointcloud = np.stack((X, Y, Z), axis=2)
pointcloud = pointcloud.reshape(-1, 3)
pointcloud = np.concatenate((pointcloud, np.ones((pointcloud.shape[0], 1))), axis=1)
# 应用外参进行转换
pointcloud = 20. / 65535. * (camera_extrinsics @ pointcloud.T)
pointcloud = pointcloud[:3].T # 去除齐次坐标
# 获取RGB颜色信息,并转换为0-1之间的范围
colors = rgb_image.reshape(-1, 3) / 255.0
return pointcloud, colors
# 内参矩阵 K
camera_intrinsics = np.array([[418.96369417, 0., 489.16315478],
[0., 419.04813353, 267.88796254],
[0., 0., 1.]], dtype=np.float64)
# 外参矩阵 Extrinsics
camera_extrinsics = np.array([[-3.9147413e-03, -9.9999213e-01, 6.7846401e-04, 1.0138103e-02],
[9.3531040e-03, -7.1505480e-04, -9.9995601e-01, 1.2053192e+00],
[9.9994862e-01, -3.9082235e-03, 9.3558291e-03, -2.1235154e+00],
[0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.0000000e+00]], dtype=np.float64)
# 加载深度图像
depth_image = cv2.imread(r"E:\project\depth\Depth-Anything-V2-main\vis_depth\LW433B12XN1045039_1706225802664_01_6_1706225788457.png", cv2.IMREAD_ANYDEPTH)
# 加载对应的RGB图像
rgb_image = cv2.imread(r"E:\project\depth\Depth-Anything-V2-main\imgs\LW433B12XN1045039_1706225802664_01_6_1706225788457.jpg",cv2.IMREAD_COLOR)
rgb_image= cv2.cvtColor(rgb_image, cv2.COLOR_BGR2RGB)
# 将深度图转换为带颜色的点云数据
pointcloud, colors = depth_to_point_cloud(depth_image, rgb_image, camera_intrinsics, camera_extrinsics, scale=1.0)
# 创建 Open3D 点云对象
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(pointcloud)
pcd.colors = o3d.utility.Vector3dVector(colors)
# 可视化点云
o3d.visualization.draw_geometries([pcd])
# 保存点云为 PLY 文件
o3d.io.write_point_cloud("output_point_cloud_with_rgb.ply", pcd)
点云转深度图
import cv2
import numpy as np
import open3d as o3d
img_width = 960
img_height = 540
frame_id=0
if __name__ == '__main__':
fx=418.96369417
fy=489.16315478
cx=419.04813353
cy=267.88796254
camera_intrinsics = np.array([[418.96369417, 0., 489.16315478], [0., 419.04813353, 267.88796254], [0., 0., 1.]], dtype=np.float64)
K_4x4 = np.eye(4)
K_4x4[:3, :3] = camera_intrinsics
camera_extrinsics = np.array(
[[-3.9147413e-03, -9.9999213e-01, 6.7846401e-04, 1.0138103e-02], [9.3531040e-03, -7.1505480e-04, -9.9995601e-01, 1.2053192e+00], [9.9994862e-01, -3.9082235e-03, 9.3558291e-03, -2.1235154e+00],
[0.0023456e+00, 0.0000000e+00, 0.0000000e+00, 1.0000000e+00]], dtype=np.float64)
world_to_camera = np.linalg.inv(camera_extrinsics)
print('lidar------------', frame_id)
pts_3d = []
pts_2d = []
pcd = o3d.io.read_point_cloud("output_point_cloud.ply")
points = np.asarray(pcd.points)
pts_3d.append(points[:, :3])
#pts_3d_to_2d=pts_3d @ lidar2vcs @np.linalg.inv(cam2vcs).T @ K_4x4.T
points_2d = np.hstack((points, np.ones((points.shape[0], 1)))) @ np.linalg.inv(world_to_camera) @ K_4x4.T
points_2d[:, [0, 1]] /= points_2d[:, [2]]
depth = points_2d[:, 2]
#创建深度图,并将所有点初始化为最大深度(如无穷远)
depth_map = np.full((img_height, img_width), np.inf)
w = points_2d[:, 0].astype(int)
h = points_2d[:, 1].astype(int)
# 过滤点,使得 w 和 h 在图像范围内
mask = np.logical_and.reduce((w >= 0, w < img_width, h >= 0, h < img_height))
w, h, depth = w[mask], h[mask], depth[mask]
# 逐像素赋值深度(最近点优先)
for i in range(len(w)):
if depth_map[h[i], w[i]] > depth[i]:
depth_map[h[i], w[i]] = depth[i]
# 将无穷远的像素设为最大深度值
max_depth = np.max(depth_map[np.isfinite(depth_map)])
depth_map[~np.isfinite(depth_map)] = max_depth
depth = (depth_map - depth_map.min()) / (depth_map.max() - depth_map.min())
# 缩放到0到65535的范围,并转换为uint16类型
array_uint16 = (65535-depth * 65535).astype(np.uint16)
if 0:
# 归一化到 0-255 并转换为 uint8
depth_map =255- (255 * (depth_map / max_depth)).astype(np.uint8)
cv2.imwrite(f'./depth_{frame_id}.png', array_uint16)