1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
| import numpy as np from typing import Tuple
class GaussianSplattingReconstructor: """ 3D Gaussian Splatting 重建器 原理: 1. 从多视角图像初始化点云 2. 每个点用一个 3D 高斯分布表示 3. 通过可微渲染优化高斯参数 4. 渲染新视角时投影到目标相机 NuRec 应用: - 输入:源车 6 相机记录的驾驶场景 - 重建:3D 高斯场景表示 - 输出:目标车型相机视角的渲染 """ def __init__(self, n_gaussians=500000): self.n_gaussians = n_gaussians self.positions = np.random.randn(n_gaussians, 3) * 10 self.scales = np.ones((n_gaussians, 3)) * 0.01 self.rotations = np.array([[1, 0, 0, 0]] * n_gaussians, dtype=np.float32) self.opacities = np.ones((n_gaussians, 1)) * 0.8 self.colors = np.random.randn(n_gaussians, 3) * 0.5 + 0.5 def render_view(self, camera_params: dict, image_size: Tuple[int, int] = (1080, 1920)) -> np.ndarray: """ 渲染目标视角 Args: camera_params: 相机参数 { 'extrinsics': (4, 4) 相机外参 'intrinsics': (3, 3) 相机内参 'distortion': 畸变模型 } image_size: (H, W) Returns: image: (H, W, 3) 渲染图像 """ H, W = image_size extrinsics = camera_params['extrinsics'] intrinsics = camera_params['intrinsics'] cam_coords = (extrinsics[:3, :3] @ self.positions.T + extrinsics[:3, 3:4].T) pixel_coords = intrinsics @ cam_coords pixel_coords = pixel_coords[:2] / pixel_coords[2:3] depths = cam_coords[2] order = np.argsort(-depths) image = np.zeros((H, W, 3), dtype=np.float32) for idx in order: x, y = int(pixel_coords[0, idx]), int(pixel_coords[1, idx]) if 0 <= x < W and 0 <= y < H: alpha = self.opacities[idx, 0] color = self.colors[idx] image[y, x] = image[y, x] * (1 - alpha) + color * alpha return image def adapt_carline(self, source_rig: dict, target_rig: dict) -> dict: """ 车型适配:从源车视角渲染目标车视角 Args: source_rig: 源车相机配置 { 'cameras': [ {'name': 'front_wide', 'fov': 120, 'extrinsics': ...}, {'name': 'front_tele', 'fov': 30, 'extrinsics': ...}, ... ] } target_rig: 目标车相机配置 Returns: rendered_views: 各相机渲染结果 """ rendered = {} for cam in target_rig['cameras']: source_cam = self._find_matching_camera( cam['name'], source_rig['cameras'] ) if source_cam: rendered[cam['name']] = 'use_source' else: params = { 'extrinsics': cam['extrinsics'], 'intrinsics': cam['intrinsics'], 'distortion': cam.get('distortion', 'pinhole') } rendered[cam['name']] = self.render_view(params) return rendered def _find_matching_camera(self, name, cameras): for cam in cameras: if cam['name'] == name: return cam return None
NUREC_DATASET_SPEC = { 'n_scenes': 1500, 'scene_duration_sec': 20, 'cameras': [ {'name': 'front_wide', 'fov': 120, 'type': 'pinhole'}, {'name': 'front_tele', 'fov': 30, 'type': 'pinhole'}, {'name': 'cross_left', 'fov': 120, 'type': 'fisheye'}, {'name': 'cross_right', 'fov': 120, 'type': 'fisheye'}, {'name': 'rear_left', 'fov': 70, 'type': 'fisheye'}, {'name': 'rear_right', 'fov': 70, 'type': 'fisheye'}, ], 'host': 'Hugging Face', 'format': 'NCore' }
if __name__ == "__main__": reconstructor = GaussianSplattingReconstructor(n_gaussians=100000) target_cam = { 'extrinsics': np.eye(4), 'intrinsics': np.array([ [1920, 0, 960], [0, 1920, 540], [0, 0, 1] ], dtype=np.float32), 'distortion': 'pinhole' } image = reconstructor.render_view(target_cam) print(f"渲染图像: {image.shape}") print(f"非零像素: {np.count_nonzero(image.any(axis=2))}")
|