Divide in image of size [w, h] in up to max_num_patches of size patch_size
(h, w, patch_size, max_num_crops)
| 294 | |
| 295 | |
| 296 | def select_tiling(h, w, patch_size, max_num_crops): |
| 297 | """Divide in image of size [w, h] in up to max_num_patches of size patch_size""" |
| 298 | original_size = np.stack([h, w]) # [1, 2] |
| 299 | original_res = h * w |
| 300 | tilings = [] |
| 301 | for i in range(1, max_num_crops + 1): |
| 302 | for j in range(1, max_num_crops + 1): |
| 303 | if i*j <= max_num_crops: |
| 304 | tilings.append((i, j)) |
| 305 | # sort so argmin and argmax favour smaller tilings in the event of a tie |
| 306 | tilings.sort(key=lambda x: (x[0]*x[1], x[0])) |
| 307 | candidate_tilings = np.array(tilings, dtype=np.int32) # [n_resolutions, 2] |
| 308 | candidate_resolutions = candidate_tilings * patch_size # [n_resolutions, 2] |
| 309 | |
| 310 | # How much we would need to scale the image to fit exactly in each tiling |
| 311 | original_size = np.stack([h, w], dtype=np.float32) # [1, 2] |
| 312 | |
| 313 | # The original size can be zero in rare cases if the image is smaller than the margin |
| 314 | # In those cases letting the scale become infinite means the tiling is based on the |
| 315 | # other side, or falls back to the smallest tiling |
| 316 | with np.errstate(divide='ignore'): |
| 317 | required_scale_d = candidate_resolutions.astype(np.float32) / original_size, |
| 318 | required_scale = np.min(required_scale_d, axis=-1, keepdims=True) # [n_resolutions, 1] |
| 319 | if np.all(required_scale < 1): |
| 320 | # We are forced to downscale, so try to minimize the amount of downscaling |
| 321 | ix = np.argmax(required_scale) |
| 322 | else: |
| 323 | # Pick the resolution that required the least upscaling so that it most closely fits the image |
| 324 | required_scale = np.where(required_scale < 1.0, 10e9, required_scale) |
| 325 | ix = np.argmin(required_scale) |
| 326 | return candidate_tilings[ix] |
| 327 | |
| 328 | |
| 329 | @dataclasses.dataclass |
no outgoing calls
no test coverage detected