Skip to content

Commit

Permalink
Add text background color and transparency to visualizer
Browse files Browse the repository at this point in the history
  • Loading branch information
daniilpastukhov committed Jun 27, 2023
1 parent dc55a2f commit 7479b25
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 13 deletions.
8 changes: 5 additions & 3 deletions depthai_sdk/src/depthai_sdk/visualize/configs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dataclasses import dataclass, field
from enum import IntEnum
from typing import Tuple
from typing import Tuple, Optional
import numpy as np

try:
Expand Down Expand Up @@ -81,8 +81,10 @@ class TextConfig:
font_thickness: int = 2
font_position: TextPosition = TextPosition.TOP_LEFT

bg_transparency: float = 0.5
bg_color: Tuple[int, int, int] = (0, 0, 0)
background_color: Optional[Tuple[int, int, int]] = None
background_transparency: float = 0.5

outline_color: Tuple[int, int, int] = (0, 0, 0)

line_type: int = 16 # cv2.LINE_AA

Expand Down
50 changes: 44 additions & 6 deletions depthai_sdk/src/depthai_sdk/visualize/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,9 @@ def __init__(self,
detections: List[Union[ImgDetection, dai.Tracklet]],
normalizer: BoundingBox,
label_map: List[Tuple[str, Tuple]] = None,
label_color: Tuple[int, int, int] = None,
label_background_color: Tuple[int, int, int] = None,
label_background_transparency: float = None,
spatial_points: List[dai.Point3f] = None,
is_spatial=False,
parent_bbox: Union[np.ndarray, Tuple[int, int, int, int]] = None):
Expand All @@ -312,6 +315,9 @@ def __init__(self,
self.detections = detections
self.normalizer = normalizer
self.label_map = label_map
self.label_color = label_color
self.label_background_color = label_background_color
self.label_background_transparency = label_background_transparency
self.spatial_points = spatial_points
self.is_spatial = is_spatial
self.parent_bbox = parent_bbox
Expand All @@ -331,7 +337,10 @@ def serialize(self) -> dict:
'detections': [{
'bbox': bbox.to_tuple(frame_shape=self.frame_shape) if isinstance(bbox, BoundingBox) else bbox,
'label': label,
'color': color
'color': color,
'label_color': self.label_color,
'label_background_color': self.label_background_color,
'label_background_transparency': self.label_background_transparency
} for bbox, label, color in list(self.get_detections())]
}
if len(self._children) > 0:
Expand Down Expand Up @@ -385,12 +394,17 @@ def prepare(self) -> 'VisDetections':

# Add spatial coordinates
self.add_child(VisText(f'{spatial_coords.x}\n{spatial_coords.y}\n{spatial_coords.z}',
color=self.label_color or color,
bbox=normalized_bbox,
position=TextPosition.BOTTOM_RIGHT))
position=TextPosition.BOTTOM_RIGHT,
background_color=self.label_background_color,
background_transparency=self.label_background_transparency))

if cv2 and not detection_config.hide_label and len(label) > 0:
# Place label in the bounding box
self.add_child(VisText(text=label.capitalize(), bbox=normalized_bbox,
self.add_child(VisText(text=label.capitalize(),
color=self.label_color or color,
bbox=normalized_bbox,
position=detection_config.label_position,
padding=detection_config.label_padding))

Expand Down Expand Up @@ -438,6 +452,8 @@ def __init__(self,
color: Tuple[int, int, int] = None,
thickness: int = None,
outline: bool = True,
background_color: Tuple[int, int, int] = None,
background_transparency: float = 0.5,
bbox: Union[np.ndarray, Tuple[int, int, int, int], BoundingBox] = None,
position: TextPosition = TextPosition.TOP_LEFT,
padding: int = 10):
Expand All @@ -456,6 +472,8 @@ def __init__(self,
color: Text color.
thickness: Font thickness.
outline: Enable outline if set to True, disable otherwise.
background_color: Background color.
background_transparency: Background transparency.
bbox: Bounding box where to place text.
position: Position w.r.t. to frame (or bbox if is set).
padding: Padding.
Expand All @@ -467,6 +485,8 @@ def __init__(self,
self.color = color
self.thickness = thickness
self.outline = outline
self.background_color = background_color
self.background_transparency = background_transparency
self.bbox = bbox
self.position = position
self.padding = padding
Expand All @@ -479,6 +499,8 @@ def serialize(self):
'color': self.color,
'thickness': self.thickness,
'outline': self.outline,
'background_color': self.background_color,
'background_transparency': self.background_transparency
}

def prepare(self) -> 'VisText':
Expand All @@ -505,7 +527,6 @@ def draw(self, frame: np.ndarray) -> None:

# Extract shape of the bbox if exists
if self.bbox is not None:
# shape = self.bbox[2] - self.bbox[0], self.bbox[3] - self.bbox[1]
tl, br = self.bbox.denormalize(frame.shape)
shape = br[0] - tl[0], br[1] - tl[1]
else:
Expand All @@ -519,19 +540,36 @@ def draw(self, frame: np.ndarray) -> None:
font_thickness = max(1, int(font_scale * 2)) \
if text_config.auto_scale else self.thickness or text_config.font_thickness

dy = cv2.getTextSize(self.text, text_config.font_face, font_scale, font_thickness)[0][1] + 10
dx, dy = cv2.getTextSize(self.text, text_config.font_face, font_scale, font_thickness)[0]
dy += 10

for line in self.text.splitlines():
y = self.coords[1]

background_color = self.background_color or text_config.background_color
background_transparency = self.background_transparency or text_config.background_transparency
if background_color is not None:
img_with_background = cv2.rectangle(img=frame.copy(),
pt1=(self.coords[0], y - dy),
pt2=(self.coords[0] + dx, y + 10),
color=background_color,
thickness=-1)
# take transparency into account
cv2.addWeighted(src1=img_with_background,
alpha=background_transparency,
src2=frame,
beta=1 - background_transparency,
gamma=0,
dst=frame)

if self.outline:
# Background
cv2.putText(img=frame,
text=line,
org=self.coords,
fontFace=text_config.font_face,
fontScale=font_scale,
color=text_config.bg_color,
color=text_config.outline_color,
thickness=font_thickness + 1,
lineType=text_config.line_type)

Expand Down
27 changes: 23 additions & 4 deletions depthai_sdk/src/depthai_sdk/visualize/visualizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def add_bbox(self,
Args:
bbox: Bounding box.
label: Label for the detection.
thickness: Bounding box thickness.
color: Bounding box color (RGB).
bbox_style: Bounding box style (one of depthai_sdk.visualize.configs.BboxStyle).
Expand All @@ -90,6 +91,9 @@ def add_detections(self,
normalizer: BoundingBox = None,
label_map: List[Tuple[str, Tuple]] = None,
spatial_points: List[dai.Point3f] = None,
label_color: Tuple[int, int, int] = None,
label_background_color: Tuple[int, int, int] = None,
label_background_transparency: float = None,
is_spatial=False,
bbox: Union[np.ndarray, Tuple[int, int, int, int]] = None,
) -> 'Visualizer':
Expand All @@ -101,15 +105,22 @@ def add_detections(self,
normalizer: Normalizer object.
label_map: List of tuples (label, color).
spatial_points: List of spatial points. None if not spatial.
label_color: Color for the label.
label_background_color: Color for the label background.
label_background_transparency: Transparency for the label background.
is_spatial: Flag that indicates if the detections are spatial.
bbox: Bounding box, if there's a detection inside a bounding box.
Returns:
self
"""
detection_overlay = VisDetections(detections=detections,
normalizer=normalizer,
label_map=label_map,
spatial_points=spatial_points,
label_color=label_color,
label_background_color=label_background_color,
label_background_transparency=label_background_transparency,
is_spatial=is_spatial,
parent_bbox=bbox)
self.add_object(detection_overlay)
Expand All @@ -122,6 +133,8 @@ def add_text(self,
color: Tuple[int, int, int] = None,
thickness: int = None,
outline: bool = True,
background_color: Tuple[int, int, int] = None,
background_transparency: float = 0.5,
bbox: Union[np.ndarray, Tuple[int, ...], BoundingBox] = None,
position: TextPosition = TextPosition.TOP_LEFT,
padding: int = 10) -> 'Visualizer':
Expand All @@ -135,6 +148,8 @@ def add_text(self,
color: Color of the text.
thickness: Thickness of the text.
outline: Flag that indicates if the text should be outlined.
background_color: Background color.
background_transparency: Background transparency.
bbox: Bounding box.
position: Position.
padding: Padding.
Expand All @@ -148,6 +163,8 @@ def add_text(self,
color=color,
thickness=thickness,
outline=outline,
background_color=background_color,
background_transparency=background_transparency,
bbox=bbox,
position=position,
padding=padding)
Expand Down Expand Up @@ -368,8 +385,9 @@ def text(self,
font_scale: float = None,
font_thickness: int = None,
font_position: TextPosition = None,
bg_transparency: float = None,
bg_color: Tuple[int, int, int] = None,
background_transparency: float = None,
background_color: Tuple[int, int, int] = None,
outline_color: Tuple[int, int, int] = None,
line_type: int = None,
auto_scale: bool = None) -> 'Visualizer':
"""
Expand All @@ -382,8 +400,9 @@ def text(self,
font_scale: Font scale.
font_thickness: Font thickness.
font_position: Font position.
bg_transparency: Text background transparency.
bg_color: Text background color.
background_transparency: Text background transparency.
background_color: Text background color.
outline_color: Outline color.
line_type: Line type (from cv2).
auto_scale: Flag that indicates if the font scale should be automatically adjusted.
Expand Down

0 comments on commit 7479b25

Please sign in to comment.