ZED2相机api使用心得
一. ZED相机的选型
STEREOLABS(ZED相机厂家)的官网:https://www.stereolabs.com/zed/
ZED双目相机有以下四种型号:
ZED 2i:ZED相机最新款(ZED相机二代的进阶版,防尘防水)
ZED 2 :ZED相机二代(相较于1代多了支持IMU)
ZED mini:功能上和二代基本一致,尺寸更小,性能上要差,比如这里支持的景深在15m以内,而二代的景深最大支持20m。
ZED:ZED相机一代,支持2K视频,景深范围在(0.3m,25m),无IMU,所以对于需要玩SLAM的这款就不推荐了。
二. 安装ZED的SDK
2.1 安装SDK
ZED相机SDK官网:https://www.stereolabs.com/developers/release/
我们可以看到是,所有的SDK基本都需要你安装cuda,因此我选择了cuda11.0进行安装,具体的cuda安装过程可参考我之前的一篇博客:Windows10环境下搭建CUDA10.1和pytorch1.6。
直接安装即可,将下载下来的exe双击运行ZED_SDK_Windows10_cuda11.0_v3.5.2_4.exe
即可,如下图所示
一直往下走即可。
2.2 安装python API
安装完成之后,可以在 C:\Program Files (x86)\ZED SDK\
下看到get_python_api.py
,如下图
直接进行安装python的api:python get_python_api.py
三. python API的使用
-
导入zed的python包
import pyzed.sl as sl
-
查看zed相机版本,这里说下,如果检测到是ZED一代的化,是不支持拿IMU数据的。
zed = sl.Camera() info = zed.get_camera_information() print("Camera Model: " + str(info.camera_model))
- 拿到相机的温度信息(本人亲测可用,讲真别用官方教程里的例子,得到的温度全是0,坑)
sensors_data = sl.SensorsData() if zed.get_sensors_data(sensors_data, sl.TIME_REFERENCE.CURRENT) == sl.ERROR_CODE.SUCCESS: # 这里分别拿到左、右相机,imu,气压计4者的温度 temperature_left = sensors_data.get_temperature_data().get(sl.SENSOR_LOCATION.ONBOARD_LEFT) temperature_right = sensors_data.get_temperature_data().get(sl.SENSOR_LOCATION.ONBOARD_RIGHT) temperature_imu = sensors_data.get_temperature_data().get(sl.SENSOR_LOCATION.IMU) temperature_barometer = sensors_data.get_temperature_data().get(sl.SENSOR_LOCATION.BAROMETER) print("Left: {:.2f}, Right: {:.2f}, IMU: {:.2f}, Barometer: {:.2f}\r\n".format(temperature_left, temperature_right, temperature_imu, temperature_barometer))
-
拿到相机的惯导(IMU)信息,注意这里使用的是Y轴向上的右手定律,这里即Z轴方向是车头/飞机头的方向。
# 初始化 zed = sl.Camera() # Create a ZED camera object input_type = sl.InputType() # Set configuration parameters init = sl.InitParameters(input_t=input_type) # 初始化 self.init.coordinate_system = sl.COORDINATE_SYSTEM.RIGHT_HANDED_Y_UP # 右手定律Y轴向上 while True: runtime_parameters = sl.RuntimeParameters() if zed.grab(runtime_parameters) == sl.ERROR_CODE.SUCCESS: zed_imu = zed_sensors.get_imu_data() zed_imu_pose = sl.Transform() ox = round(zed_imu.get_pose(zed_imu_pose).get_orientation().get()[0], 3) oy = round(zed_imu.get_pose(zed_imu_pose).get_orientation().get()[1], 3) oz = round(zed_imu.get_pose(zed_imu_pose).get_orientation().get()[2], 3) ow = round(zed_imu.get_pose(zed_imu_pose).get_orientation().get()[3], 3) print("IMU Orientation: Ox: {0}, Oy: {1}, Oz {2}, Ow: {3}\n".format(ox, oy, oz, ow))
这里拿到的数据是四元数,如果我们想转成欧拉角,这里推推荐使用scipy的转换函数
Rotation.from_quat
。from scipy.spatial.transform import Rotation # 将上面拿到的四元数转成欧拉角 rot = Rotation.from_quat([ox,oy,oz,ow]) eular_angle = rot.as_euler('xyz', degrees=True) print(f'翻滚角:{eular_angle[2]},俯仰角:{eular_angle[0]},方位角:eular_angle[1]')
-
拿取当前时间(毫秒级)
# 当前时间戳(毫秒) time_zed = zed_pose.timestamp.get_milliseconds()
-
拿到前景图
# 定义图像数据 image_size = zed.get_camera_information().camera_resolution image_zed = sl.Mat(image_size.width, image_size.height, sl.MAT_TYPE.U8_C4) while True: # 从zed相机中拿到前景图 zed.grab() # 拿取图像 zed.retrieve_image(image_zed, sl.VIEW.LEFT, sl.MEM.CPU, image_size) # 转成numpy image_np = image_zed.get_data()
-
拿到景深图(当然也可以拿到3D点云数据)
# 这里需要在初始化中加入深度模式 init.depth_mode = sl.DEPTH_MODE.ULTRA # 深度模式 (默认-PERFORMANCE) init.coordinate_units = sl.UNIT.MILLIMETER # 毫米级 (默认-MILLIMETER) # 定义测量数据 depth_zed = sl.Mat(image_size.width / 2, image_size.height / 2) # 16位进行保存 point_cloud_zed = sl.Mat(image_size.width / 2,image_size.height / 2) while True: # 从zed相机中拿到景深图 zed.grab() # 拿取景深图像 zed.retrieve_measure(depth_zed, sl.MEASURE.DEPTH,sl.MEM.CPU,image_size) # 拿取3D点云图像 zed.retrieve_measure(point_cloud_zed, sl.MEASURE.XYZRGBA) # 转成numpy depth_np = depth_zed.get_data() point_cloud_value = point_cloud_zed.get_value(x, y)[1]