Skip to content

Commit 31838b0

Browse files
package fixes and path additions
1 parent c35cffd commit 31838b0

8 files changed

Lines changed: 119 additions & 2 deletions

File tree

LICENSE

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Shared Use License
2+
3+
This software in source and binary forms is owned by Derivative Inc. (Derivative) and can only be used, and/or modified for use, in conjunction with Derivative's TouchDesigner software, and only if you are a licensee who has accepted Derivative's TouchDesigner license or assignment agreement (which also govern the use of this software). You may share or redistribute a modified version of this software provided the following conditions are met:
4+
5+
1. The shared files or redistribution must retain the information set out above and this list of conditions.
6+
2. Derivative's name (Derivative Inc.) or its trademarks may not be used to endorse or promote products derived from this software without specific prior written permission from Derivative.

TDOAK.toe

-159 KB
Binary file not shown.

src/TDOAK/TDOAK.tox

-232 Bytes
Binary file not shown.

src/TDOAK/TDOAKCamCtl.tox

-24 Bytes
Binary file not shown.

src/TDOAK/examples/detection_input_pipeline.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from __future__ import annotations
1+
from __future__ import annotations
22

33
# detection_input_pipeline.py — YOLO object detection on HOST frames (depthai v3)
44
# Load into the Pipeline DAT parameter of the OAK component.
@@ -11,7 +11,7 @@
1111
#
1212
# Feed it once per frame from an Execute DAT:
1313
# def onFrameStart(frame):
14-
# op('TDOAK').ext.OAKManagerExt.SendFrame('image_in', op('moviefilein1'))
14+
# op('TDOAK').SendFrame('image_in', op('moviefilein1'))
1515
#
1616
# Streams:
1717
# 'rgb' — the letterboxed frame inference ran on (loops back from the device),
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from __future__ import annotations
2+
3+
# mono_depth_pipeline.py — monocular (single-camera) depth via MiDaS v2.1 (depthai v3)
4+
# Neural depth from ONE ordinary RGB camera — no stereo pair, no ToF.
5+
# Load into the Pipeline DAT parameter of the OAK component.
6+
#
7+
# REQUIRES the `depthai_nodes` package (provides ParsingNeuralNetwork, which resolves the
8+
# model from the Luxonis Model Zoo and parses its output for you).
9+
#
10+
# MiDaS v2.1 ships an RVC2 (Myriad X / OAK-D) build — unlike Depth-Anything, which is
11+
# RVC4-only and won't run on these devices.
12+
#
13+
# Streams:
14+
# 'rgb' — BGR passthrough: the exact frame inference ran on (384x256), so the depth
15+
# map below is pixel-aligned with it.
16+
# 'depth' — a depthai_nodes Map2D message. OAKManagerExt's built-in Map2D decoder turns
17+
# it into a float32 (H, W) array, so a Script TOP bound to 'depth' fills
18+
# automatically as a single-channel float TOP. Values are RELATIVE inverse
19+
# depth (larger = nearer), NOT metric — normalize for display, e.g. divide by
20+
# the frame's max in a Script TOP or with a Math/Normalize TOP downstream.
21+
22+
from typing import TYPE_CHECKING
23+
24+
if TYPE_CHECKING:
25+
import depthai as dai
26+
27+
# Model Zoo slug + variant. Other RVC2 variants: 256x192 (faster), 288x512 / 384x512 (finer).
28+
MODEL: str = 'luxonis/midas-v2-1:small-384x256'
29+
30+
31+
def build(pipeline: dai.Pipeline) -> tuple[dict[str, dai.DataOutputQueue], list[str]]:
32+
import depthai as dai
33+
from depthai_nodes.node import ParsingNeuralNetwork
34+
35+
cam = pipeline.create(dai.node.Camera).build()
36+
nn = pipeline.create(ParsingNeuralNetwork).build(cam, MODEL)
37+
38+
queues: dict[str, dai.DataOutputQueue] = {
39+
'rgb': nn.passthrough.createOutputQueue(maxSize=1, blocking=False),
40+
'depth': nn.out.createOutputQueue(maxSize=1, blocking=False),
41+
}
42+
43+
return queues, ['rgb', 'depth']

src/TDOAK/examples/pose_handler.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""
2+
def parse(msg):
3+
# WORKER THREAD — no op()/TD access. Decode the model's message into plain,
4+
# thread-safe data (numpy array, or list/dict of primitives). Return None to skip.
5+
return msg.getTensor("pose") # or keypoints, clusters, segmentation, ...
6+
"""
7+
import numpy as np
8+
9+
def fill(scriptOp, data): # data: list[PoseEntry]
10+
# MAIN THREAD — full TD access, runs inside the operator's cook.
11+
scriptOp.clear()
12+
if not data:
13+
scriptOp.copyNumpyArray(np.zeros((2, 17), dtype=np.float32)) # keep 2 ch, 0 samples
14+
return
15+
# Stack every person's keypoints as samples -> (P*17, 2)
16+
kp = np.concatenate(
17+
[np.asarray(p['keypoints'], dtype=np.float32) for p in data],
18+
axis=0,
19+
)
20+
arr = np.ascontiguousarray(kp.T) # (2, P*17): ch0 = x, ch1 = y
21+
arr[1] = 1.0 - arr[1] # flip Y to match the flipud'd rgb display
22+
scriptOp.copyNumpyArray(arr) # -> channels chan1 (x), chan2 (y)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""
2+
def parse(msg):
3+
# WORKER THREAD — no op()/TD access. Decode the model's message into plain,
4+
# thread-safe data (numpy array, or list/dict of primitives). Return None to skip.
5+
return msg.getTensor("pose") # or keypoints, clusters, segmentation, ...
6+
"""
7+
import numpy as np
8+
9+
def fill(scriptOp, data): # data: list[PoseEntry]
10+
# MAIN THREAD — full TD access, runs inside the operator's cook.
11+
stagingData = scriptOp.createGeometryStagingData()
12+
13+
if not data:
14+
scriptOp.buildGeometry(stagingData)
15+
return
16+
17+
stagingData.createPointAttrib(name='P')
18+
# Stack every person's keypoints as samples -> (P*17, 2)
19+
20+
kp = np.concatenate(
21+
[np.asarray(p['keypoints'], dtype=np.float32) for p in data],
22+
axis=0,
23+
)
24+
25+
# this is of shape (n*17,2), but we need 3 coordinates per point
26+
kp = np.pad(kp, ((0, 0), (0, 1)), mode='constant')
27+
# flip y
28+
kp[:, 1] = 1 - kp[:, 1]
29+
stagingData.appendPointAttribValues('P', kp.tolist())
30+
31+
# now build the edges between the keypoints
32+
# be careful, as we have to add 18 to every new detected array point indexes to account for more than 1 detection.
33+
34+
edge_chunks = []
35+
for i, p in enumerate(data):
36+
edges = np.asarray(p['edges'], dtype=np.float32)
37+
edges += i * 18
38+
edge_chunks.append(edges)
39+
40+
edges = np.concatenate(edge_chunks, axis=0)
41+
42+
for e in edges:
43+
stagingData.appendPrimLine(int(e[0]),int(e[1]))
44+
45+
scriptOp.buildGeometry(stagingData)
46+

0 commit comments

Comments
 (0)