-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
770 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,12 @@ | ||
from .img_detections import ImgDetectionWithKeypoints, ImgDetectionsWithKeypoints | ||
from .keypoints import HandKeypoints, Keypoints | ||
from .lines import Line, Lines | ||
|
||
__all__ = [ | ||
"ImgDetectionWithKeypoints", | ||
"ImgDetectionsWithKeypoints", | ||
"HandKeypoints", | ||
"Keypoints", | ||
"Line", | ||
"Lines", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import numpy as np | ||
import depthai as dai | ||
|
||
def create_feature_point(x: float, y: float, id: int, age: int) -> dai.TrackedFeature: | ||
""" | ||
Create a tracked feature point. | ||
Args: | ||
x (float): X coordinate of the feature point. | ||
y (float): Y coordinate of the feature point. | ||
id (int): ID of the feature point. | ||
age (int): Age of the feature point. | ||
Returns: | ||
dai.TrackedFeature: Tracked feature point. | ||
""" | ||
|
||
feature = dai.TrackedFeature() | ||
feature.position.x = x | ||
feature.position.y = y | ||
feature.id = id | ||
feature.age = age | ||
|
||
return feature | ||
|
||
def create_tracked_features_message(reference_points: np.ndarray, target_points: np.ndarray) -> dai.TrackedFeatures: | ||
""" | ||
Create a message for the tracked features. | ||
Args: | ||
reference_points (np.ndarray): Reference points of shape (N,2) meaning [...,[x, y],...]. | ||
target_points (np.ndarray): Target points of shape (N,2) meaning [...,[x, y],...]. | ||
Returns: | ||
dai.TrackedFeatures: Message containing the tracked features. | ||
""" | ||
|
||
|
||
if not isinstance(reference_points, np.ndarray): | ||
raise ValueError(f"reference_points should be numpy array, got {type(reference_points)}.") | ||
if len(reference_points.shape) != 2: | ||
raise ValueError(f"reference_points should be of shape (N,2) meaning [...,[x, y],...], got {reference_points.shape}.") | ||
if reference_points.shape[1] != 2: | ||
raise ValueError(f"reference_points 2nd dimension should be of size 2 e.g. [x, y], got {reference_points.shape[1]}.") | ||
if not isinstance(target_points, np.ndarray): | ||
raise ValueError(f"target_points should be numpy array, got {type(target_points)}.") | ||
if len(target_points.shape) != 2: | ||
raise ValueError(f"target_points should be of shape (N,2) meaning [...,[x, y],...], got {target_points.shape}.") | ||
if target_points.shape[1] != 2: | ||
raise ValueError(f"target_points 2nd dimension should be of size 2 e.g. [x, y], got {target_points.shape[1]}.") | ||
|
||
features = [] | ||
|
||
for i in range(reference_points.shape[0]): | ||
reference_feature = create_feature_point(reference_points[i][0], reference_points[i][1], i, 0) | ||
target_feature = create_feature_point(target_points[i][0], target_points[i][1], i, 1) | ||
features.append(reference_feature) | ||
features.append(target_feature) | ||
|
||
features_msg = dai.TrackedFeatures() | ||
features_msg.trackedFeatures = features | ||
|
||
return features_msg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import depthai as dai | ||
from typing import List | ||
|
||
class Line(dai.Buffer): | ||
def __init__(self): | ||
super().__init__() | ||
self._start_point: dai.Point2f = None | ||
self._end_point: dai.Point2f = None | ||
self._confidence: float = None | ||
|
||
@property | ||
def start_point(self) -> dai.Point2f: | ||
return self._start_point | ||
|
||
@start_point.setter | ||
def start_point(self, value: dai.Point2f): | ||
if not isinstance(value, dai.Point2f): | ||
raise TypeError(f"start_point must be of type Point2f, instead got {type(value)}.") | ||
self._start_point = value | ||
|
||
@property | ||
def end_point(self) -> dai.Point2f: | ||
return self._end_point | ||
|
||
@end_point.setter | ||
def end_point(self, value: dai.Point2f): | ||
if not isinstance(value, dai.Point2f): | ||
raise TypeError(f"end_point must be of type Point2f, instead got {type(value)}.") | ||
self._end_point = value | ||
|
||
@property | ||
def confidence(self) -> float: | ||
return self._confidence | ||
|
||
@confidence.setter | ||
def confidence(self, value: float): | ||
if not isinstance(value, float): | ||
raise TypeError(f"confidence must be of type float, instead got {type(value)}.") | ||
self._confidence = value | ||
|
||
|
||
class Lines(dai.Buffer): | ||
def __init__(self): | ||
super().__init__() | ||
self._lines: List[Line] = [] | ||
|
||
@property | ||
def lines(self) -> List[Line]: | ||
return self._lines | ||
|
||
@lines.setter | ||
def lines(self, value: List[Line]): | ||
if not isinstance(value, List): | ||
raise TypeError(f"lines must be of type List[Line], instead got {type(value)}.") | ||
for line in value: | ||
if not isinstance(line, Line): | ||
raise TypeError(f"lines must be of type List[Line], instead got {type(value)}.") | ||
self._lines = value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import depthai as dai | ||
import numpy as np | ||
|
||
from ..messages.creators import create_keypoints_message | ||
|
||
class KeypointParser(dai.node.ThreadedHostNode): | ||
def __init__( | ||
self, | ||
scale_factor=1, | ||
num_keypoints=None, | ||
): | ||
dai.node.ThreadedHostNode.__init__(self) | ||
self.input = dai.Node.Input(self) | ||
self.out = dai.Node.Output(self) | ||
|
||
self.scale_factor = scale_factor | ||
self.num_keypoints = num_keypoints | ||
|
||
def setScaleFactor(self, scale_factor): | ||
self.scale_factor = scale_factor | ||
|
||
def setNumKeypoints(self, num_keypoints): | ||
self.num_keypoints = num_keypoints | ||
|
||
def run(self): | ||
""" | ||
Postprocessing logic for Keypoint model. | ||
Returns: | ||
dai.Keypoints: num_keypoints keypoints (2D or 3D). | ||
""" | ||
|
||
if self.num_keypoints is None: | ||
raise ValueError("Number of keypoints must be specified!") | ||
|
||
while self.isRunning(): | ||
|
||
try: | ||
output: dai.NNData = self.input.get() | ||
except dai.MessageQueue.QueueException as e: | ||
break # Pipeline was stopped | ||
|
||
output_layer_names = output.getAllLayerNames() | ||
|
||
if len(output_layer_names) != 1: | ||
raise ValueError(f"Expected 1 output layer, got {len(output_layer_names)}.") | ||
|
||
keypoints = output.getTensor(output_layer_names[0]) | ||
num_coords = int(np.prod(keypoints.shape) / self.num_keypoints) | ||
|
||
if num_coords not in [2, 3]: | ||
raise ValueError(f"Expected 2 or 3 coordinates per keypoint, got {num_coords}.") | ||
|
||
keypoints = keypoints.reshape(self.num_keypoints, num_coords) | ||
|
||
keypoints /= self.scale_factor | ||
|
||
msg = create_keypoints_message(keypoints) | ||
|
||
self.out.send(msg) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.