# This file is used to visualize bounding boxes on an image from urllib.parse import urlparse from PIL import Image, ImageDraw, ImageFont import numpy as np import requests from typing import List from functools import cache @cache def get_font(path_or_url: str = 'https://github.com/googlefonts/roboto/raw/main/src/hinted/Roboto-Regular.ttf', size: int = 10): if urlparse(path_or_url).scheme in ["http", "https"]: # Online return ImageFont.truetype(requests.get(path_or_url, stream=True).raw, size=size) else: # Local return ImageFont.truetype(path_or_url, size=size) def visualize_bboxes_on_image( image: Image.Image, bboxes: List[List[int]], titles: List[str] = None, width = 2, bbox_color="red", label_text_color="black", label_rectangle_color="red", convert_to_x0y0x1y1 = None, label_text_padding = 2, label_rectangle_left_padding=10, label_rectangle_top_padding=10, label_text_size = 10) -> Image.Image: ''' Visualize bounding boxes on an image Args: image: Image to visualize bboxes: List of bounding boxes titles: Titles of the bounding boxes width: Width of the bounding box bbox_color: Color of the bounding box label_text_color: Color of the label text label_rectangle_color: Color of the label rectangle convert_to_x0y0x1y1: Function to convert bounding box to x0y0x1y1 format label_text_padding: Padding of the label text label_rectangle_left_padding: Left padding of the label rectangle label_rectangle_top_padding: Top padding of the label rectangle label_text_size: Font size of the label text Returns: Image: Image with bounding boxes''' image = image.copy().convert("RGB") draw = ImageDraw.Draw(image) font = get_font(size = label_text_size) titles = (titles or []) + np.full(len(bboxes) - len(titles or []), None).tolist() for bbox, title in zip(bboxes, titles): x0, y0, x1, y1 = convert_to_x0y0x1y1(bbox) if convert_to_x0y0x1y1 is not None else bbox draw.rectangle([x0, y0, x1, y1], outline=bbox_color, width=width) if title is not None: text_position = (x0 + label_rectangle_left_padding, y0 - label_rectangle_top_padding) text_bbox_left, text_bbox_top, text_bbox_right, text_bbox_bottom = draw.textbbox(text_position, title, font=font) draw.rectangle( ( text_bbox_left - label_text_padding, text_bbox_top - label_text_padding, text_bbox_right + label_text_padding, text_bbox_bottom + label_text_padding ), fill=label_rectangle_color) draw.text(text_position, title, font=font, fill=label_text_color) return image