I work with the ZED 2i in FHD and 15 FPS modes.
I need capture and compute data at 1-2 FPS.
When I carefully reading documentation, I noticed 2 details and questions:
- The
grab()
method grab the freshest frame. - if I make time.sleep(1)
, then will give last frame or frame from buffer? When work with OpenCV for skip frames and not decode them then need call grab
multiple times and then retrieve
the last grabbed frame for decoding, but in ZED SDK calling grab prefoms computations.
- The
grab_compute_capping_fps
parameter limits the computation frequency and may set 1-2 FPS - I need the retrieved frame and computed data (e.g., the point cloud) to correspond to the same moment in time (Frame N + PointCoud N is correct and Frame N+1 + PointCloud N is incorrect). How ZED hoes SDK handle frames processing? Does it use frame indexes or another method to ensure that both the frames and computed data are from the same point in time?
I am unsure how to verify this behavior correctly.
Today, with a fresh mind, I figured out that I can compare the time of the image, camera and host.
I looked in the documentation how to get the timestamp of camera and of grabbed image.
grab_compute_capping_fps = 1
- result in a 1 second lag to between grabbed frame and actual camera time
grab_compute_capping_fps = 2
- result in a 0.5 second
Basically, it’s acceptable.
I dont know if it will work the same for every camera model, so here is the code
from datetime import datetime
from pyzed import sl
camera = sl.Camera()
init_params = sl.InitParameters()
init_params.camera_fps = 15
init_params.camera_resolution = sl.RESOLUTION.HD1080
init_params.grab_compute_capping_fps = 2
init_params.depth_mode = sl.DEPTH_MODE.QUALITY
camera.open(init_params)
runtime_params = sl.RuntimeParameters()
point_cloud = sl.Mat()
resolution = sl.Resolution()
resolution.width = 1920
resolution.height = 1080
def timestamp_to_str(timestamp: sl.Timestamp) -> str:
return datetime.fromtimestamp(timestamp.data_ns / (10 ** 9)).isoformat()
try:
while camera.grab(runtime_params) == sl.ERROR_CODE.SUCCESS:
image_timestamp_before_depth: sl.Timestamp = camera.get_timestamp(sl.TIME_REFERENCE.IMAGE)
current_camera_timestamp_before_depth: sl.Timestamp = camera.get_timestamp(sl.TIME_REFERENCE.CURRENT)
current_utc_time_before_depth = datetime.utcnow()
depth_res = camera.retrieve_measure(point_cloud, sl.MEASURE.XYZ, sl.MEM.CPU, resolution)
image_timestamp_after_depth: sl.Timestamp = camera.get_timestamp(sl.TIME_REFERENCE.IMAGE)
current_camera_timestamp_after_depth: sl.Timestamp = camera.get_timestamp(sl.TIME_REFERENCE.CURRENT)
current_utc_time_after_depth = datetime.utcnow()
print(f'\n{"DEPTH" if depth_res is not None else "FRAME"}')
print(
f'ImgBeforeDepth: {timestamp_to_str(image_timestamp_before_depth)}; CurCamBeforeDepth: {timestamp_to_str(current_camera_timestamp_before_depth)}'
f'; CurBeforeDepth: {current_utc_time_before_depth.isoformat()}'
)
print(
f'ImgAfterDepth: {timestamp_to_str(image_timestamp_after_depth)}; CurCamAfterDepth: {timestamp_to_str(current_camera_timestamp_after_depth)}'
f'; CurAfterDepth: {current_utc_time_after_depth.isoformat()}'
)
finally:
camera.close()