Spaces:
Running on Zero
Running on Zero
File size: 2,722 Bytes
7826761 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | from __future__ import annotations
import cv2
import numpy as np
def create_default_face_bbox(image: np.ndarray, scale: float = 0.9) -> np.ndarray:
img_h, img_w = image.shape[:2]
box_size = min(img_w, img_h) * float(scale)
cx = (img_w - 1) * 0.5
cy = (img_h - 1) * 0.5
half = box_size * 0.5
return np.array([cx - half, cy - half, cx + half, cy + half], dtype=np.float32)
def enlarge_bbox(bbox: np.ndarray, scale: float) -> np.ndarray:
bbox = np.asarray(bbox, dtype=np.float32)
center = np.array([(bbox[0] + bbox[2]) * 0.5, (bbox[1] + bbox[3]) * 0.5], dtype=np.float32)
size = np.array([bbox[2] - bbox[0], bbox[3] - bbox[1]], dtype=np.float32) * float(scale)
half = size * 0.5
return np.array(
[center[0] - half[0], center[1] - half[1], center[0] + half[0], center[1] + half[1]],
dtype=np.float32,
)
def make_bbox_square(bbox: np.ndarray) -> np.ndarray:
x0, y0, x1, y1 = np.asarray(bbox, dtype=np.float32)
size = int(round(max(x1 - x0, y1 - y0)))
cx = (x0 + x1) * 0.5
cy = (y0 + y1) * 0.5
new_x0 = int(round(cx - size * 0.5))
new_y0 = int(round(cy - size * 0.5))
new_x1 = new_x0 + size
new_y1 = new_y0 + size
return np.array([new_x0, new_y0, new_x1, new_y1], dtype=np.int32)
def calc_crop_pad_info(
bbox: np.ndarray,
img_width: int,
img_height: int,
) -> tuple[tuple[int, int, int, int], tuple[int, int, int, int]]:
x0, y0, x1, y1 = np.asarray(bbox, dtype=np.int32)
pad_left = max(0, -x0)
pad_top = max(0, -y0)
pad_right = max(0, x1 - img_width)
pad_bottom = max(0, y1 - img_height)
crop_left = max(0, x0)
crop_top = max(0, y0)
crop_right = min(img_width, x1)
crop_bottom = min(img_height, y1)
return (pad_left, pad_top, pad_right, pad_bottom), (crop_left, crop_top, crop_right, crop_bottom)
def crop_and_resize_image(
image: np.ndarray,
bbox: np.ndarray,
target_size: int,
) -> tuple[np.ndarray, np.ndarray]:
img_h, img_w = image.shape[:2]
bbox = np.asarray(bbox, dtype=np.float32).copy()
pad_info, crop_info = calc_crop_pad_info(bbox, img_w, img_h)
bbox_w = int(round(float(bbox[2] - bbox[0])))
bbox_h = int(round(float(bbox[3] - bbox[1])))
x0, y0, x1, y1 = crop_info
cropped = image[y0:y1, x0:x1]
if sum(pad_info) > 0:
padded = np.zeros((bbox_h, bbox_w, 3), dtype=image.dtype)
padded[pad_info[1]:(bbox_h - pad_info[3]), pad_info[0]:(bbox_w - pad_info[2])] = cropped
cropped = padded
resized = cv2.resize(cropped, (int(target_size), int(target_size)), interpolation=cv2.INTER_LINEAR)
return resized, bbox
|