|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"""Mask utilities.""" |
|
|
|
|
|
import numpy as np |
|
|
from pycocotools.mask import encode |
|
|
|
|
|
|
|
|
def mask_to_box(mask): |
|
|
"""Convert binary masks to boxes.""" |
|
|
shape, (h, w) = mask.shape, mask.shape[-2:] |
|
|
masks = mask.reshape((-1, h, w)).astype("bool") |
|
|
in_height = np.max(masks, axis=-1) |
|
|
in_width = np.max(masks, axis=-2) |
|
|
in_height_coords = in_height * np.arange(h, dtype="int32") |
|
|
in_width_coords = in_width * np.arange(w, dtype="int32") |
|
|
bottom_edges = np.max(in_height_coords, axis=-1) |
|
|
top_edges = np.min(in_height_coords + h * (~in_height), axis=-1) |
|
|
right_edges = np.max(in_width_coords, axis=-1) |
|
|
left_edges = np.min(in_width_coords + w * (~in_width), axis=-1) |
|
|
is_empty = (right_edges < left_edges) | (bottom_edges < top_edges) |
|
|
boxes = np.stack([left_edges, top_edges, right_edges, bottom_edges], axis=-1) |
|
|
boxes = boxes.astype("float32") * ((~is_empty)[:, None]) |
|
|
return boxes.reshape(*shape[:-2], 4) if len(shape) > 2 else boxes[0] |
|
|
|
|
|
|
|
|
def encode_masks(masks): |
|
|
"""Encode a set of masks to RLEs.""" |
|
|
rles = encode(np.asfortranarray(masks)) |
|
|
for rle in rles: |
|
|
rle["counts"] = rle["counts"].decode() |
|
|
return rles |
|
|
|