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
| class IR CameraSimulator: """ Aurelion 物理仿真红外摄像头模型 模拟链: 1. 3D 场景 → 2D 投影(光学模型) 2. IR 补光 → 反射模型(皮肤/眼镜材质) 3. 传感器 → 噪声模型(读出噪声/固定模式噪声) 4. ISP → 图像处理(去马赛克/白平衡/压缩) """ def __init__( self, resolution: tuple = (1280, 960), fps: int = 30, fov_h: float = 60, fov_v: float = 45, ir_wavelength: int = 940, ir_power: float = 1.0, ): self.resolution = resolution self.fps = fps self.fov_h = fov_h self.fov_v = fov_v self.ir_wavelength = ir_wavelength self.ir_power = ir_power def simulate_capture( self, avatar: DriverAvatar, scene: dict ) -> dict: """ 仿真一帧 IR 捕获 Args: avatar: 驾驶员模型 scene: 场景配置(光照/天气/振动) Returns: frame_data: 包含图像和元数据 """ base_image = self._render_3d_scene(avatar, scene) skin_reflectance = self._get_skin_reflectance( avatar.skin_tone, self.ir_wavelength ) ambient_ir = scene.get('ambient_ir', 0.1) ir_illumination = self.ir_power + ambient_ir read_noise = np.random.normal( 0, scene.get('noise_level', 2), self.resolution ) fixed_pattern_noise = np.random.normal( 0, 1, self.resolution ) * 0.5 if scene.get('vibration'): blur_kernel = self._motion_blur_kernel(scene['vibration']) if avatar.glasses: glasses_occlusion = self._simulate_glasses( avatar.glasses_type, scene ) return { 'image': base_image, 'metadata': { 'skin_reflectance': skin_reflectance, 'ir_power': ir_illumination, 'noise': scene.get('noise_level', 2), 'scene': scene, }, 'ground_truth': { 'gaze': avatar.gaze_pattern, 'drowsiness': avatar.drowsiness_level, 'blink_count': None, 'perclos': None, } } def _render_3d_scene(self, avatar, scene): """简化:返回模拟图像""" return np.zeros((*self.resolution[::-1], 3), dtype=np.uint8) def _get_skin_reflectance(self, skin_tone, wavelength): """ 不同肤色在 940nm IR 下的反射率 关键:IR 下肤色差异远小于可见光 """ reflectance_map = { 1: 0.45, 2: 0.43, 3: 0.42, 4: 0.40, 5: 0.38, 6: 0.36, } return reflectance_map.get(skin_tone, 0.42) def _motion_blur_kernel(self, vibration): """运动模糊核""" return np.ones((3, 3)) / 9 def _simulate_glasses(self, glasses_type, scene): """眼镜遮挡/反射模拟""" return {"occlusion_ratio": 0.1 if glasses_type == "frame" else 0.3}
if __name__ == "__main__": cam = IRCameraSimulator(resolution=(1280, 960), fps=30, ir_wavelength=940) scenarios = [ {"name": "白天正常", "ambient_ir": 0.3, "noise_level": 1, "vibration": False}, {"name": "夜晚正常", "ambient_ir": 0.05, "noise_level": 3, "vibration": False}, {"name": "隧道入口", "ambient_ir": 0.15, "noise_level": 2, "vibration": True}, {"name": "强逆光", "ambient_ir": 0.5, "noise_level": 1, "vibration": False}, ] for scene in scenarios: avatar = DriverAvatar( skin_tone=np.random.randint(1, 7), glasses=np.random.random() > 0.7, drowsiness_level="drowsy" ) result = cam.simulate_capture(avatar, scene) print(f"{scene['name']:12s}: 皮肤反射率={result['metadata']['skin_reflectance']:.2f}, " f"噪声={result['metadata']['noise']}, " f"眼镜={'有' if avatar.glasses else '无'}")
|