Charles Kabui commited on
Commit
e18f153
·
1 Parent(s): daba8b1

visualize_bboxes_on_image

Browse files
utils/remove_duplicates.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def remove_duplicates(items: list, key=lambda x: x, show_process=False):
2
+ '''
3
+ Remove duplicates from a list of items
4
+ Args:
5
+ items: List of items
6
+ key: Function to get the key of the item
7
+ show_process: Whether to show the process or not
8
+ Returns:
9
+ List: List of items without duplicates
10
+ '''
11
+ progress = lambda x, *, desc: x
12
+ if show_process:
13
+ import tqdm
14
+ progress = tqdm.tqdm
15
+ return list({key(item): item for item in progress(items, desc='Deduping...')}.values())
utils/show_tile_images.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from utils.fig2img import fig2img
2
+ import matplotlib.pyplot as plt
3
+ import numpy as np
4
+ from PIL import Image
5
+ from typing import List
6
+
7
+ def show_tile_images(
8
+ images: List[np.ndarray | Image.Image],
9
+ width_parts: int,
10
+ figsize = None,
11
+ space = 0.0,
12
+ pad = False,
13
+ figcolor = 'white',
14
+ titles: List[str] = None,
15
+ title_color: str = None,
16
+ title_background_color: str = None,
17
+ title_font_size: int = None):
18
+ '''
19
+ Show images in a tile format
20
+ Args:
21
+ images: List of images to show
22
+ width_parts: Number of images to show in a row
23
+ figsize: Size of the figure
24
+ space: Space between images
25
+ pad: Whether to pad the images or not
26
+ figcolor: Background color of the figure
27
+ titles: Titles of the images
28
+ title_color: Color of the title
29
+ title_background_color: Background color of the title
30
+ title_font_size: Font size of the title
31
+ Returns:
32
+ Image: Image of the figure
33
+ '''
34
+ height = int(np.ceil(len(images) / width_parts))
35
+ fig, axs = plt.subplots(height, width_parts, figsize=figsize if figsize != None else (8 * 2, 12 * height))
36
+ fig.patch.set_facecolor(figcolor)
37
+ axes = axs.flatten() if isinstance(axs, np.ndarray) else [axs]
38
+ titles = (titles or []) + np.full(len(images) - len(titles or []), None).tolist()
39
+ for img, ax, title in zip(images, axes, titles):
40
+ if title:
41
+ params = {k: v for k, v in { 'color': title_color, 'backgroundcolor': title_background_color, 'fontsize': title_font_size }.items() if v is not None}
42
+ ax.set_title(title, **params)
43
+ ax.imshow(img.convert("RGB") if not isinstance(img, np.ndarray) else img)
44
+ ax.axis('off')
45
+ if pad:
46
+ fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=space, hspace=space)
47
+ fig.tight_layout(h_pad=space, w_pad = space, pad = space)
48
+ else:
49
+ fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=space, hspace=space)
50
+ fig.tight_layout(h_pad=space, w_pad = space, pad = 0)
51
+ plt.margins()
52
+ plt.close()
53
+ return fig2img(fig)
utils/visualize_bboxes_on_image.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is used to visualize bounding boxes on an image
2
+ from urllib.parse import urlparse
3
+ from PIL import Image, ImageDraw, ImageFont
4
+ import numpy as np
5
+ import requests
6
+ from typing import List
7
+ from functools import cache
8
+
9
+ @cache
10
+ def get_font(path_or_url: str = 'https://github.com/googlefonts/roboto/raw/main/src/hinted/Roboto-Regular.ttf', size: int = 10):
11
+ if urlparse(path_or_url).scheme in ["http", "https"]: # Online
12
+ return ImageFont.truetype(requests.get(path_or_url, stream=True).raw, size=size)
13
+ else: # Local
14
+ return ImageFont.truetype(path_or_url, size=size)
15
+
16
+ def visualize_bboxes_on_image(
17
+ image: Image.Image,
18
+ bboxes: List[List[int]],
19
+ titles: List[str] = None,
20
+ width = 2,
21
+ bbox_color="red",
22
+ label_text_color="black",
23
+ label_rectangle_color="red",
24
+ convert_to_x0y0x1y1 = None,
25
+ label_text_padding = 2,
26
+ label_rectangle_left_padding=10,
27
+ label_rectangle_top_padding=10,
28
+ label_text_size = 10) -> Image.Image:
29
+ '''
30
+ Visualize bounding boxes on an image
31
+ Args:
32
+ image: Image to visualize
33
+ bboxes: List of bounding boxes
34
+ titles: Titles of the bounding boxes
35
+ width: Width of the bounding box
36
+ bbox_color: Color of the bounding box
37
+ label_text_color: Color of the label text
38
+ label_rectangle_color: Color of the label rectangle
39
+ convert_to_x0y0x1y1: Function to convert bounding box to x0y0x1y1 format
40
+ label_text_padding: Padding of the label text
41
+ label_rectangle_left_padding: Left padding of the label rectangle
42
+ label_rectangle_top_padding: Top padding of the label rectangle
43
+ label_text_size: Font size of the label text
44
+ Returns:
45
+ Image: Image with bounding boxes'''
46
+ image = image.copy().convert("RGB")
47
+ draw = ImageDraw.Draw(image)
48
+ font = get_font(size = label_text_size)
49
+ titles = (titles or []) + np.full(len(bboxes) - len(titles or []), None).tolist()
50
+ for bbox, title in zip(bboxes, titles):
51
+ x0, y0, x1, y1 = convert_to_x0y0x1y1(bbox) if convert_to_x0y0x1y1 is not None else bbox
52
+ draw.rectangle([x0, y0, x1, y1], outline=bbox_color, width=width)
53
+ if title is not None:
54
+ title = title + " " + str(bbox)
55
+ text_position = (x0 + label_rectangle_left_padding, y0 - label_rectangle_top_padding)
56
+ text_bbox_left, text_bbox_top, text_bbox_right, text_bbox_bottom = draw.textbbox(text_position, title, font=font)
57
+ draw.rectangle(
58
+ (
59
+ text_bbox_left - label_text_padding,
60
+ text_bbox_top - label_text_padding,
61
+ text_bbox_right + label_text_padding,
62
+ text_bbox_bottom + label_text_padding
63
+ ),
64
+ fill=label_rectangle_color)
65
+ draw.text(text_position, title, font=font, fill=label_text_color)
66
+ return image