Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/dino-tracking/backend/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
depthai==3.7.1
depthai-nodes==0.5.0
depthai==3.8.0
depthai-nodes==0.6.0
opencv-python-headless~=4.10.0
python-dotenv
python-box
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import cv2
import depthai as dai
import numpy as np
from depthai_nodes.message import SegmentationMask
from depthai_nodes.node.base_host_node import BaseHostNode


Expand Down Expand Up @@ -31,12 +30,8 @@ def process(self, frame_msg: dai.ImgFrame, segmentation: dai.Buffer):
self.out.send(frame_msg)
return

assert isinstance(segmentation, SegmentationMask)
mask = getattr(segmentation, "mask", None)

if mask is None:
self.out.send(frame_msg)
return
assert isinstance(segmentation, dai.SegmentationMask)
mask = segmentation.getCvMask()

frame = frame_msg.getCvFrame()
H, W = frame.shape[:2]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import depthai as dai
import numpy as np
from depthai_nodes.message import SegmentationMask
from depthai_nodes.node import BaseHostNode


Expand Down Expand Up @@ -31,10 +30,8 @@ def clear_selection(self) -> None:
self._pending_click = None
self._selected_mask = None

def process(self, segmentation: dai.Buffer):
assert isinstance(segmentation, SegmentationMask)

segmentation_mask = segmentation.mask.astype(np.int32)
def process(self, segmentation: dai.SegmentationMask):
segmentation_mask = segmentation.getCvMask().astype(np.int32)

if self._pending_click:
segment_id = self._map_click_to_segment(
Expand Down Expand Up @@ -78,10 +75,17 @@ def _map_click_to_segment(
if patch.size == 0:
return None

values, counts = np.unique(patch, return_counts=True)
# Native dai.SegmentationMask uses 255 as background/unassigned.
# Do not select the background as an object, while keeping class/instance
# id 0 valid.
foreground_patch = patch[patch != 255]
if foreground_patch.size == 0:
return None

values, counts = np.unique(foreground_patch, return_counts=True)
return int(values[np.argmax(counts)])

def _send_mask(self, segmentation: SegmentationMask, mask: np.ndarray):
def _send_mask(self, segmentation: dai.SegmentationMask, mask: np.ndarray):
mask_u8 = mask.astype(np.uint8) * 255

out = dai.ImgFrame()
Expand Down
2 changes: 1 addition & 1 deletion neural-networks/generic-example/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Reusable single-model inference scaffold. It runs one Model Zoo model with one i
## Validation

- `Run:` `python3 main.py`
- `Alternative run:` `python3 main.py --model luxonis/mediapipe-selfie-segmentation:256x144 --overlay_mode`
- `Alternative run:` `python3 main.py --model luxonis/mediapipe-selfie-segmentation:256x144`
- `Archive run:` `python3 main.py --model /path/to/custom-model.tar.xz`
- `Success looks like:` Visualizer exposes `Video` and `Detections`, and the pipeline runs until `q` is pressed
- `Common failure meaning:` model identifier unavailable for platform, private model auth missing, or selected model violates the single-input/single-output assumptions
16 changes: 11 additions & 5 deletions neural-networks/generic-example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Here is a list of all available parameters:
-api API_KEY, --api_key API_KEY
HubAI API key for private HubAI access. Can also use 'DEPTHAI_HUB_API_KEY' environment variable instead. (default: )
-overlay OVERLAY_MODE, --overlay_mode
If passed, overlays model output on the input image when the output is an array (e.g., depth maps, segmentation maps). Otherwise, displays outputs separately.
If passed, overlays model output on the input image when the output is an array (e.g., depth maps). Otherwise, displays outputs separately.
```

## Peripheral Mode
Expand Down Expand Up @@ -53,20 +53,26 @@ This will run a simple YOLOv6 object detection model (`luxonis/yolov6-nano:r2-co

```bash
python3 main.py \
--model luxonis/mediapipe-selfie-segmentation:256x144 \
--overlay_mode
--model luxonis/mediapipe-selfie-segmentation:256x144
```

This will run a selfie segmentation model.

```bash
python3 main.py \
--model luxonis/yolov8-instance-segmentation-nano:coco-512x288 \
--overlay_mode
--model luxonis/yolov8-instance-segmentation-nano:coco-512x288
Comment thread
rolandocortez marked this conversation as resolved.
```

And this will run an instance segmentation model.

```bash
python3 main.py \
--model luxonis/midas-v2-1:small-512x288 \
--overlay_mode
```

This will run a MiDaS depth estimation model and overlay the depth map on the input image.

```bash
python3 main.py \
--model /path/to/custom-model.tar.xz
Expand Down
4 changes: 2 additions & 2 deletions neural-networks/generic-example/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
depthai==3.7.1
depthai-nodes==0.5.0
depthai==3.8.0
depthai-nodes==0.6.0
opencv-python-headless~=4.10.0
numpy>=1.22
python-dotenv
2 changes: 1 addition & 1 deletion neural-networks/generic-example/utils/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def initialize_argparser():
parser.add_argument(
"-overlay",
"--overlay_mode",
help="If passed, overlays model output on the input image when the output is an array (e.g., depth maps, segmentation maps). Otherwise, displays outputs separately.",
help="If passed, overlays model output on the input image when the output is an array (e.g., depth maps). Otherwise, displays outputs separately.",
required=False,
action="store_true",
)
Expand Down
9 changes: 4 additions & 5 deletions neural-networks/object-detection/yolo-p/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,24 @@ This is the repository reference for ADAS-style YOLO-P output: detections plus r
- `Runs on:` RVC2 peripheral, RVC4 peripheral, and RVC4 standalone packaging
- `Requires:` YOLO-P model and input resized to model dimensions
- `Input:` camera frames by default or `ReplayVideo` via `--media_path`
- `Output:` `Road Segmentation` and `Detections`
- `Output:` `Video`, `Detections`, `Road Segmentation`, and `Lane Segmentation`
- `Models:` YOLO-P YAMLs in [depthai_models/](depthai_models/)
- `Visualizer / UI:` DepthAI Visualizer via `dai.RemoteConnection`

## Read First

- [README.md](README.md)
- [main.py](main.py)
- [utils/annotation_node.py](utils/annotation_node.py)
- [utils/arguments.py](utils/arguments.py)

## Architecture

- `ParsingNeuralNetwork` runs the YOLO-P multi-head model on camera or replay input.
- [utils/annotation_node.py](utils/annotation_node.py) consumes three outputs:
- [main.py](main.py) sends the model outputs to Visualizer topics:
- detections
- road segmentation
- lane segmentation
- The Visualizer exposes the segmentation composite and detection overlay separately.
- The Visualizer renders the input video, detections, road segmentation, and lane segmentation topics.

## Constraints

Expand All @@ -62,5 +61,5 @@ This is the repository reference for ADAS-style YOLO-P output: detections plus r
## Validation

- `Run:` `python3 main.py`
- `Success looks like:` the Visualizer shows `Road Segmentation` and `Detections`, with lane/road overlays and detected vehicles
- `Success looks like:` the Visualizer shows `Video`, `Detections`, `Road Segmentation`, and `Lane Segmentation`, with road/lane segmentation and detected vehicles
- `Common failure meaning:` the model output ordering changed, the replay input was resized incorrectly, or the operator expected a generic single-output detector
17 changes: 4 additions & 13 deletions neural-networks/object-detection/yolo-p/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from depthai_nodes.node import ParsingNeuralNetwork

from utils.arguments import initialize_argparser
from utils.annotation_node import AnnotationNode

_, args = initialize_argparser()

Expand Down Expand Up @@ -54,19 +53,11 @@
input_node_out, nn_archive
)

# annotation
annotation_node = pipeline.create(AnnotationNode).build(
frame=input_node_out,
detections=nn.getOutput(0),
road_segmentations=nn.getOutput(1),
lane_segmentations=nn.getOutput(2),
)

# visualization
visualizer.addTopic(
"Road Segmentation", annotation_node.out_segmentations, "images"
)
visualizer.addTopic("Detections", annotation_node.out_detections, "images")
visualizer.addTopic("Video", nn.passthrough, "images")
visualizer.addTopic("Detections", nn.getOutput(0), "images")
visualizer.addTopic("Road Segmentation", nn.getOutput(1), "images")
visualizer.addTopic("Lane Segmentation", nn.getOutput(2), "images")

print("Pipeline created.")

Expand Down
4 changes: 2 additions & 2 deletions neural-networks/object-detection/yolo-p/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
depthai==3.7.1
depthai-nodes==0.5.0
depthai==3.8.0
depthai-nodes==0.6.0
opencv-python-headless~=4.10.0
numpy>=1.22
79 changes: 0 additions & 79 deletions neural-networks/object-detection/yolo-p/utils/annotation_node.py

This file was deleted.

1 change: 1 addition & 0 deletions neural-networks/segmentation/blur-background/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
seg_nn: ParsingNeuralNetwork = pipeline.create(ParsingNeuralNetwork).build(
input_node, seg_model_description, fps=args.fps_limit
)
seg_nn.getParser(dai.node.SegmentationParser).setBackgroundClass(False)

blur_background = pipeline.create(BlurBackground).build(
seg_nn.passthrough, seg_nn.out
Expand Down
4 changes: 2 additions & 2 deletions neural-networks/segmentation/blur-background/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
depthai==3.7.1
depthai-nodes==0.5.0
depthai==3.8.0
depthai-nodes==0.6.0
opencv-python-headless~=4.10.0
numpy>=1.22
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import cv2
import depthai as dai
from depthai_nodes.message import SegmentationMask


class BlurBackground(dai.node.HostNode):
Expand Down Expand Up @@ -34,12 +33,11 @@ def process(
"""Blurs the background of the input frame based on the segmentation mask."""

assert isinstance(frame_msg, dai.ImgFrame)
assert isinstance(mask_msg, SegmentationMask)
assert isinstance(mask_msg, dai.SegmentationMask)

frame = frame_msg.getCvFrame()
person_mask = (
mask_msg.mask == 15
) # person is class 15 in the output of the model
mask = mask_msg.getCvMask()
person_mask = mask == 15 # person is class 15 in the output of the model

bg = frame.copy()
blurred_bg = cv2.blur(bg, (10, 10))
Expand Down
1 change: 1 addition & 0 deletions neural-networks/segmentation/depth-crop/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
nn = pipeline.create(ParsingNeuralNetwork).build(
nnSource=nn_archive, input=manip.out
)
nn.getParser(dai.node.SegmentationParser).setBackgroundClass(False)

# annotation
annotation_node = pipeline.create(AnnotationNode).build(
Expand Down
4 changes: 2 additions & 2 deletions neural-networks/segmentation/depth-crop/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
depthai==3.7.1
depthai-nodes==0.5.0
depthai==3.8.0
depthai-nodes==0.6.0
12 changes: 8 additions & 4 deletions neural-networks/segmentation/depth-crop/utils/annotation_node.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import cv2
import depthai as dai
import numpy as np
from depthai_nodes import SegmentationMask, PRIMARY_COLOR
from depthai_nodes import PRIMARY_COLOR

# Custom colormap with 0 mapped to black - better disparity visualization
JET_CUSTOM = cv2.applyColorMap(np.arange(256, dtype=np.uint8), cv2.COLORMAP_JET)
Expand Down Expand Up @@ -46,10 +46,14 @@ def process(
) -> None:
frame = preview.getCvFrame()

assert isinstance(mask, SegmentationMask)
assert isinstance(mask, dai.SegmentationMask)

mask_data = mask.mask
mask_data = cv2.resize(mask_data, (frame.shape[1], frame.shape[0]))
mask_data = mask.getCvMask()
mask_data = cv2.resize(
mask_data,
(frame.shape[1], frame.shape[0]),
interpolation=cv2.INTER_NEAREST,
)

mask = np.zeros_like(frame)
color = [
Expand Down
Loading