Skip to content

Commit 29ca479

Browse files
committed
Added ToF configuration function, support ToF depth from pointcloud, pin numpy below 2.0, depthai-sdk to 1.15
1 parent 2160cf3 commit 29ca479

File tree

7 files changed

+73
-30
lines changed

7 files changed

+73
-30
lines changed

depthai_sdk/requirements.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
numpy>=1.19; python_version < "3.7"
2-
numpy>=1.21; python_version >= "3.7"
1+
numpy>=1.19,<2.0.0; python_version < "3.7"
2+
numpy>=1.21,<2.0.0; python_version >= "3.7"
33
opencv-contrib-python>4
44
blobconverter>=1.4.1
55
pytube>=12.1.0

depthai_sdk/setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
setup(
1111
name='depthai-sdk',
12-
version='1.13.1',
12+
version='1.15.0',
1313
description='This package provides an abstraction of the DepthAI API library.',
1414
long_description=io.open("README.md", encoding="utf-8").read(),
1515
long_description_content_type="text/markdown",

depthai_sdk/src/depthai_sdk/classes/packets.py

+9
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,15 @@ def get_sequence_num(self) -> int:
234234
def get_timestamp(self) -> timedelta:
235235
return self.depth_map.getTimestampDevice()
236236

237+
def crop_points(self, bb: BoundingBox) -> np.ndarray:
238+
"""
239+
Crop points to the bounding box
240+
241+
Returns: Cropped section of the point cloud
242+
"""
243+
x1, y1, x2, y2 = bb.to_tuple(self.points.shape)
244+
return self.points[y1:y2, x1:x2]
245+
237246

238247
class SpatialBbMappingPacket(DisparityDepthPacket):
239248
"""

depthai_sdk/src/depthai_sdk/components/nn_component.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,10 @@ def config_nn(self,
551551
self._change_resize_mode(self._ar_resize_mode)
552552

553553
if conf_threshold is not None and self.is_detector():
554-
self.node.setConfidenceThreshold(conf_threshold)
554+
if 0 <= conf_threshold <= 1:
555+
self.node.setConfidenceThreshold(conf_threshold)
556+
else:
557+
raise ValueError("Confidence threshold must be between 0 and 1!")
555558

556559
def config_spatial(self,
557560
bb_scale_factor: Optional[float] = None,

depthai_sdk/src/depthai_sdk/components/pointcloud_component.py

+16-13
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from depthai_sdk.components.camera_component import CameraComponent
66
from depthai_sdk.components.component import Component, ComponentOutput
77
from depthai_sdk.components.stereo_component import StereoComponent
8+
from depthai_sdk.components.tof_component import ToFComponent
89
from depthai_sdk.oak_outputs.xout.xout_base import XoutBase, StreamXout
910
from depthai_sdk.oak_outputs.xout.xout_pointcloud import XoutPointcloud
1011
from depthai_sdk.replay import Replay
@@ -15,7 +16,7 @@ class PointcloudComponent(Component):
1516
def __init__(self,
1617
device: dai.Device,
1718
pipeline: dai.Pipeline,
18-
stereo: Union[None, StereoComponent, dai.node.StereoDepth, dai.Node.Output] = None,
19+
depth_input: Union[None, StereoComponent, ToFComponent, dai.node.StereoDepth, dai.Node.Output] = None,
1920
colorize: Optional[CameraComponent] = None,
2021
replay: Optional[Replay] = None,
2122
args: Any = None):
@@ -28,15 +29,14 @@ def __init__(self,
2829
super().__init__()
2930
self.out = self.Out(self)
3031

31-
self.stereo_depth_node: dai.node.StereoDepth
32-
self.depth: dai.Node.Output # Depth node output
32+
self.depth: dai.Node.Output # depth output
3333

3434
self.colorize_comp: Optional[CameraComponent] = colorize
3535

3636
self._replay: Optional[Replay] = replay
3737

3838
# Depth aspect
39-
if stereo is None:
39+
if depth_input is None:
4040
stereo = StereoComponent(device, pipeline, replay=replay, args=args)
4141
stereo.config_stereo(lr_check=True, subpixel=True, subpixel_bits=3, confidence=230)
4242
stereo.node.initialConfig.setNumInvalidateEdgePixels(20)
@@ -58,15 +58,18 @@ def __init__(self,
5858
# Align to colorize node
5959
stereo.config_stereo(align=self.colorize_comp)
6060

61-
if isinstance(stereo, StereoComponent):
62-
stereo = stereo.node
63-
64-
if isinstance(stereo, dai.node.StereoDepth):
65-
self.stereo_depth_node = stereo
66-
self.depth = stereo.depth
67-
elif isinstance(stereo, dai.Node.Output):
68-
self.stereo_depth_node = stereo.getParent()
69-
self.depth = stereo
61+
if isinstance(depth_input, StereoComponent):
62+
depth_input = stereo.node
63+
elif isinstance(depth_input, ToFComponent):
64+
if depth_input._align is not None:
65+
self.depth = depth_input._align.outputAligned
66+
else:
67+
self.depth = depth_input.node.depth
68+
69+
if isinstance(depth_input, dai.node.StereoDepth):
70+
self.depth = depth_input.depth
71+
elif isinstance(depth_input, dai.Node.Output):
72+
self.depth = depth_input
7073

7174
def config_postprocessing(self) -> None:
7275
"""

depthai_sdk/src/depthai_sdk/components/tof_component.py

+32-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import List, Optional, Union
1+
from typing import List, Optional, Union, Tuple
22

33
import depthai as dai
44

@@ -21,6 +21,7 @@ def __init__(
2121
pipeline: dai.Pipeline,
2222
source: Union[str, dai.CameraBoardSocket, None] = None,
2323
align_to: Optional[CameraComponent] = None,
24+
fps: Optional[int] = None,
2425
):
2526
super().__init__()
2627
self.out = self.Out(self)
@@ -40,17 +41,19 @@ def __init__(
4041
self.camera_node.setBoardSocket(source)
4142
self.camera_socket = source
4243

43-
self.node = pipeline.create(dai.node.ToF)
44+
if fps is not None:
45+
self.camera_node.setFps(fps)
46+
47+
self.node: dai.node.ToF = pipeline.create(dai.node.ToF)
4448
self._control_in = pipeline.create(dai.node.XLinkIn)
4549
self.camera_node.raw.link(self.node.input)
4650
self._control_in.setStreamName(f"{self.node.id}_inputControl")
4751
self._control_in.out.link(self.node.inputConfig)
4852

53+
self._align_to_output: dai.Node.Output = None
54+
4955
if align_to is not None:
50-
self._align = pipeline.create(dai.node.ImageAlign)
51-
self._align_to_output = align_to.node.isp
52-
self.node.depth.link(self._align.input)
53-
self._align_to_output.link(self._align.inputAlignTo)
56+
self.set_align_to(align_to)
5457

5558
def _find_tof(self, device: dai.Device) -> dai.CameraBoardSocket:
5659
# Use the first ToF sensor, usually, there will only be one
@@ -62,14 +65,34 @@ def _find_tof(self, device: dai.Device) -> dai.CameraBoardSocket:
6265
f"No ToF sensor found on this camera! {device.getConnectedCameraFeatures()}"
6366
)
6467

65-
def set_align_to(self, align_to: CameraComponent) -> None:
68+
def set_align_to(self, align_to: CameraComponent, output_size: Optional[Tuple] = None) -> None:
6669
if self._align is None:
6770
self._align = self._pipeline.create(dai.node.ImageAlign)
6871
self.node.depth.link(self._align.input)
6972
if align_to.is_mono():
70-
align_to.node.out.link(self._align.inputAlignTo)
73+
self._align_to_output = align_to.node.out
7174
else:
72-
align_to.node.isp.link(self._align.inputAlignTo)
75+
self._align_to_output = align_to.node.isp
76+
77+
self._align_to_output.link(self._align.inputAlignTo)
78+
79+
if output_size is not None:
80+
self._align.setOutputSize(*output_size)
81+
82+
83+
def configure_tof(self,
84+
phaseShuffleTemporalFilter: bool = None,
85+
phaseUnwrappingLevel: int = None,
86+
phaseUnwrapErrorThreshold: int = None,
87+
) -> None:
88+
tofConfig = self.node.initialConfig.get()
89+
if phaseShuffleTemporalFilter is not None:
90+
tofConfig.enablePhaseShuffleTemporalFilter = phaseShuffleTemporalFilter
91+
if phaseUnwrappingLevel is not None:
92+
tofConfig.phaseUnwrappingLevel = phaseUnwrappingLevel
93+
if phaseUnwrapErrorThreshold is not None:
94+
tofConfig.phaseUnwrapErrorThreshold = phaseUnwrapErrorThreshold
95+
self.node.initialConfig.set(tofConfig)
7396

7497
def on_pipeline_started(self, device: dai.Device) -> None:
7598
self.control.set_input_queue(

depthai_sdk/src/depthai_sdk/oak_camera.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -390,14 +390,19 @@ def create_stereo(self,
390390
"""
391391
return self.stereo(resolution, fps, left, right, encode)
392392

393-
def create_tof(self, source: Union[str, dai.CameraBoardSocket, None] = None, align_to: Optional[CameraComponent] = None) -> ToFComponent:
393+
def create_tof(self,
394+
source: Union[str, dai.CameraBoardSocket, None] = None,
395+
fps: Optional[float] = None,
396+
align_to: Optional[CameraComponent] = None) -> ToFComponent:
394397
"""
395398
Create ToF component.
396399
397400
Args:
398401
source (str / dai.CameraBoardSocket): ToF camera source
402+
fps (float): Sensor FPS
403+
align_to (CameraComponent): Align ToF to this camera component
399404
"""
400-
comp = ToFComponent(self.device, self.pipeline, source, align_to)
405+
comp = ToFComponent(self.device, self.pipeline, source, align_to, fps)
401406
self._components.append(comp)
402407
return comp
403408

@@ -410,7 +415,7 @@ def create_imu(self) -> IMUComponent:
410415
return comp
411416

412417
def create_pointcloud(self,
413-
stereo: Union[None, StereoComponent, dai.node.StereoDepth, dai.Node.Output] = None,
418+
depth_input: Union[None, StereoComponent, ToFComponent, dai.node.StereoDepth, dai.Node.Output] = None,
414419
colorize: Union[None, CameraComponent, dai.node.MonoCamera, dai.node.ColorCamera, dai.Node.Output, bool] = None,
415420
) -> PointcloudComponent:
416421

@@ -427,7 +432,7 @@ def create_pointcloud(self,
427432
comp = PointcloudComponent(
428433
self.device,
429434
self.pipeline,
430-
stereo=stereo,
435+
depth_input=depth_input,
431436
colorize=colorize,
432437
replay=self.replay,
433438
args=self._args,

0 commit comments

Comments
 (0)