File size: 1,609 Bytes
d667566
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Tiling helpers shared by training and inference."""
from __future__ import annotations

import numpy as np

from .config import STRIDE, TILE


def tile_origins(h: int, w: int, tile: int = TILE, stride: int = STRIDE) -> list[tuple[int, int]]:
    """Top-left corners of overlapping tiles covering the image."""
    def axis(n: int) -> list[int]:
        if n <= tile:
            return [0]
        pos = list(range(0, n - tile + 1, stride))
        if pos[-1] != n - tile:
            pos.append(n - tile)
        return pos

    return [(x, y) for y in axis(h) for x in axis(w)]


def pad_to(img: np.ndarray, tile: int = TILE) -> np.ndarray:
    """Pad the bottom/right so an image smaller than one tile still works."""
    h, w = img.shape[:2]
    ph, pw = max(0, tile - h), max(0, tile - w)
    if ph == 0 and pw == 0:
        return img
    return np.pad(img, [(0, ph), (0, pw)] + [(0, 0)] * (img.ndim - 2), mode="edge")


def boxes_in_tile(boxes: np.ndarray, x0: int, y0: int, tile: int = TILE,
                  min_visible: float = 0.7) -> np.ndarray:
    """Boxes clipped into tile-local coordinates, keeping mostly-visible ones."""
    if len(boxes) == 0:
        return np.zeros((0, 4), np.float32)
    b = boxes.astype(np.float32).copy()
    area = np.maximum(1.0, (b[:, 2] - b[:, 0]) * (b[:, 3] - b[:, 1]))
    b[:, [0, 2]] -= x0
    b[:, [1, 3]] -= y0
    c = b.copy()
    c[:, [0, 2]] = np.clip(c[:, [0, 2]], 0, tile)
    c[:, [1, 3]] = np.clip(c[:, [1, 3]], 0, tile)
    vis = np.clip(c[:, 2] - c[:, 0], 0, None) * np.clip(c[:, 3] - c[:, 1], 0, None)
    return c[vis / area >= min_visible]