如何将Carla模拟器的相机数据保存至本地磁盘?
问题分析与修复方案
核心问题点
- 重复注册相机回调:while循环内反复执行
camera.listen(...),会不断给相机添加新的保存回调,旧回调不会自动销毁,导致内存占用急剧上升,最终引发Jupyter内核崩溃。 - 多回调冲突:同时注册了图像更新回调和保存回调,两者抢占相机资源,且重复注册本身违反Carla传感器回调的使用规范。
- Jupyter与OpenCV窗口不兼容:
cv2.imshow和cv2.waitKey在Jupyter环境下的事件循环容易冲突,进一步加剧内核崩溃风险。
修复后的代码
import glob import os import sys import random import carla import cv2 import numpy as np import matplotlib.pyplot as plt # 初始化CARLA客户端与世界 client = carla.Client('localhost', 2000) client.set_timeout(10.0) # 超时时间无需设500秒,10秒足够 world = client.get_world() blueprint_library = world.get_blueprint_library() spawn_points = world.get_map().get_spawn_points() spectator = world.get_spectator() # 生成车辆 vehicle_blueprint = blueprint_library.find('vehicle.audi.etron') vehicle = world.try_spawn_actor(vehicle_blueprint, random.choice(spawn_points)) if not vehicle: # 防止随机 spawn 失败 vehicle = world.spawn_actor(vehicle_blueprint, spawn_points[0]) # 设置 spectator 视角 transform = carla.Transform(vehicle.get_transform().transform(carla.Location(x=2, z=0.5)), vehicle.get_transform().rotation) spectator.set_transform(transform) # 初始化相机传感器 camera_blueprint = blueprint_library.find('sensor.camera.rgb') # 可以手动设置图像分辨率(可选) camera_blueprint.set_attribute('image_size_x', '1920') camera_blueprint.set_attribute('image_size_y', '1080') camera_transform = carla.Transform(carla.Location(z=2, x=0.5)) camera = world.spawn_actor(camera_blueprint, camera_transform, attach_to=vehicle) # 图像保存路径 save_path = r"C:\Users\Joshi\Desktop\CARLA_0.9.13\WindowsNoEditor\PythonAPI\examples\out" os.makedirs(save_path, exist_ok=True) # 确保目录存在 # 整合回调函数:同时处理图像显示(用matplotlib适配Jupyter)和保存 frame_count = 0 def camera_callback(image): global frame_count # 将原始数据转为numpy数组(RGBA格式) img_data = np.reshape(np.copy(image.raw_data), (image.height, image.width, 4)) # 转为RGB格式适配matplotlib显示 img_rgb = img_data[:, :, :3] # 保存图像为PNG,用帧号作为文件名避免覆盖 image.save_to_disk(os.path.join(save_path, f"{frame_count:06d}.png"), color_converter=carla.ColorConverter.RGB) # Jupyter环境下用matplotlib显示图像(替换cv2.imshow) plt.clf() plt.imshow(img_rgb) plt.axis('off') plt.show(block=False) plt.pause(0.01) frame_count += 1 # 只注册一次回调 camera.listen(camera_callback) # 设置车辆自动驾驶 vehicle.set_autopilot(True) # 运行主循环,输入'p'并回车退出 try: while True: user_input = input("输入'p'并回车退出:") if user_input.strip() == 'p': break finally: # 清理资源 camera.stop() camera.destroy() vehicle.destroy() plt.close()
关键修复说明
- 单次回调注册:仅在初始化时调用一次
camera.listen(),避免重复添加回调导致内存泄漏。 - 整合回调逻辑:将图像保存和显示逻辑放在同一个回调函数中,避免资源冲突。
- Jupyter适配:用
matplotlib替代cv2.imshow,解决Jupyter环境下的窗口显示冲突问题。 - 路径与文件名处理:确保保存目录存在,用帧号生成有序的PNG文件名,避免文件覆盖。
- 资源清理:添加
finally块确保退出时销毁传感器和车辆,释放CARLA资源。
内容的提问来源于stack exchange,提问作者LostJosh
相关产品推荐
相关产品推荐

