This project was created and dedicated to all the students, colleagues, and friends during my time teaching at the Department of Computational Art at Goldsmiths, University of London
Farewell for now! Thank you all for everything!
A self-contained TouchDesigner component that runs YOLO11 object detection inside a headless browser bundled with TouchDesigner β no Python environment, no conda, no pip install required on the user's machine. Drop the .tox into your project and you're done.
β οΈ Requires an internet connection. The embedded headless browser needs network access while running (to bootstrap the inference runtime). Make sure your machine is online.
β Works on TouchDesigner Commercial and Non-Commercial. The binary frame pipeline stays within the Non-Commercial 1280Γ720 TOP cap (frames are 640Γ640).
- License: MIT (see
tdyolo-web/LICENSE) - Architecture inspired by torinmb/yolo-touchdesigner. Implementation is independent β no source code was copied. See "Attribution" below.
Two ways to use the component:
- Download
TDYolo_v2.toxfrom the Releases page. - In TouchDesigner 2023.12000 or newer, drag
TDYolo_v2.toxinto your.toeproject.
- Clone the repo:
git clone https://github.com/patrickhartono/TDYolo.git cd TDYolo - Open
TDYolo_v2.toein TouchDesigner 2023.12000 or newer.
report(table DAT, 8 columns):Object_Type, Confidence, X_Center, Y_Center, Width, Height, ID, ClassIDsummary(table DAT, 2 columns):Object_Type, Count- Visual overlays via
null2(bbox),null5(labels),null3(source frame) β see Outputs below
That is the entire setup. There is no Python environment to install and no external runtime dependency.
| Input | Type | Description |
|---|---|---|
in1 |
TOP | External video feed. If unconnected, the bundled moviefilein1 (sample video in video/) is used. |
The component exposes 6 outputConnectors at its boundary:
| Output | Type | Description |
|---|---|---|
report |
DAT (table) | 8 columns: Object_Type, Confidence, X_Center, Y_Center, Width, Height, ID, ClassID. Coordinates are top-left origin, pixel-space in the 640Γ640 inference canvas. |
summary |
DAT (table) | 2 columns: Object_Type, Count. Aggregated per-class counts for the current frame. |
null2 |
TOP | Bounding box overlay (transparent canvas, only edges drawn, per-class colors). |
null5 |
TOP | Detection labels overlay (transparent canvas, "person 1: 0.93" badges above each bbox, black text on class-colored background). |
null3 |
TOP | Synched 640Γ640 source frame the inference engine actually processed. Use this as the underlying image when compositing overlays. |
Compose at the parent /project1 level using compositeTOPs to combine source + bboxes + labels into your final view.
| Param | Type | Default | Description |
|---|---|---|---|
Detectionlables |
Str | empty | Comma-separated whitelist of COCO class names (e.g. person, car, dog). Empty = all 80 COCO classes. |
Confidence |
Float | 0.2 |
Minimum detection confidence (0β1). Lower = more detections; higher = stricter. |
Frameskip |
Int | 0 |
Frames to skip between inference runs (0 = every frame, 2 = run every 3rd frame, etc.). Performance lever. |
Detectionlimit |
Int | 1 |
Max detections per frame (0 = unlimited). Highest-confidence kept first. |
Model |
Str (read-only) | yolo11n |
Detection model. Only yolo11n is bundled β displayed as text, not configurable. |
Changing any of these parameters auto-reloads the embedded browser inference page (~1β2 second handover). No manual reload needed.
| Param | Type | Description |
|---|---|---|
Port |
Int (display) | The TCP port the embedded webserverDAT is bound to. Assigned automatically at project load. |
Reset |
Pulse | Manual browser reload. Same effect as a Detection-page param change. Useful if the visual feels stuck but the server is still alive. |
Hardreconnect |
Pulse | Destroy + recreate the embedded Chromium browser on the same port. Use when the browser is frozen (ERR_CONNECTION_REFUSED or no detections coming through). |
Findnewport |
Pulse | Pick a fresh free port and rebind the server. Use only when the port itself is locked by another process. |
| Param | Type | Description |
|---|---|---|
Version |
Str (display) | Component version (0.1.0). |
License |
Str (display) | MIT. |
Attribution |
Str (display) | Architecture inspiration credit. |
Help |
Pulse | Opens https://github.com/patrickhartono/TDYolo in your default browser. |
in1 (or moviefilein1)
β
βΌ
flip1 β letterbox (640Γ640) β source ββββ
β
βΌ
chopexec3 (reads source RGBA directly,
packs to CHW uint8 in Python,
trigger=absTime.frame)
β
βΌ WebSocket (binary) β 127.0.0.1:<port>
βββββββββ΄βββββββββββββββββββββββββββββ
βΌ β
webserver_v2 (webserverDAT + VFS-backed β
HTTP server) β
β β
β serves index.html + JS bundle + β
β ONNX model from VFS to: β
βΌ β
webrender1 (headless Chromium) β
β β
β ONNX Runtime Web runs yolo11n β
β on each binary frame β
β β
β JSON predictions over WS ββββββββββ
βΌ
webserver_v2/predictions (textDAT, raw JSON)
β
βΌ
datexec1 (parse β tables)
β
βΌ
report (8-col) / summary (2-col)
Frames travel TouchDesigner β browser as compact 12-byte-header binary messages followed by HΓWΓ3 CHW uint8 payload. Detections travel browser β TouchDesigner as JSON text messages on the same WebSocket.
TDYolo/
βββ README.md # this file
βββ TDYolo_v2.toe # bundled TouchDesigner project
βββ TDYolo_v2.tox # exported drop-in component (drag into your own .toe)
βββ ARCHITECTURE-TDYolo_v2.md # node-level architecture reference
βββ COMPARISON.md # TDYolo v1 vs TDYolo_v2 vs torinmb's yolo container
βββ AGENTS.md # collaboration notes
βββ tdyolo-web/ # browser app source (MIT-licensed)
β βββ LICENSE
β βββ package.json
β βββ vite.config.js
β βββ index.html
β βββ public/models/yolo11n.onnx # bundled detection model
β βββ src/
β β βββ main.js # entry β WS lifecycle + mode select
β β βββ config.js # URL param parsing
β β βββ pipeline.js # per-frame orchestrator
β β βββ inference/
β β β βββ onnx.js # ORT session manager
β β β βββ postprocess.js # YOLO decode + NMS
β β β βββ io.js # ImageData/CHW β input tensor
β β βββ modes/
β β β βββ binary.js # TD β browser binary frame protocol
β β β βββ webcam.js # browser webcam fallback
β β βββ utils/
β β βββ protocol.js # JSON output schema
β β βββ math.js # IoU
β βββ dist/ # built output, embedded into TD VFS
βββ video/
β βββ example-1.mp4 # short sample
β βββ example-2.mov # longer sample
βββ python-script/ # legacy v1 (conda-based) β kept for historical reference
- Default backend is WebGPU with WASM fallback. Pass
?cpu=truein the URL to force WASM (slower but compatible with older Chromium builds). - A 640Γ640 frame of
yolo11nruns at roughly 30β60 FPS on an Apple Silicon MacBook Pro depending on backend choice and webrenderTOP overhead. - WebSocket frame transport adds β 1 frame of latency vs an in-process inference loop β unnoticeable for most artistic uses.
| If you need⦠| Tune |
|---|---|
| Higher FPS on weaker hardware | Increase Frameskip (1β3) |
| Fewer overlays (cleaner output) | Lower Detectionlimit (3β5) |
| Stricter detections (fewer false positives) | Raise Confidence (0.4β0.6) |
| All COCO classes detected | Leave Detectionlables empty |
Browser stuck / no detections coming through
- Pulse
Hardreconnect(Server page) β destroy + recreate the embedded Chromium on the same port.
Port conflict (rare β only if another local process grabbed the same port)
- Pulse
Findnewport(Server page) β picks a fresh free port and rebinds.
Detection labels look wrong or off-screen
- Verify input video is reaching
in1. The component falls back to bundled sample video if no input is connected.
Want to verify everything is running
- Inspect
reporttable β should populate within ~3 seconds of project load.
Not currently planned. Open an issue if interested.
The architecture pattern (browser-hosted ONNX inference, frames pushed over WebSocket from TD, JSON predictions returned and parsed by a datexecuteDAT) is inspired by Torin Blankensmith's yolo-touchdesigner project.
No source code from yolo-touchdesigner has been copied. The browser app, the TouchDesigner-side glue, the binary frame protocol, and the output schema were all written independently, with the official ONNX Runtime Web examples and the Ultralytics ONNX export docs as references.
This project is MIT licensed to make it easy to use in classrooms and share publicly. See tdyolo-web/LICENSE for the full text.
- Ultralytics for YOLOv11
- ONNX Runtime Web team for the in-browser inference runtime
- Derivative for TouchDesigner
- Torin Blankensmith for the architectural inspiration
MIT β Copyright (c) 2026 Patrick Hartono. See tdyolo-web/LICENSE for full text.