Skip to content

Commit 5cfd862

Browse files
author
Matevz Morato
committed
Add a porting guide and update README.md [no ci]
1 parent 39f2a7d commit 5cfd862

File tree

3 files changed

+222
-126
lines changed

3 files changed

+222
-126
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ DepthAI library for interfacing with Luxonis DepthAI hardware.
88

99
> ⚠️ This is a `v3.x.y` version of the library which is still in active development without a stable API yet.
1010
11+
> ℹ️ For porting code from `v2` version of the library, we recommend using the [porting guide](./V2V3PortinGuide.md)
1112
1213
## Documentation
1314
Documentation is available over at [Luxonis DepthAI API](https://stg.docs.luxonis.com/software/v3/)
@@ -16,7 +17,7 @@ Documentation is available over at [Luxonis DepthAI API](https://stg.docs.luxoni
1617
DepthAI library doesn't yet provide API stability guarantees. While we take care to properly deprecate old functions, some changes might still be breaking.
1718

1819
## Examples
19-
Examples for both C++ and Python are available in the `examples` folder. To get started with them see [README.md](./examples/README.md) for more information.
20+
Examples for both C++ and Python are available in the `examples` folder. To see hwo to build and run them see [README.md](./examples/README.md) for more information.
2021

2122
## Dependencies
2223
- CMake >= 3.14 and <4.0

V2V3PortinGuide.md

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
# DepthAI v2 → v3 Porting Guide
2+
3+
This document describes the changes between the v2 and v3 APIs of DepthAI and how to migrate existing code.
4+
5+
## What's new in the v3 API
6+
7+
* No more **explicit** XLink nodes – the XLink “bridges” are created automatically.
8+
* Host nodes – nodes that run on the host machine now work cleanly with device‑side nodes.
9+
* Custom host nodes – users can create custom nodes that run on the host machine
10+
11+
* Both `ThreadedHostNode` and `HostNode` are supported.
12+
* `ThreadedHostNode` works similarly to `ScriptNode`; the user **specifies** a `run` function that executes in a separate thread.
13+
* `HostNode` exposes an input map `inputs` whose entries are implicitly synced.
14+
* Available in both Python and C++.
15+
* Record‑and‑replay nodes.
16+
* `Pipeline` now has a live device that can be queried during pipeline creation.
17+
* Support for the new **Model Zoo**.
18+
* `ImageManip` has a refreshed API with better‑defined behaviour.
19+
* `ColorCamera` and `MonoCamera` are deprecated in favour of the new `Camera` node.
20+
21+
---
22+
23+
## Minimal changes required
24+
25+
* Remove the explicit creation of `dai.Device` (unless you intentionally pass a live device handle via the pipeline constructor – a rare edge case).
26+
* Remove explicit XLink nodes.
27+
* Replace `dai.Device(pipeline)` with `pipeline.start()`.
28+
* Replace any `.getOutputQueue()` calls with `output.createOutputQueue()`.
29+
* Replace any `.getInputQueue()` calls with `input.createInputQueue()`.
30+
31+
---
32+
33+
## Quick port: simple RGB stream example
34+
35+
Below, the old v2 code is commented with `# ORIG` and the new code with `# NEW`.
36+
37+
```python
38+
#!/usr/bin/env python3
39+
40+
import cv2
41+
import depthai as dai
42+
43+
# Create pipeline
44+
pipeline = dai.Pipeline()
45+
46+
# Define source and output
47+
camRgb = pipeline.create(dai.node.ColorCamera)
48+
49+
# ORIG – explicit XLink removed in v3
50+
# xoutVideo = pipeline.create(dai.node.XLinkOut)
51+
# xoutVideo.setStreamName("video")
52+
53+
# Properties
54+
camRgb.setBoardSocket(dai.CameraBoardSocket.CAM_A)
55+
camRgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_1080_P)
56+
camRgb.setVideoSize(1920, 1080)
57+
58+
# Linking
59+
# ORIG
60+
# camRgb.video.link(xoutVideo.input)
61+
# NEW – output queue straight from the node
62+
videoQueue = camRgb.video.createOutputQueue()
63+
64+
# ORIG – entire `with dai.Device` block removed
65+
# with dai.Device(pipeline) as device:
66+
# video = device.getOutputQueue(name="video", maxSize=1, blocking=False)
67+
# while True:
68+
# NEW – start the pipeline
69+
pipeline.start()
70+
while pipeline.isRunning():
71+
videoIn = videoQueue.get() # blocking
72+
cv2.imshow("video", videoIn.getCvFrame())
73+
if cv2.waitKey(1) == ord('q'):
74+
break
75+
```
76+
77+
This runs on RVC2 devices. Note that `ColorCamera`/`MonoCamera` nodes are deprecated on RVC4; see the next section for using `Camera` instead.
78+
79+
---
80+
81+
## Porting `ColorCamera` / `MonoCamera` usage to `Camera`
82+
83+
The new `Camera` node can expose as many outputs as you request.
84+
85+
```python
86+
camRgb = pipeline.create(dai.node.ColorCamera)
87+
camRgb.setPreviewSize(300, 300)
88+
camRgb.setInterleaved(False)
89+
camRgb.setColorOrder(dai.ColorCameraProperties.ColorOrder.RGB)
90+
outputQueue = camRgb.preview.createOutputQueue()
91+
```
92+
93+
turns into
94+
95+
```python
96+
camRgb = pipeline.create(dai.node.Camera).build() # don’t forget .build()
97+
cameraOutput = camRgb.requestOutput((300, 300), type=dai.ImgFrame.Type.RGB888p) # replaces .preview
98+
outputQueue = cameraOutput.createOutputQueue()
99+
```
100+
101+
Request multiple outputs simply by calling `requestOutput` again. For full‑resolution use‑cases that previously used `.isp`, call `requestFullResolutionOutput()` instead.
102+
103+
For former `MonoCamera` pipelines, replace the `.out` output with `requestOutput`, e.g.
104+
105+
```python
106+
mono = pipeline.create(dai.node.Camera).build()
107+
monoOut = mono.requestOutput((1280, 720), type=dai.ImgFrame.Type.GRAY8)
108+
```
109+
110+
---
111+
112+
## Porting the old `ImageManip` to the new API
113+
114+
The new API tracks every transformation in sequence and separates *how* the final image is resized.
115+
See the [official documentation](https://docs.luxonis.com/software/v3/depthai-components/nodes/image_manip/) for full details.
116+
117+
### v2 example
118+
119+
```python
120+
#!/usr/bin/env python3
121+
122+
import cv2
123+
import depthai as dai
124+
125+
# Create pipeline
126+
pipeline = dai.Pipeline()
127+
128+
camRgb = pipeline.create(dai.node.ColorCamera)
129+
camRgb.setPreviewSize(1000, 500)
130+
camRgb.setInterleaved(False)
131+
maxFrameSize = camRgb.getPreviewHeight() * camRgb.getPreviewWidth() * 3
132+
133+
# In this example we use 2 imageManips for splitting the original 1000x500
134+
# preview frame into 2 500x500 frames
135+
manip1 = pipeline.create(dai.node.ImageManip)
136+
manip1.initialConfig.setCropRect(0, 0, 0.5, 1)
137+
manip1.setMaxOutputFrameSize(maxFrameSize)
138+
camRgb.preview.link(manip1.inputImage)
139+
140+
manip2 = pipeline.create(dai.node.ImageManip)
141+
manip2.initialConfig.setCropRect(0.5, 0, 1, 1)
142+
manip2.setMaxOutputFrameSize(maxFrameSize)
143+
camRgb.preview.link(manip2.inputImage)
144+
145+
xout1 = pipeline.create(dai.node.XLinkOut)
146+
xout1.setStreamName('out1')
147+
manip1.out.link(xout1.input)
148+
149+
xout2 = pipeline.create(dai.node.XLinkOut)
150+
xout2.setStreamName('out2')
151+
manip2.out.link(xout2.input)
152+
153+
# Connect to device and start pipeline
154+
with dai.Device(pipeline) as device:
155+
# Output queue will be used to get the rgb frames from the output defined above
156+
q1 = device.getOutputQueue(name="out1", maxSize=4, blocking=False)
157+
q2 = device.getOutputQueue(name="out2", maxSize=4, blocking=False)
158+
159+
while True:
160+
if q1.has():
161+
cv2.imshow("Tile 1", q1.get().getCvFrame())
162+
163+
if q2.has():
164+
cv2.imshow("Tile 2", q2.get().getCvFrame())
165+
166+
if cv2.waitKey(1) == ord('q'):
167+
break
168+
```
169+
170+
### v3 equivalent:
171+
172+
```python
173+
#!/usr/bin/env python3
174+
175+
import cv2
176+
import depthai as dai
177+
178+
# Create pipeline
179+
pipeline = dai.Pipeline()
180+
181+
camRgb = pipeline.create(dai.node.Camera).build()
182+
preview = camRgb.requestOutput((1000, 500), type=dai.ImgFrame.Type.RGB888p)
183+
184+
# In this example we use 2 imageManips for splitting the original 1000x500
185+
# preview frame into 2 500x500 frames
186+
manip1 = pipeline.create(dai.node.ImageManip)
187+
manip1.initialConfig.addCrop(0, 0, 500, 500)
188+
preview.link(manip1.inputImage)
189+
190+
manip2 = pipeline.create(dai.node.ImageManip)
191+
manip2.initialConfig.addCrop(500, 0, 500, 500)
192+
preview.link(manip2.inputImage)
193+
194+
q1 = manip1.out.createOutputQueue()
195+
q2 = manip2.out.createOutputQueue()
196+
197+
pipeline.start()
198+
with pipeline:
199+
while pipeline.isRunning():
200+
if q1.has():
201+
cv2.imshow("Tile 1", q1.get().getCvFrame())
202+
203+
if q2.has():
204+
cv2.imshow("Tile 2", q2.get().getCvFrame())
205+
206+
if cv2.waitKey(1) == ord('q'):
207+
break
208+
```

examples/README.md

Lines changed: 12 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,137 +1,24 @@
1-
# Examples for the Depthai V3 API
2-
3-
The examples in this directory show the existing functionality of the Depthai V3 API.
4-
5-
The examples range from the ones that were just minimally ported from the V2 API, to showcase that porting the existing code is straightforward,
6-
to the ones that are specifically designed to show the new features of the V3 API.
7-
8-
The StereoDepth/stereo_autocreate.py example is a good example of the new features of the V3 API which showcases the ability to automatically create the stereo inputs
9-
as well as the ability to create a custom node that can be used in the pipeline.
10-
11-
```python
12-
# Create pipeline
13-
with dai.Pipeline() as pipeline:
14-
# Allow stereo inputs to be created automatically
15-
stereo = pipeline.create(dai.node.StereoDepth).build(autoCreateCameras=True)
16-
# This can be alternatively written as:
17-
# stereo = dai.node.StereoDepth(autoCreateCameras=True)
18-
visualizer = pipeline.create(StereoVisualizer).build(stereo.disparity)
19-
pipeline.start()
20-
while pipeline.isRunning():
21-
time.sleep(0.1)
22-
```
1+
# DepthAI Examples
232

3+
For more information about the examples, please refer to the [DepthAI documentation](https://stg.docs.luxonis.com/software/v3/examples/).
244
## Supported platforms
255
The examples are now split into three categories:
26-
* In the root directory of examples, there are the examples that are supported on all platforms
27-
* In RVC2/RVC4 directories there are the examples that are supported only on the RVC2/RVC4 platform
28-
29-
In the future we plan to make the examples more platform agnostic and we'll be slowly moving as many examples as possible to the root directory.
30-
31-
## Supported languages
32-
The examples are currently in Python and C++. The C++ examples are in the `cpp` directory and the Python examples are in the `python` directory.
33-
34-
Currently there are more python examples than C++ examples, but we plan to match the examples in both languages in the future and keep them 1:1.
6+
* In the root directory of examples, there are the examples that are supported on both RVC2 and RVC4 platforms devices
7+
* In RVC2/RVC4 directories there are the examples that are supported only on one of the platforms
358

36-
## Syntax differences compared to the V2 API
9+
## Python
3710

38-
In Python, currently, there exist two syntaxes for creating nodes. Before we decide, we first want to gather feedback from you.
39-
40-
One syntax uses the `Pipeline.create(...)` and `Node.build(...)` methods like this `pipeline.create(dai.node.StereoDepth).build(autoCreateCameras=True)`.
41-
42-
The other syntax uses the pipeline from the `with` statement and does all the work in the constructor -- e.g. `dai.node.StereoDepth(autoCreateCameras=True`.
43-
44-
In Python, both syntaxes also accept keyword arguments that mirror setter methods -- e.g. `dai.node.VideoEncoder(bitrate=2*24)`. Currently, not all parameters are available.
45-
46-
We'd love to hear your opinion which one you prefer. Currently, this syntax is now available only for `Camera`, `DetectionNetwork`, `StereoDepth` and `VideoEncoder`. Other nodes still have to be created with `pipeline.create`, parameters set with setter methods and inputs linked with `.link`.
47-
48-
Examples of this can be found in the `VideoEncoder` example.
49-
50-
## Python installation
51-
52-
To get the examples running, install the requirements with:
11+
To get the python examples running, install the requirements with:
5312

5413
```
5514
python3 depthai-core/examples/python/install_requirements.py
5615
```
57-
58-
NOTE: Right now wheels for windows are missing, but wheels for MacOS and Linux, both x86_64 and arm64 are available.
59-
60-
## What's new in the V3 API
61-
* No more expliclit XLink nodes - the XLink "bridges" are created automatically
62-
* Host nodes - nodes that run on the host machine now cleanly interoperate with the device nodes
63-
* Custom host nodes - the user can create custom nodes that run on the host machine
64-
* Both `ThreadedHostNode` and `HostNode` are supported.
65-
* `ThreadedHostNode` works in a very similar fashion to the `ScriptNode` where the user specifes a `run` function which is then executed in a separate thread.
66-
* `HostNode` has an input map `inputs` where all the inputs are implicitly synced
67-
* Available both in Python and C++
68-
* Record and replay nodes
69-
* Holistic record and replay is WIP
70-
* Support for both RVC2&RVC3 with initial support for RVC4
71-
* Device is now available at node construction, so we will be able to create smart defaults
72-
* Not used extensively yet, will be added gradually to more and more nodes.
73-
* Support for NNArchive for the existing NN nodes
74-
* `build(params)` functions for nodes where they can autocreate its inputs
75-
* Not yet used extensively yet, will be added gradually to more and more nodes.
76-
77-
78-
## How to port an example from V2 to V3
79-
The process of porting an example from V2 to V3 should be straightforward.
80-
81-
The minimal needed changes:
82-
* Remove the explicit creation of the device **or** pass the device in the pipeline constructor
83-
* Remove the explicit XLink nodes
84-
* Replace any `.getOutputQueue()` calls with `output.createOutputQueue()` calls
85-
86-
87-
### Quick porting example
88-
Let's take the simplest `rgb_video.py` example and port it to the V3 API.
89-
90-
The commented out code from the old API is commented with #ORIG and the new code is commented with #NEW.:
91-
```python
92-
#!/usr/bin/env python3
93-
94-
import cv2
95-
import depthai as dai
96-
97-
# Create pipeline
98-
# ORIG
99-
# pipeline = dai.Pipeline()
100-
with dai.Pipeline() as pipeline:
101-
# Define source and output
102-
camRgb = pipeline.create(dai.node.ColorCamera)
103-
104-
# ORIG
105-
# xoutVideo = pipeline.create(dai.node.XLinkOut)
106-
# xoutVideo.setStreamName("video")
107-
108-
# Properties
109-
camRgb.setBoardSocket(dai.CameraBoardSocket.CAM_A)
110-
camRgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_1080_P)
111-
camRgb.setVideoSize(1920, 1080)
112-
113-
# Linking
114-
camRgb.video.link(xoutVideo.input)
115-
# NEW
116-
videoQueue = camRgb.video.createOutputQueue()
117-
118-
# ORIG
119-
# with dai.Device(pipeline) as device:
120-
# video = device.getOutputQueue(name="video", maxSize=1, blocking=False)
121-
# while True:
122-
# NEW
123-
while pipeline.isRunning():
124-
videoIn = video.get()
125-
# Get BGR frame from NV12 encoded video frame to show with opencv
126-
# Visualizing the frame on slower hosts might have overhead
127-
cv2.imshow("video", videoIn.getCvFrame())
128-
129-
if cv2.waitKey(1) == ord('q'):
130-
break
16+
and run the example with:
17+
```
18+
python3 depthai-core/examples/python/Camera/camera_output.py
13119
```
13220

133-
134-
## Running examples
21+
## C++
13522

13623
To build the examples configure with following option added from the root of the repository:
13724
```
@@ -142,7 +29,7 @@ cmake --build build
14229
Then navigate to `build/examples` folder and run a preferred example
14330
```
14431
cd build/examples
145-
./MobileNet/rgb_mobilenet
32+
./cpp/Camera/camera_output
14633
```
14734

14835
## VSLAM
@@ -163,4 +50,4 @@ python3 depthai-core/examples/python/install_requirements.py --install_rerun
16350
You can also install it separately, installation instructions can be found [here](https://rerun.io/docs/getting-started/installing-viewer). If you use Numpy v2.0 you might need to downgrade it for Rerun.
16451
**NOTE** Currently, Rerun does not work with Numpy 2.0, you need to downgrade it to, for example 1.24.4 to be able to properly view images.
16552

166-
> ℹ️ Multi-Config generators (like Visual Studio on Windows) will have the examples built in `build/examples/MobileNet/[Debug/Release/...]/rgb_mobilenet`
53+
> ℹ️ Multi-Config generators (like Visual Studio on Windows) will have the examples built in `build/examples/Camera/[Debug/Release/...]/camera_output`

0 commit comments

Comments
 (0)