Dark Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 97f9d6f

Browse files
authored
Merge pull request #1114 from luxonis/release_2.31.0.0
Release 2.31.0.0
2 parents 765299d + 7a3e683 commit 97f9d6f

File tree

12 files changed

+181
-48
lines changed
  • .github/workflows
    • docker-hub.yml
    • main.yml
  • CMakeLists.txt
  • cmake/Hunter
    • config.cmake
  • depthai-core
  • examples/ObjectTracker
    • object_tracker.py
  • setup.py
  • src
    • DatatypeBindings.cpp
    • pipeline
      • datatype
        • ObjectTrackerConfigBindings.cpp
      • node
        • ObjectTrackerBindings.cpp
  • utilities
    • cam_test.py
    • stress_test.py

12 files changed

+181
-48
lines changed

.github/workflows/docker-hub.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ jobs:
1313
runs-on: ${{ matrix.os }}
1414
strategy:
1515
matrix:
16-
os: [ubuntu-latest, [Linux, ARM], [Linux, ARM64]]
16+
os: [ubuntu-latest, [Linux, ARM], ubuntu-24.04-arm]
1717
include:
1818
- os: ubuntu-latest
1919
arch: amd64
2020
- os: [Linux, ARM]
2121
arch: armv7
22-
- os: [Linux, ARM64]
22+
- os: ubuntu-24.04-arm
2323
arch: armv8
2424
steps:
2525
- name: Clean the workspace

.github/workflows/main.yml

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,13 @@ jobs:
6767
needs: build-docstrings
6868
strategy:
6969
matrix:
70-
os: [ubuntu-latest, windows-latest, macos-latest]
70+
os: [ubuntu-latest, windows-latest, macos-14]
7171
runs-on: ${{ matrix.os }}
7272
steps:
7373
- name: Print home directory
7474
run: echo Home directory inside container $HOME
7575
- name: Setup cmake
76-
if: matrix.os == 'macos-latest'
76+
if: matrix.os == 'macos-14'
7777
uses: jwlawson/actions-setup-cmake@v1.13
7878
with:
7979
cmake-version: '3.29.x'
@@ -113,7 +113,7 @@ jobs:
113113
sudo apt install libusb-1.0-0-dev
114114
115115
- name: Install dependencies (MacOS)
116-
if: matrix.os == 'macos-latest'
116+
if: matrix.os == 'macos-14'
117117
run: |
118118
python -m pip install --upgrade pip
119119
brew install libusb
@@ -184,7 +184,7 @@ jobs:
184184
runs-on: windows-latest
185185
strategy:
186186
matrix:
187-
python-version: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12', '3.13']
187+
python-version: [3.9, '3.10', '3.11', '3.12', '3.13', '3.14']
188188
python-architecture: [x64, x86]
189189
fail-fast: false
190190
steps:
@@ -207,6 +207,11 @@ jobs:
207207
- name: Select Windows SDK
208208
run: echo "CMAKE_ARGS=-DCMAKE_SYSTEM_VERSION=${{ env.CMAKE_WINDOWS_SDK_VERSION }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
209209

210+
- name: Set UTF-8 encoding
211+
run: |
212+
echo "PYTHONIOENCODING=utf-8" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
213+
echo "PYTHONUTF8=1" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
214+
210215
- name: Install dependencies
211216
run: choco install strawberryperl
212217
- name: Set up Python ${{ matrix.python-version }}
@@ -240,7 +245,7 @@ jobs:
240245
needs: build-docstrings
241246
strategy:
242247
matrix:
243-
python-version: [3.8, 3.9, '3.10', '3.11', '3.12', '3.13']
248+
python-version: [3.9, '3.10', '3.11', '3.12', '3.13', '3.14']
244249
os: [macos-13, macos-14] # macos-13 is x64, macos-14 is arm64
245250
runs-on: ${{ matrix.os }}
246251
steps:
@@ -301,7 +306,7 @@ jobs:
301306
needs: build-docstrings
302307
runs-on: ubuntu-latest
303308
container:
304-
image: quay.io/pypa/manylinux_2_28_x86_64:latest
309+
image: quay.io/pypa/manylinux_2_28_x86_64:2025.11.10-2
305310
env:
306311
PLAT: manylinux_2_28_x86_64
307312
steps:
@@ -317,7 +322,7 @@ jobs:
317322
run: yum install -y --disableplugin=fastestmirror libusb1-devel perl-core
318323
- name: Installing cmake dependency
319324
run: |
320-
/opt/python/cp38-cp38/bin/python3.8 -m pip install cmake
325+
/opt/python/cp38-cp38/bin/python3.8 -m pip install "cmake<4.0"
321326
ln -s /opt/python/cp38-cp38/bin/cmake /bin/
322327
- name: Create folder structure
323328
run: mkdir -p wheelhouse/audited/
@@ -331,8 +336,8 @@ jobs:
331336

332337
- name: Build and install depthai-core
333338
run: |
334-
cmake -S depthai-core/ -B build_core -D CMAKE_BUILD_TYPE=Release -D CMAKE_TOOLCHAIN_FILE=$PWD/cmake/toolchain/pic.cmake
335-
cmake --build build_core --target install --parallel 4
339+
/opt/python/cp38-cp38/bin/cmake -S depthai-core/ -B build_core -D CMAKE_BUILD_TYPE=Release -D CMAKE_TOOLCHAIN_FILE=$PWD/cmake/toolchain/pic.cmake
340+
/opt/python/cp38-cp38/bin/cmake --build build_core --target install --parallel 4
336341
echo "DEPTHAI_INSTALLATION_DIR=$PWD/build_core/install/" >> $GITHUB_ENV
337342
338343
- name: Append build hash if not a tagged commit
@@ -341,10 +346,11 @@ jobs:
341346

342347
- name: Building source distribution
343348
run: |
349+
/opt/python/cp38-cp38/bin/python3.8 -m pip install --upgrade setuptools wheel
344350
/opt/python/cp38-cp38/bin/python3.8 setup.py sdist --formats=gztar
345351
mv dist/* wheelhouse/audited/
346352
- name: Build wheels
347-
run: for PYBIN in /opt/python/cp3{7..13}*/bin; do "${PYBIN}/pip" wheel . -w ./wheelhouse/ --verbose; done
353+
run: for PYBIN in /opt/python/cp3{9..14}*/bin; do "${PYBIN}/pip" wheel . -w ./wheelhouse/ --verbose; done
348354
- name: Audit wheels
349355
run: for whl in wheelhouse/*.whl; do auditwheel repair "$whl" --plat $PLAT -w wheelhouse/audited/; done
350356
- name: Archive wheel artifacts
@@ -363,9 +369,9 @@ jobs:
363369
# This job builds wheels for ARM64 arch
364370
build-linux-arm64:
365371
needs: build-docstrings
366-
runs-on: [self-hosted, linux, ARM64]
372+
runs-on: ubuntu-24.04-arm
367373
container:
368-
image: quay.io/pypa/manylinux_2_28_aarch64:latest
374+
image: quay.io/pypa/manylinux_2_28_aarch64:2025.11.10-2
369375
env:
370376
PLAT: manylinux_2_28_aarch64
371377
# Mount local hunter cache directory, instead of transfering to Github and back
@@ -379,7 +385,7 @@ jobs:
379385
run: yum install -y --disableplugin=fastestmirror libusb1-devel perl-core
380386
- name: Installing cmake dependency
381387
run: |
382-
/opt/python/cp38-cp38/bin/python3.8 -m pip install cmake
388+
/opt/python/cp38-cp38/bin/python3.8 -m pip install "cmake<4"
383389
ln -s /opt/python/cp38-cp38/bin/cmake /bin/
384390
- name: Create folder structure
385391
run: mkdir -p wheelhouse/audited/
@@ -393,15 +399,15 @@ jobs:
393399

394400
- name: Build and install depthai-core
395401
run: |
396-
cmake -S depthai-core/ -B build_core -D CMAKE_BUILD_TYPE=Release -D CMAKE_TOOLCHAIN_FILE=$PWD/cmake/toolchain/pic.cmake
397-
cmake --build build_core --target install --parallel 4
402+
/opt/python/cp38-cp38/bin/cmake -S depthai-core/ -B build_core -D CMAKE_BUILD_TYPE=Release -D CMAKE_TOOLCHAIN_FILE=$PWD/cmake/toolchain/pic.cmake
403+
/opt/python/cp38-cp38/bin/cmake --build build_core --target install --parallel 4
398404
echo "DEPTHAI_INSTALLATION_DIR=$PWD/build_core/install/" >> $GITHUB_ENV
399405
400406
- name: Append build hash if not a tagged commit
401407
if: startsWith(github.ref, 'refs/tags/v') != true
402408
run: echo "BUILD_COMMIT_HASH=${{github.sha}}" >> $GITHUB_ENV
403409
- name: Building wheels
404-
run: for PYBIN in /opt/python/cp3{7..13}*/bin; do "${PYBIN}/pip" wheel . -w ./wheelhouse/ --verbose; done
410+
run: for PYBIN in /opt/python/cp3{9..14}*/bin; do "${PYBIN}/pip" wheel . -w ./wheelhouse/ --verbose; done
405411
- name: Auditing wheels
406412
run: for whl in wheelhouse/*.whl; do auditwheel repair "$whl" --plat $PLAT -w wheelhouse/audited/; done
407413
- name: Archive wheel artifacts

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ pybind11_add_module(${TARGET_NAME}
159159
src/pipeline/datatype/PointCloudConfigBindings.cpp
160160
src/pipeline/datatype/PointCloudDataBindings.cpp
161161
src/pipeline/datatype/ImageAlignConfigBindings.cpp
162+
src/pipeline/datatype/ObjectTrackerConfigBindings.cpp
162163
)
163164

164165
if(WIN32)

cmake/Hunter/config.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
hunter_config(
33
pybind11
44
VERSION "2.12.0"
5-
URL "https://github.com/pybind/pybind11/archive/refs/tags/v2.12.0.tar.gz"
6-
SHA1 "e70610cba7b6b7d7a57827d5357c016ad2155c0f"
5+
URL "https://github.com/pybind/pybind11/archive/refs/tags/v3.0.1.tar.gz"
6+
SHA1 "b20ddcd79e2b03b7e2777a2a0b06b646f2f23ce0"
77
)

examples/ObjectTracker/object_tracker.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@
2929

3030
xlinkOut = pipeline.create(dai.node.XLinkOut)
3131
trackerOut = pipeline.create(dai.node.XLinkOut)
32+
xinTrackerConfig = pipeline.create(dai.node.XLinkIn)
3233

3334
xlinkOut.setStreamName("preview")
3435
trackerOut.setStreamName("tracklets")
36+
xinTrackerConfig.setStreamName("trackerConfig")
3537

3638
# Properties
3739
camRgb.setPreviewSize(300, 300)
@@ -64,18 +66,27 @@
6466
detectionNetwork.out.link(objectTracker.inputDetections)
6567
objectTracker.out.link(trackerOut.input)
6668

69+
# set tracking parameters
70+
objectTracker.setOcclusionRatioThreshold(0.4)
71+
objectTracker.setTrackletMaxLifespan(120)
72+
objectTracker.setTrackletBirthThreshold(3)
73+
74+
xinTrackerConfig.out.link(objectTracker.inputConfig)
75+
6776
# Connect to device and start pipeline
6877
with dai.Device(pipeline) as device:
6978

7079
preview = device.getOutputQueue("preview", 4, False)
7180
tracklets = device.getOutputQueue("tracklets", 4, False)
81+
trackerConfigQueue = device.getInputQueue("trackerConfig")
7282

7383
startTime = time.monotonic()
7484
counter = 0
7585
fps = 0
7686
frame = None
7787

7888
while(True):
89+
latestTrackedIds = []
7990
imgFrame = preview.get()
8091
track = tracklets.get()
8192

@@ -106,9 +117,26 @@
106117
cv2.putText(frame, t.status.name, (x1 + 10, y1 + 50), cv2.FONT_HERSHEY_TRIPLEX, 0.5, 255)
107118
cv2.rectangle(frame, (x1, y1), (x2, y2), color, cv2.FONT_HERSHEY_SIMPLEX)
108119

120+
if t.status == dai.Tracklet.TrackingStatus.TRACKED:
121+
latestTrackedIds.append(t.id)
122+
109123
cv2.putText(frame, "NN fps: {:.2f}".format(fps), (2, frame.shape[0] - 4), cv2.FONT_HERSHEY_TRIPLEX, 0.4, color)
110124

111125
cv2.imshow("tracker", frame)
112126

113-
if cv2.waitKey(1) == ord('q'):
127+
key = cv2.waitKey(1)
128+
if key == ord('q'):
114129
break
130+
elif key == ord('g'):
131+
# send tracker config to device
132+
config = dai.ObjectTrackerConfig()
133+
134+
# take a random ID from the latest tracked IDs
135+
if len(latestTrackedIds) > 0:
136+
idToRemove = (np.random.choice(latestTrackedIds))
137+
print(f"Force removing ID: {idToRemove}")
138+
config.forceRemoveID(idToRemove)
139+
trackerConfigQueue.send(config)
140+
else:
141+
print("No tracked IDs available to force remove")
142+

setup.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,19 +238,18 @@ def build_extension(self, ext):
238238
"Operating System :: Unix",
239239
"Programming Language :: Python",
240240
"Programming Language :: Python :: 3",
241-
"Programming Language :: Python :: 3.7",
242-
"Programming Language :: Python :: 3.8",
243241
"Programming Language :: Python :: 3.9",
244242
"Programming Language :: Python :: 3.10",
245243
"Programming Language :: Python :: 3.11",
246244
"Programming Language :: Python :: 3.12",
247245
"Programming Language :: Python :: 3.13",
246+
"Programming Language :: Python :: 3.14",
248247
"Programming Language :: C++",
249248
"Programming Language :: Python :: Implementation :: CPython",
250249
"Topic :: Scientific/Engineering",
251250
"Topic :: Software Development",
252251
],
253-
python_requires='>=3.7',
252+
python_requires='>=3.9',
254253
entry_points={
255254
"console_scripts": [
256255
f'depthai={DEPTHAI_CLI_MODULE_NAME}.depthai_cli:cli'

src/DatatypeBindings.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ void bind_tracklets(pybind11::module& m, void* pCallstack);
2828
void bind_pointcloudconfig(pybind11::module& m, void* pCallstack);
2929
void bind_pointclouddata(pybind11::module& m, void* pCallstack);
3030
void bind_imagealignconfig(pybind11::module& m, void* pCallstack);
31+
void bind_objecttrackerconfig(pybind11::module& m, void* pCallstack);
3132

3233
void DatatypeBindings::addToCallstack(std::deque& callstack) {
3334
// Bind common datatypebindings
@@ -59,6 +60,7 @@ void DatatypeBindings::addToCallstack(std::deque& callstack) {
5960
callstack.push_front(bind_pointcloudconfig);
6061
callstack.push_front(bind_pointclouddata);
6162
callstack.push_front(bind_imagealignconfig);
63+
callstack.push_front(bind_objecttrackerconfig);
6264
}
6365

6466
void DatatypeBindings::bind(pybind11::module& m, void* pCallstack){

src/pipeline/datatype/ObjectTrackerConfigBindings.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include "DatatypeBindings.hpp"
2+
#include "pipeline/CommonBindings.hpp"
3+
#include <unordered_map>
4+
#include <memory>
5+
6+
// depthai
7+
#include "depthai/pipeline/datatype/ObjectTrackerConfig.hpp"
8+
9+
//pybind
10+
#include <pybind11/chrono.h>
11+
#include <pybind11/numpy.h>
12+
13+
// #include "spdlog/spdlog.h"
14+
15+
void bind_objecttrackerconfig(pybind11::module& m, void* pCallstack){
16+
17+
using namespace dai;
18+
19+
py::class_> rawConfig(m, "RawObjectTrackerConfig", DOC(dai, RawObjectTrackerConfig));
20+
py::class_> config(m, "ObjectTrackerConfig", DOC(dai, ObjectTrackerConfig));
21+
22+
///////////////////////////////////////////////////////////////////////
23+
///////////////////////////////////////////////////////////////////////
24+
///////////////////////////////////////////////////////////////////////
25+
// Call the rest of the type defines, then perform the actual bindings
26+
Callstack* callstack = (Callstack*) pCallstack;
27+
auto cb = callstack->top();
28+
callstack->pop();
29+
cb(m, pCallstack);
30+
// Actual bindings
31+
///////////////////////////////////////////////////////////////////////
32+
///////////////////////////////////////////////////////////////////////
33+
///////////////////////////////////////////////////////////////////////
34+
35+
// Metadata / raw
36+
rawConfig
37+
.def(py::init<>())
38+
.def_readwrite("trackletIdsToRemove", &RawObjectTrackerConfig::trackletIdsToRemove, DOC(dai, RawObjectTrackerConfig, trackletIdsToRemove))
39+
;
40+
41+
// Message
42+
config
43+
.def(py::init<>())
44+
.def(py::init>())
45+
46+
.def("set", &ObjectTrackerConfig::set, py::arg("config"), DOC(dai, ObjectTrackerConfig, set))
47+
.def("get", &ObjectTrackerConfig::get, DOC(dai, ObjectTrackerConfig, get))
48+
.def("forceRemoveID", &ObjectTrackerConfig::forceRemoveID, DOC(dai, ObjectTrackerConfig, forceRemoveID))
49+
.def("forceRemoveIDs", &ObjectTrackerConfig::forceRemoveIDs, DOC(dai, ObjectTrackerConfig, forceRemoveIDs))
50+
;
51+
52+
// add aliases
53+
54+
}

src/pipeline/node/ObjectTrackerBindings.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,18 @@ void bind_objecttracker(pybind11::module& m, void* pCallstack){
4848
.def_readwrite("detectionLabelsToTrack", &ObjectTrackerProperties::detectionLabelsToTrack, DOC(dai, ObjectTrackerProperties, detectionLabelsToTrack))
4949
.def_readwrite("trackerType", &ObjectTrackerProperties::trackerType, DOC(dai, ObjectTrackerProperties, trackerType))
5050
.def_readwrite("trackerIdAssignmentPolicy", &ObjectTrackerProperties::trackerIdAssignmentPolicy, DOC(dai, ObjectTrackerProperties, trackerIdAssignmentPolicy))
51+
.def_readwrite("trackingPerClass", &ObjectTrackerProperties::trackingPerClass, DOC(dai, ObjectTrackerProperties, trackingPerClass))
52+
.def_readwrite("occlusionRatioThreshold", &ObjectTrackerProperties::occlusionRatioThreshold, DOC(dai, ObjectTrackerProperties, occlusionRatioThreshold))
53+
.def_readwrite("trackletMaxLifespan", &ObjectTrackerProperties::trackletMaxLifespan, DOC(dai, ObjectTrackerProperties, trackletMaxLifespan))
54+
.def_readwrite("trackletBirthThreshold", &ObjectTrackerProperties::trackletBirthThreshold, DOC(dai, ObjectTrackerProperties, trackletBirthThreshold))
5155
;
5256

5357
// Node
5458
objectTracker
5559
.def_readonly("inputTrackerFrame", &ObjectTracker::inputTrackerFrame, DOC(dai, node, ObjectTracker, inputTrackerFrame))
5660
.def_readonly("inputDetectionFrame", &ObjectTracker::inputDetectionFrame, DOC(dai, node, ObjectTracker, inputDetectionFrame))
5761
.def_readonly("inputDetections", &ObjectTracker::inputDetections, DOC(dai, node, ObjectTracker, inputDetections))
62+
.def_readonly("inputConfig", &ObjectTracker::inputConfig, DOC(dai, node, ObjectTracker, inputConfig))
5863
.def_readonly("out", &ObjectTracker::out, DOC(dai, node, ObjectTracker, out))
5964
.def_readonly("passthroughTrackerFrame", &ObjectTracker::passthroughTrackerFrame, DOC(dai, node, ObjectTracker, passthroughTrackerFrame))
6065
.def_readonly("passthroughDetectionFrame", &ObjectTracker::passthroughDetectionFrame, DOC(dai, node, ObjectTracker, passthroughDetectionFrame))
@@ -66,6 +71,9 @@ void bind_objecttracker(pybind11::module& m, void* pCallstack){
6671
.def("setTrackerType", &ObjectTracker::setTrackerType, py::arg("type"), DOC(dai, node, ObjectTracker, setTrackerType))
6772
.def("setTrackerIdAssignmentPolicy", &ObjectTracker::setTrackerIdAssignmentPolicy, py::arg("type"), DOC(dai, node, ObjectTracker, setTrackerIdAssignmentPolicy))
6873
.def("setTrackingPerClass", &ObjectTracker::setTrackingPerClass, py::arg("trackingPerClass"), DOC(dai, node, ObjectTracker, setTrackingPerClass))
74+
.def("setOcclusionRatioThreshold", &ObjectTracker::setOcclusionRatioThreshold, py::arg("occlusionRatioThreshold"), DOC(dai, node, ObjectTracker, setOcclusionRatioThreshold))
75+
.def("setTrackletMaxLifespan", &ObjectTracker::setTrackletMaxLifespan, py::arg("lifespan"), DOC(dai, node, ObjectTracker, setTrackletMaxLifespan))
76+
.def("setTrackletBirthThreshold", &ObjectTracker::setTrackletBirthThreshold, py::arg("threshold"), DOC(dai, node, ObjectTracker, setTrackletBirthThreshold))
6977
;
7078
daiNodeModule.attr("ObjectTracker").attr("Properties") = objectTrackerProperties;
7179

0 commit comments

Comments
(0)