|
1 | 1 | from PIL import Image, ImageFilter, ImageOps
|
2 | 2 |
|
3 | 3 |
|
4 |
| -def get_crop_region(mask, pad=0): |
5 |
| - """finds a rectangular region that contains all masked ares in an image. Returns (x1, y1, x2, y2) coordinates of the rectangle. |
6 |
| - For example, if a user has painted the top-right part of a 512x512 image, the result may be (256, 0, 512, 256)""" |
7 |
| - mask_img = mask if isinstance(mask, Image.Image) else Image.fromarray(mask) |
8 |
| - box = mask_img.getbbox() |
9 |
| - if box: |
| 4 | +def get_crop_region_v2(mask, pad=0): |
| 5 | + """ |
| 6 | + Finds a rectangular region that contains all masked ares in a mask. |
| 7 | + Returns None if mask is completely black mask (all 0) |
| 8 | +
|
| 9 | + Parameters: |
| 10 | + mask: PIL.Image.Image L mode or numpy 1d array |
| 11 | + pad: int number of pixels that the region will be extended on all sides |
| 12 | + Returns: (x1, y1, x2, y2) | None |
| 13 | +
|
| 14 | + Introduced post 1.9.0 |
| 15 | + """ |
| 16 | + mask = mask if isinstance(mask, Image.Image) else Image.fromarray(mask) |
| 17 | + if box := mask.getbbox(): |
10 | 18 | x1, y1, x2, y2 = box
|
11 |
| - else: # when no box is found |
12 |
| - x1, y1 = mask_img.size |
13 |
| - x2 = y2 = 0 |
14 |
| - return max(x1 - pad, 0), max(y1 - pad, 0), min(x2 + pad, mask_img.size[0]), min(y2 + pad, mask_img.size[1]) |
| 19 | + return max(x1 - pad, 0), max(y1 - pad, 0), min(x2 + pad, mask.size[0]), min(y2 + pad, mask.size[1]) if pad else box |
| 20 | + |
| 21 | + |
| 22 | +def get_crop_region(mask, pad=0): |
| 23 | + """ |
| 24 | + Same function as get_crop_region_v2 but handles completely black mask (all 0) differently |
| 25 | + when mask all black still return coordinates but the coordinates may be invalid ie x2>x1 or y2>y1 |
| 26 | + Notes: it is possible for the coordinates to be "valid" again if pad size is sufficiently large |
| 27 | + (mask_size.x-pad, mask_size.y-pad, pad, pad) |
| 28 | +
|
| 29 | + Extension developer should use get_crop_region_v2 instead unless for compatibility considerations. |
| 30 | + """ |
| 31 | + mask = mask if isinstance(mask, Image.Image) else Image.fromarray(mask) |
| 32 | + if box := get_crop_region_v2(mask, pad): |
| 33 | + return box |
| 34 | + x1, y1 = mask.size |
| 35 | + x2 = y2 = 0 |
| 36 | + return max(x1 - pad, 0), max(y1 - pad, 0), min(x2 + pad, mask.size[0]), min(y2 + pad, mask.size[1]) |
15 | 37 |
|
16 | 38 |
|
17 | 39 | def expand_crop_region(crop_region, processing_width, processing_height, image_width, image_height):
|
|
0 commit comments