detrflow / inference /visualizer.py
umutonuryasar's picture
Complete pipeline — inference, FastAPI, Gradio demo, training scripts
1d1c820
Raw
History Blame Contribute Delete
2.02 kB
from __future__ import annotations
import random
from PIL import Image, ImageDraw, ImageFont
def _get_color(label: str) -> tuple[int, int, int]:
rng = random.Random(hash(label) & 0xFFFFFFFF)
h = rng.random()
# HSV → RGB with S=0.7, V=0.9
import colorsys
r, g, b = colorsys.hsv_to_rgb(h, 0.70, 0.90)
return int(r * 255), int(g * 255), int(b * 255)
def _load_font(size: int = 14) -> ImageFont.ImageFont:
for path in [
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
"/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf",
]:
try:
return ImageFont.truetype(path, size)
except OSError:
continue
return ImageFont.load_default()
def draw_detections(
image: Image.Image,
detections: list[dict],
line_width: int = 2,
font_size: int = 14,
) -> Image.Image:
"""Overlay bounding boxes, labels, and confidence scores on *image*.
*detections* is the list returned by RTDetrPredictor.predict().
Returns a new RGB image (original is not mutated).
"""
out = image.convert("RGB").copy()
draw = ImageDraw.Draw(out, "RGBA")
font = _load_font(font_size)
for det in detections:
label: str = det["label"]
score: float = det["score"]
box = det["box"]
x1, y1, x2, y2 = box["x1"], box["y1"], box["x2"], box["y2"]
color = _get_color(label)
fill_rgba = (*color, 40) # translucent fill
draw.rectangle([x1, y1, x2, y2], outline=color, fill=fill_rgba, width=line_width)
text = f"{label} {score:.2f}"
bbox = draw.textbbox((x1, y1), text, font=font)
text_w = bbox[2] - bbox[0]
text_h = bbox[3] - bbox[1]
# Background pill behind text
pad = 3
draw.rectangle(
[x1, y1 - text_h - pad * 2, x1 + text_w + pad * 2, y1],
fill=(*color, 220),
)
draw.text((x1 + pad, y1 - text_h - pad), text, fill=(255, 255, 255), font=font)
return out