Skip to content

Commit

Permalink
improved visualizations
Browse files Browse the repository at this point in the history
  • Loading branch information
kozlov721 committed Dec 4, 2024
1 parent 316dcc3 commit 1db7431
Showing 1 changed file with 85 additions and 20 deletions.
105 changes: 85 additions & 20 deletions luxonis_ml/data/utils/visualizations.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,77 @@
import colorsys
import hashlib
import math
from typing import Dict, List, Tuple

import cv2
import numpy as np

from luxonis_ml.data.utils import (
get_qualified_task_name,
get_task_name,
task_type_iterator,
)
from luxonis_ml.data.utils import get_task_name, task_type_iterator

from .types import Labels

font = cv2.FONT_HERSHEY_SIMPLEX

def _str_to_rgb(string: str) -> tuple:

def rgb_to_hsb(r: int, g: int, b: int) -> Tuple[float, float, float]:
h, s, br = colorsys.rgb_to_hsv(r / 255, g / 255, b / 255)
return h * 360, s, br

Check warning on line 18 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L17-L18

Added lines #L17 - L18 were not covered by tests


def hsb_to_rgb(h: float, s: float, b: float) -> Tuple[int, int, int]:
r, g, b = colorsys.hsv_to_rgb(h / 360, s, b)
return int(r * 255), int(g * 255), int(b * 255)

Check warning on line 23 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L22-L23

Added lines #L22 - L23 were not covered by tests


def get_contrast_color(r: int, g: int, b: int) -> Tuple[int, int, int]:
h, s, v = rgb_to_hsb(r, g, b)
h = (h + 180) % 360
return hsb_to_rgb(h, s, v)

Check warning on line 29 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L27-L29

Added lines #L27 - L29 were not covered by tests


def str_to_rgb(string: str) -> Tuple[int, int, int]:
h = int(hashlib.md5(string.encode()).hexdigest(), 16)
r = (h & 0xFF0000) >> 16
g = (h & 0x00FF00) >> 8
b = h & 0x0000FF

return (r, g, b)
return r, g, b

Check warning on line 38 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L38

Added line #L38 was not covered by tests


def draw_dashed_rectangle(
image: np.ndarray,
pt1: Tuple[int, int],
pt2: Tuple[int, int],
color: Tuple[int, int, int],
thickness: int = 1,
dash_length: int = 10,
):
x1, y1 = pt1
x2, y2 = pt2

Check warning on line 50 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L49-L50

Added lines #L49 - L50 were not covered by tests

def draw_dashed_line(p1, p2):
line_length = int(np.hypot(p2[0] - p1[0], p2[1] - p1[1]))
dashes = [

Check warning on line 54 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L52-L54

Added lines #L52 - L54 were not covered by tests
(i, i + dash_length)
for i in range(0, line_length, 2 * dash_length)
]
for start, end in dashes:
if end > line_length:
end = line_length
start_point = (

Check warning on line 61 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L58-L61

Added lines #L58 - L61 were not covered by tests
int(p1[0] + (p2[0] - p1[0]) * start / line_length),
int(p1[1] + (p2[1] - p1[1]) * start / line_length),
)
end_point = (

Check warning on line 65 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L65

Added line #L65 was not covered by tests
int(p1[0] + (p2[0] - p1[0]) * end / line_length),
int(p1[1] + (p2[1] - p1[1]) * end / line_length),
)
cv2.line(image, start_point, end_point, color, thickness)

Check warning on line 69 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L69

Added line #L69 was not covered by tests

draw_dashed_line((x1, y1), (x2, y1))
draw_dashed_line((x2, y1), (x2, y2))
draw_dashed_line((x2, y2), (x1, y2))
draw_dashed_line((x1, y2), (x1, y1))

Check warning on line 74 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L71-L74

Added lines #L71 - L74 were not covered by tests


def draw_cross(
Expand Down Expand Up @@ -160,15 +211,15 @@ class names.
for i, mask in enumerate(arr):
mask = cv2.resize(mask, (w, h), interpolation=cv2.INTER_NEAREST)
mask_viz[mask == 1] = (

Check warning on line 213 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L208-L213

Added lines #L208 - L213 were not covered by tests
_str_to_rgb(class_names[task_name][i])
str_to_rgb(class_names[task_name][i])
if (i != 0 or len(arr) == 1)
else (0, 0, 0)
)
binary_mask = (mask_viz > 0).astype(np.uint8)

Check warning on line 218 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L218

Added line #L218 was not covered by tests

blended = np.where(

Check warning on line 220 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L220

Added line #L220 was not covered by tests
binary_mask > 0,
cv2.addWeighted(image, 0.3, mask_viz, 0.7, 0),
cv2.addWeighted(image, 0.4, mask_viz, 0.6, 0),
image,
)
images[task_name] = blended

Check warning on line 225 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L225

Added line #L225 was not covered by tests
Expand All @@ -177,15 +228,28 @@ class names.
task_name = get_task_name(task)
curr_image = images.get(task_name, image.copy())

Check warning on line 229 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L227-L229

Added lines #L227 - L229 were not covered by tests

draw_function = cv2.rectangle

Check warning on line 231 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L231

Added line #L231 was not covered by tests

is_sublabel = len(task.split("/")) > 2

Check warning on line 233 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L233

Added line #L233 was not covered by tests

if is_sublabel:
draw_function = draw_dashed_rectangle

Check warning on line 236 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L235-L236

Added lines #L235 - L236 were not covered by tests

arr[:, [1, 3]] *= w
arr[:, [2, 4]] *= h
arr[:, 3] = arr[:, 1] + arr[:, 3]
arr[:, 4] = arr[:, 2] + arr[:, 4]
arr = arr.astype(int)

Check warning on line 242 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L238-L242

Added lines #L238 - L242 were not covered by tests

for box in arr:
cv2.rectangle(
color = get_contrast_color(

Check warning on line 245 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L245

Added line #L245 was not covered by tests
*str_to_rgb(class_names[task_name][int(box[0])])
)
draw_function(

Check warning on line 248 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L248

Added line #L248 was not covered by tests
curr_image,
(int(box[1] * w), int(box[2] * h)),
(int(box[1] * w + box[3] * w), int(box[2] * h + box[4] * h)),
_str_to_rgb(
get_qualified_task_name(task)
+ class_names[task_name][int(box[0])]
),
(box[1], box[2]),
(box[3], box[4]),
color,
2,
)
images[task_name] = curr_image

Check warning on line 255 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L255

Added line #L255 was not covered by tests
Expand All @@ -199,21 +263,22 @@ class names.
for kp in arr:
cls_ = int(kp[0])
kp = kp[1:].reshape(-1, 3)
color = get_contrast_color(*str_to_rgb(task_classes[cls_]))

Check warning on line 266 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L266

Added line #L266 was not covered by tests
for k in kp:
if k[-1] == 2:
cv2.circle(

Check warning on line 269 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L268-L269

Added lines #L268 - L269 were not covered by tests
curr_image,
(int(k[0] * w), int(k[1] * h)),
2,
_str_to_rgb(task_classes[cls_]),
2,
radius=2,
color=color,
thickness=2,
)
else:
draw_cross(

Check warning on line 277 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L277

Added line #L277 was not covered by tests
curr_image,
(int(k[0] * w), int(k[1] * h)),
size=5,
color=_str_to_rgb(task_classes[cls_]),
color=color,
thickness=2,
)
images[task_name] = curr_image

Check warning on line 284 in luxonis_ml/data/utils/visualizations.py

View check run for this annotation

Codecov / codecov/patch

luxonis_ml/data/utils/visualizations.py#L284

Added line #L284 was not covered by tests
Expand Down

0 comments on commit 1db7431

Please sign in to comment.