Plots bounding boxes on an image with marks attached to the edges of the boxes where no overlap with other boxes occurs. Args: image: The image to plot the bounding boxes on. bboxes: A 2D int array of shape (num_boxes, 4), where each row represents a bounding box: (y_top_left, x_
(
image: Image.Image,
bboxes, # (y, x, h, w)
mark_helper: MarkHelper,
linewidth=2,
alpha=0,
edgecolor=None,
fn_save=None,
normalized_to_pixel=True,
add_mark=True
)
| 174 | return best_corner |
| 175 | |
| 176 | def plot_boxes_with_marks( |
| 177 | image: Image.Image, |
| 178 | bboxes, # (y, x, h, w) |
| 179 | mark_helper: MarkHelper, |
| 180 | linewidth=2, |
| 181 | alpha=0, |
| 182 | edgecolor=None, |
| 183 | fn_save=None, |
| 184 | normalized_to_pixel=True, |
| 185 | add_mark=True |
| 186 | ) -> np.ndarray: |
| 187 | """Plots bounding boxes on an image with marks attached to the edges of the boxes where no overlap with other boxes occurs. |
| 188 | Args: |
| 189 | image: The image to plot the bounding boxes on. |
| 190 | bboxes: A 2D int array of shape (num_boxes, 4), where each row represents a bounding box: (y_top_left, x_top_left, box_height, box_width). If normalized_to_pixel is True, the values are float and are normalized with the image size. If normalized_to_pixel is False, the values are int and are in pixel. |
| 191 | """ |
| 192 | # Then modify the drawing code |
| 193 | draw = ImageDraw.Draw(image) |
| 194 | |
| 195 | # draw boxes on the image |
| 196 | image_width, image_height = image.size |
| 197 | |
| 198 | if normalized_to_pixel: |
| 199 | bboxes = [(int(y * image_height), int(x * image_width), int(h * image_height), int(w * image_width)) for y, x, h, w in bboxes] |
| 200 | |
| 201 | for box in bboxes: |
| 202 | y, x, h, w = box |
| 203 | draw.rectangle([x, y, x + w, y + h], outline=edgecolor, width=linewidth) |
| 204 | |
| 205 | # Draw the bounding boxes with index at the least overlapping corner |
| 206 | drawn_boxes = [] |
| 207 | for idx, bbox in enumerate(bboxes): |
| 208 | text = str(idx) |
| 209 | text_h, text_w = mark_helper.get_mark_size(text, image_height, image_width) |
| 210 | corner_y, corner_x = _find_least_overlapping_corner( |
| 211 | bbox, bboxes, drawn_boxes, (text_h, text_w), (image_height, image_width)) |
| 212 | |
| 213 | # Define the index box (y, x, y + h, x + w) |
| 214 | text_box = (corner_y, corner_x, text_h, text_w) |
| 215 | |
| 216 | if add_mark: |
| 217 | # Draw the filled index box and text |
| 218 | draw.rectangle([corner_x, corner_y, corner_x + text_w, corner_y + text_h], # (x, y, x + w, y + h) |
| 219 | fill="red") |
| 220 | font = mark_helper.get_font(image_height, image_width) |
| 221 | draw.text((corner_x, corner_y), text, fill='white', font=font) |
| 222 | |
| 223 | # Update the list of drawn boxes |
| 224 | drawn_boxes.append(np.array(text_box)) |
| 225 | |
| 226 | if fn_save is not None: # PIL image |
| 227 | image.save(fn_save) |
| 228 | return image |
| 229 | |
| 230 | def plot_circles_with_marks( |
| 231 | image: Image.Image, |
no test coverage detected