document-similarity-matching-using-visual-layout-features-archive
/
utils
/visualize_bboxes_on_image.py
| # 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 | |
| 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 |