Hi from Pollen Robotics 🙂
 
We just received our ToF module. Using this example we get a pretty nice looking depthmap

(Except for the looping colors, but I assume that over a few meters the sensor is not accurate anymore)
(We are using an OAK FFC-4P btw)
However, when I try to mesure distances, they are pretty far off most of the time. For example
Real distance (black circle) ~= 380

Real distance ~= 340

Real distance ~= 195

Real distance ~= 880

A few questions :
- I don't understand what the different parameters are doing, and the documentation is not very helpful to me (this is the first time I work with a ToF sensor). Could you explain what freqModUsed, avgPhaseShuffle, and minimumAmplitude are doing ?
 
- Am I right to expect millimeters out of the depth map ?
 
- Is there any calibration needed ? Could that have been degraded during transport ?
 
Here is my code for depth mesurement in the image (at the position of the cursor), based on the provided example
#!/usr/bin/env python3
import cv2
import depthai as dai
import numpy as np
pipeline = dai.Pipeline()
cam_a = pipeline.create(dai.node.Camera)
cam_a.setBoardSocket(dai.CameraBoardSocket.CAM_A)
tof = pipeline.create(dai.node.ToF)
# Configure the ToF node
tofConfig = tof.initialConfig.get()
tofConfig.depthParams.freqModUsed = dai.RawToFConfig.DepthParams.TypeFMod.MAX
tofConfig.depthParams.avgPhaseShuffle = False
tofConfig.depthParams.minimumAmplitude = 3.0
tof.initialConfig.set(tofConfig)
cam_a.raw.link(tof.input)
xout = pipeline.create(dai.node.XLinkOut)
xout.setStreamName("depth")
tof.depth.link(xout.input)
last_mouse_pos = (0, 0)
last_depth_mesurement = 0
def mouse_callback(event, x, y, flags, params):
    global last_mouse_pos
    last_mouse_pos = (x, y)
cv2.namedWindow("colorized depth")
cv2.setMouseCallback("colorized depth", mouse_callback)
time_averaged_depth = []
# Connect to device and start pipeline
with dai.Device(pipeline) as device:
    print('Connected cameras:', device.getConnectedCameraFeatures())
    q = device.getOutputQueue(name="depth")
    while True:
        imgFrame = q.get()
        depth_map = imgFrame.getFrame()
        depth_downscaled = depth_map[::4]
        non_zero_depth = depth_downscaled[depth_downscaled != 0] # Remove invalid depth values
        if len(non_zero_depth) == 0:
            min_depth, max_depth = 0, 0
        else:
            min_depth = np.percentile(non_zero_depth, 3)
            max_depth = np.percentile(non_zero_depth, 97)
        last_depth_mesurement = depth_map[last_mouse_pos[1]-5:last_mouse_pos[1]+5, last_mouse_pos[0]-5:last_mouse_pos[0]+5]
        last_depth_mesurement = np.mean(last_depth_mesurement)
        time_averaged_depth.append(last_depth_mesurement)
        time_averaged_depth = time_averaged_depth[20:] if len(time_averaged_depth) > 20 else time_averaged_depth
        print("mean :", np.mean(time_averaged_depth), "(std :", np.std(time_averaged_depth), ")")
        depth_colorized = np.interp(depth_map, (min_depth, max_depth), (0, 255)).astype(np.uint8)
        depth_colorized = cv2.applyColorMap(depth_colorized, cv2.COLORMAP_JET)
        depth_colorized = cv2.circle(depth_colorized, last_mouse_pos, 5, (0, 0, 0), -1)
        cv2.imshow("colorized depth", depth_colorized)
        if cv2.waitKey(1) == ord('q'):
            break
Thanks !
Antoine