| from PIL import Image, ImageColor |
|
|
| |
| import numpy as np |
|
|
| |
| |
|
|
|
|
| def mask_to_xyxy(mask: np.ndarray, verbose: bool = False) -> tuple: |
| """Convert a binary mask of shape (h, w) to |
| xyxy bounding box format (top-left and bottom-right coordinates). |
| """ |
| ys, xs = np.where(mask) |
| if len(xs) == 0 or len(ys) == 0: |
| if verbose: |
| logger.warning("mask_to_xyxy: No object found in the mask") |
| return None |
| x_min = np.min(xs) |
| y_min = np.min(ys) |
| x_max = np.max(xs) |
| y_max = np.max(ys) |
| xyxy = (x_min, y_min, x_max, y_max) |
| xyxy = tuple([int(i) for i in xyxy]) |
| return xyxy |
|
|
|
|
| def annotate_detections( |
| im: Image.Image, |
| l_obj: list, |
| color_key: str = "class", |
| bbox_width: int = 1, |
| label_key: str = "object_id", |
| color_dict: dict = {}, |
| ): |
| |
| color_list = list( |
| mcolors.XKCD_COLORS.items() |
| ) |
| unique_color_keys = list( |
| set([o[color_key] for o in l_obj if color_key in o.keys()]) |
| ) |
|
|
| for obj in l_obj: |
| color_index = unique_color_keys.index(obj[color_key]) |
| bbox_color = ( |
| color_dict[obj[color_key]] if color_dict else color_list[color_index][1] |
| ) |
| im = ( |
| im_draw_bbox( |
| im, |
| color=bbox_color, |
| width=bbox_width, |
| caption=(str(obj[label_key]) if label_key else None), |
| **obj["boundingBox"], |
| use_bbv=True, |
| ) |
| if "boundingBox" in obj.keys() |
| else im_draw_point( |
| im, |
| **obj["point"], |
| width=bbox_width, |
| caption=(str(obj[label_key]) if label_key else None), |
| color=bbox_color, |
| ) |
| ) |
| return im |
|
|
|
|
| def annotate_masks( |
| im: Image.Image, masks: list, mask_alpha: float = 0.9, bbox_width: int = 3 |
| ) -> Image.Image: |
| """returns an annotated pillow image""" |
| masks = [ |
| b64_mask_decode(m).astype(np.uint8) if isinstance(m, str) else m for m in masks |
| ] |
| segs = [] |
| for i, m in enumerate(masks): |
| x0, y0, x1, y1 = mask_to_xyxy(m) |
| segs.append( |
| { |
| "object_id": i, |
| "boundingBox": {"x0": x0, "y0": y0, "x1": x1, "y1": y1}, |
| } |
| ) |
| ann_im = np.array(im) |
| for i, m in enumerate(masks): |
| m_color = list(mcolors.XKCD_COLORS.items())[i] |
| ann_im = im_color_mask( |
| ann_im, |
| mask_array=m, |
| alpha=mask_alpha, |
| rbg_tup=ImageColor.getrgb(m_color[1]), |
| ) |
| ann_im = annotate_detections( |
| ann_im, |
| l_obj=segs, |
| color_key="object_id", |
| label_key="object_id", |
| bbox_width=bbox_width, |
| ) |
| return ann_im |
|
|