| 27 | |
| 28 | |
| 29 | def random_crop_arr(pil_image, image_size, min_crop_frac=0.8, max_crop_frac=1.0): |
| 30 | min_smaller_dim_size = math.ceil(image_size / max_crop_frac) |
| 31 | max_smaller_dim_size = math.ceil(image_size / min_crop_frac) |
| 32 | smaller_dim_size = random.randrange(min_smaller_dim_size, max_smaller_dim_size + 1) |
| 33 | |
| 34 | # We are not on a new enough PIL to support the `reducing_gap` |
| 35 | # argument, which uses BOX downsampling at powers of two first. |
| 36 | # Thus, we do it by hand to improve downsample quality. |
| 37 | while min(*pil_image.size) >= 2 * smaller_dim_size: |
| 38 | pil_image = pil_image.resize( |
| 39 | tuple(x // 2 for x in pil_image.size), resample=Image.BOX |
| 40 | ) |
| 41 | |
| 42 | scale = smaller_dim_size / min(*pil_image.size) |
| 43 | pil_image = pil_image.resize( |
| 44 | tuple(round(x * scale) for x in pil_image.size), resample=Image.BICUBIC |
| 45 | ) |
| 46 | |
| 47 | arr = np.array(pil_image) |
| 48 | crop_y = random.randrange(arr.shape[0] - image_size + 1) |
| 49 | crop_x = random.randrange(arr.shape[1] - image_size + 1) |
| 50 | return Image.fromarray(arr[crop_y : crop_y + image_size, crop_x : crop_x + image_size]) |
| 51 | |