Divide in image of size [w, h] in up to max_num_patches of size patch_size
(h, w, patch_size, max_num_crops)
| 201 | |
| 202 | |
| 203 | def select_tiling(h, w, patch_size, max_num_crops): |
| 204 | """Divide in image of size [w, h] in up to max_num_patches of size patch_size""" |
| 205 | original_size = np.stack([h, w]) # [1, 2] |
| 206 | original_res = h * w |
| 207 | tilings = [] |
| 208 | for i in range(1, max_num_crops + 1): |
| 209 | for j in range(1, max_num_crops + 1): |
| 210 | if i*j <= max_num_crops: |
| 211 | tilings.append((i, j)) |
| 212 | # sort so argmin and argmax favour smaller tilings in the event of a tie |
| 213 | tilings.sort(key=lambda x: (x[0]*x[1], x[0])) |
| 214 | candidate_tilings = np.array(tilings, dtype=np.int32) # [n_resolutions, 2] |
| 215 | candidate_resolutions = candidate_tilings * patch_size # [n_resolutions, 2] |
| 216 | |
| 217 | # How much we would need to scale the image to fit exactly in each tiling |
| 218 | original_size = np.stack([h, w], dtype=np.float32) # [1, 2] |
| 219 | |
| 220 | # The original size can be zero in rare cases if the image is smaller than the margin |
| 221 | # In those cases letting the scale become infinite means the tiling is based on the |
| 222 | # other side, or falls back to the smallest tiling |
| 223 | with np.errstate(divide='ignore'): |
| 224 | required_scale_d = candidate_resolutions.astype(np.float32) / original_size, |
| 225 | required_scale = np.min(required_scale_d, axis=-1, keepdims=True) # [n_resolutions, 1] |
| 226 | if np.all(required_scale < 1): |
| 227 | # We are forced to downscale, so try to minimize the amount of downscaling |
| 228 | ix = np.argmax(required_scale) |
| 229 | else: |
| 230 | # Pick the resolution that required the least upscaling so that it most closely fits the image |
| 231 | required_scale = np.where(required_scale < 1.0, 10e9, required_scale) |
| 232 | ix = np.argmin(required_scale) |
| 233 | return candidate_tilings[ix] |
| 234 | |
| 235 | |
| 236 | def pixels_to_patches(array, patch_size): |
no outgoing calls
no test coverage detected