|
from typing import Dict, Any, Tuple, Optional |
|
|
|
from PIL import Image |
|
|
|
from ..root import TRANSFORMS |
|
|
|
|
|
def de_norm_box_xyxy(box, *, w, h): |
|
x1, y1, x2, y2 = box |
|
x1 = x1 * w |
|
x2 = x2 * w |
|
y1 = y1 * h |
|
y2 = y2 * h |
|
box = x1, y1, x2, y2 |
|
return box |
|
|
|
|
|
def box_xywh_to_xyxy(box, *, w=None, h=None): |
|
x, y, bw, bh = box |
|
x2 = x + bw |
|
y2 = y + bh |
|
if w is not None: |
|
x2 = min(x2, w) |
|
if h is not None: |
|
y2 = min(y2, h) |
|
box = x, y, x2, y2 |
|
return box |
|
|
|
|
|
def norm_box_xyxy(box, *, w, h): |
|
x1, y1, x2, y2 = box |
|
|
|
|
|
norm_x1 = max(0.0, min(x1 / w, 1.0)) |
|
norm_y1 = max(0.0, min(y1 / h, 1.0)) |
|
norm_x2 = max(0.0, min(x2 / w, 1.0)) |
|
norm_y2 = max(0.0, min(y2 / h, 1.0)) |
|
|
|
|
|
normalized_box = (round(norm_x1, 3), round(norm_y1, 3), round(norm_x2, 3), round(norm_y2, 3)) |
|
return normalized_box |
|
|
|
|
|
def norm_point_xyxy(point, *, w, h): |
|
x, y = point |
|
norm_x = max(0.0, min(x / w, 1.0)) |
|
norm_y = max(0.0, min(y / h, 1.0)) |
|
point = norm_x, norm_y |
|
return point |
|
|
|
|
|
def expand2square(pil_img, background_color=(255, 255, 255)): |
|
width, height = pil_img.size |
|
if width == height: |
|
return pil_img |
|
elif width > height: |
|
result = Image.new(pil_img.mode, (width, width), background_color) |
|
result.paste(pil_img, (0, (width - height) // 2)) |
|
return result |
|
else: |
|
result = Image.new(pil_img.mode, (height, height), background_color) |
|
result.paste(pil_img, ((height - width) // 2, 0)) |
|
return result |
|
|
|
|
|
def box_xyxy_expand2square(box, *, w, h): |
|
if w == h: |
|
return box |
|
if w > h: |
|
x1, y1, x2, y2 = box |
|
y1 += (w - h) // 2 |
|
y2 += (w - h) // 2 |
|
box = x1, y1, x2, y2 |
|
return box |
|
assert w < h |
|
x1, y1, x2, y2 = box |
|
x1 += (h - w) // 2 |
|
x2 += (h - w) // 2 |
|
box = x1, y1, x2, y2 |
|
return box |
|
|
|
|
|
def point_xy_expand2square(point, *, w, h): |
|
pseudo_box = (point[0], point[1], point[0], point[1]) |
|
expanded_box = box_xyxy_expand2square(box=pseudo_box, w=w, h=h) |
|
expanded_point = (expanded_box[0], expanded_box[1]) |
|
return expanded_point |
|
|
|
|
|
@TRANSFORMS.register_module() |
|
class Expand2square: |
|
def __init__(self, background_color=(255, 255, 255)): |
|
self.background_color = background_color |
|
|
|
def __call__(self, image: Image.Image, labels: Dict[str, Any] = None) -> Tuple[Image.Image, Optional[Dict[str, Any]]]: |
|
width, height = image.size |
|
processed_image = expand2square(image, background_color=self.background_color) |
|
if labels is None: |
|
return processed_image, labels |
|
if 'boxes' in labels: |
|
bboxes = [box_xyxy_expand2square(bbox, w=width, h=height) for bbox in labels['boxes']] |
|
labels['boxes'] = bboxes |
|
if 'points' in labels: |
|
points = [point_xy_expand2square(point, w=width, h=height) for point in labels['points']] |
|
labels['points'] = points |
|
return processed_image, labels |
|
|