|
@@ -1,17 +1,39 @@
|
|
from PIL import Image, ImageFilter, ImageOps
|
|
from PIL import Image, ImageFilter, ImageOps
|
|
|
|
|
|
|
|
|
|
-def get_crop_region(mask, pad=0):
|
|
|
|
- """finds a rectangular region that contains all masked ares in an image. Returns (x1, y1, x2, y2) coordinates of the rectangle.
|
|
|
|
- For example, if a user has painted the top-right part of a 512x512 image, the result may be (256, 0, 512, 256)"""
|
|
|
|
- mask_img = mask if isinstance(mask, Image.Image) else Image.fromarray(mask)
|
|
|
|
- box = mask_img.getbbox()
|
|
|
|
- if box:
|
|
|
|
|
|
+def get_crop_region_v2(mask, pad=0):
|
|
|
|
+ """
|
|
|
|
+ Finds a rectangular region that contains all masked ares in a mask.
|
|
|
|
+ Returns None if mask is completely black mask (all 0)
|
|
|
|
+
|
|
|
|
+ Parameters:
|
|
|
|
+ mask: PIL.Image.Image L mode or numpy 1d array
|
|
|
|
+ pad: int number of pixels that the region will be extended on all sides
|
|
|
|
+ Returns: (x1, y1, x2, y2) | None
|
|
|
|
+
|
|
|
|
+ Introduced post 1.9.0
|
|
|
|
+ """
|
|
|
|
+ mask = mask if isinstance(mask, Image.Image) else Image.fromarray(mask)
|
|
|
|
+ if box := mask.getbbox():
|
|
x1, y1, x2, y2 = box
|
|
x1, y1, x2, y2 = box
|
|
- else: # when no box is found
|
|
|
|
- x1, y1 = mask_img.size
|
|
|
|
- x2 = y2 = 0
|
|
|
|
- return max(x1 - pad, 0), max(y1 - pad, 0), min(x2 + pad, mask_img.size[0]), min(y2 + pad, mask_img.size[1])
|
|
|
|
|
|
+ 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
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def get_crop_region(mask, pad=0):
|
|
|
|
+ """
|
|
|
|
+ Same function as get_crop_region_v2 but handles completely black mask (all 0) differently
|
|
|
|
+ when mask all black still return coordinates but the coordinates may be invalid ie x2>x1 or y2>y1
|
|
|
|
+ Notes: it is possible for the coordinates to be "valid" again if pad size is sufficiently large
|
|
|
|
+ (mask_size.x-pad, mask_size.y-pad, pad, pad)
|
|
|
|
+
|
|
|
|
+ Extension developer should use get_crop_region_v2 instead unless for compatibility considerations.
|
|
|
|
+ """
|
|
|
|
+ mask = mask if isinstance(mask, Image.Image) else Image.fromarray(mask)
|
|
|
|
+ if box := get_crop_region_v2(mask, pad):
|
|
|
|
+ return box
|
|
|
|
+ x1, y1 = mask.size
|
|
|
|
+ x2 = y2 = 0
|
|
|
|
+ return max(x1 - pad, 0), max(y1 - pad, 0), min(x2 + pad, mask.size[0]), min(y2 + pad, mask.size[1])
|
|
|
|
|
|
|
|
|
|
def expand_crop_region(crop_region, processing_width, processing_height, image_width, image_height):
|
|
def expand_crop_region(crop_region, processing_width, processing_height, image_width, image_height):
|