Spaces:
Sleeping
Sleeping
import cv2 | |
import random | |
import numpy as np | |
from PIL import Image | |
def convert_OpenCV_to_PIL(image): | |
return Image.fromarray(image[..., ::-1]) | |
def convert_PIL_to_OpenCV(image): | |
return np.asarray(image)[..., ::-1] | |
class RandomResize: | |
def __init__(self, min_image_size, max_image_size): | |
self.min_image_size = min_image_size | |
self.max_image_size = max_image_size | |
self.modes = [Image.BICUBIC, Image.NEAREST] | |
def __call__(self, image, mode=Image.BICUBIC): | |
rand_image_size = random.randint(self.min_image_size, self.max_image_size) | |
w, h = image.size | |
if w < h: | |
scale = rand_image_size / h | |
else: | |
scale = rand_image_size / w | |
size = (int(round(w*scale)), int(round(h*scale))) | |
if size[0] == w and size[1] == h: | |
return image | |
return image.resize(size, mode) | |
class RandomResize_For_Segmentation: | |
def __init__(self, min_image_size, max_image_size): | |
self.min_image_size = min_image_size | |
self.max_image_size = max_image_size | |
self.modes = [Image.BICUBIC, Image.NEAREST] | |
def __call__(self, data): | |
image, mask = data['image'], data['mask'] | |
rand_image_size = random.randint(self.min_image_size, self.max_image_size) | |
w, h = image.size | |
if w < h: | |
scale = rand_image_size / h | |
else: | |
scale = rand_image_size / w | |
size = (int(round(w*scale)), int(round(h*scale))) | |
if size[0] == w and size[1] == h: | |
pass | |
else: | |
data['image'] = image.resize(size, Image.BICUBIC) | |
data['mask'] = mask.resize(size, Image.NEAREST) | |
return data | |
class RandomHorizontalFlip: | |
def __init__(self): | |
pass | |
def __call__(self, image): | |
if bool(random.getrandbits(1)): | |
return image.transpose(Image.FLIP_LEFT_RIGHT) | |
return image | |
class RandomHorizontalFlip_For_Segmentation: | |
def __init__(self): | |
pass | |
def __call__(self, data): | |
image, mask = data['image'], data['mask'] | |
if bool(random.getrandbits(1)): | |
data['image'] = image.transpose(Image.FLIP_LEFT_RIGHT) | |
data['mask'] = mask.transpose(Image.FLIP_LEFT_RIGHT) | |
return data | |
class Normalize: | |
def __init__(self, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)): | |
self.mean = mean | |
self.std = std | |
def __call__(self, image): | |
image = np.asarray(image) | |
norm_image = np.empty_like(image, np.float32) | |
norm_image[..., 0] = (image[..., 0] / 255. - self.mean[0]) / self.std[0] | |
norm_image[..., 1] = (image[..., 1] / 255. - self.mean[1]) / self.std[1] | |
norm_image[..., 2] = (image[..., 2] / 255. - self.mean[2]) / self.std[2] | |
return norm_image | |
class Normalize_For_Segmentation: | |
def __init__(self, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)): | |
self.mean = mean | |
self.std = std | |
def __call__(self, data): | |
image, mask = data['image'], data['mask'] | |
image = np.asarray(image, dtype=np.float32) | |
mask = np.asarray(mask, dtype=np.int64) | |
norm_image = np.empty_like(image, np.float32) | |
norm_image[..., 0] = (image[..., 0] / 255. - self.mean[0]) / self.std[0] | |
norm_image[..., 1] = (image[..., 1] / 255. - self.mean[1]) / self.std[1] | |
norm_image[..., 2] = (image[..., 2] / 255. - self.mean[2]) / self.std[2] | |
data['image'] = norm_image | |
data['mask'] = mask | |
return data | |
class Top_Left_Crop: | |
def __init__(self, crop_size, channels=3): | |
self.bg_value = 0 | |
self.crop_size = crop_size | |
self.crop_shape = (self.crop_size, self.crop_size, channels) | |
def __call__(self, image): | |
h, w, c = image.shape | |
ch = min(self.crop_size, h) | |
cw = min(self.crop_size, w) | |
cropped_image = np.ones(self.crop_shape, image.dtype) * self.bg_value | |
cropped_image[:ch, :cw] = image[:ch, :cw] | |
return cropped_image | |
class Top_Left_Crop_For_Segmentation: | |
def __init__(self, crop_size, channels=3): | |
self.bg_value = 0 | |
self.crop_size = crop_size | |
self.crop_shape = (self.crop_size, self.crop_size, channels) | |
self.crop_shape_for_mask = (self.crop_size, self.crop_size) | |
def __call__(self, data): | |
image, mask = data['image'], data['mask'] | |
h, w, c = image.shape | |
ch = min(self.crop_size, h) | |
cw = min(self.crop_size, w) | |
cropped_image = np.ones(self.crop_shape, image.dtype) * self.bg_value | |
cropped_image[:ch, :cw] = image[:ch, :cw] | |
cropped_mask = np.ones(self.crop_shape_for_mask, mask.dtype) * 255 | |
cropped_mask[:ch, :cw] = mask[:ch, :cw] | |
data['image'] = cropped_image | |
data['mask'] = cropped_mask | |
return data | |
class RandomCrop: | |
def __init__(self, crop_size, channels=3, with_bbox=False): | |
self.bg_value = 0 | |
self.with_bbox = with_bbox | |
self.crop_size = crop_size | |
self.crop_shape = (self.crop_size, self.crop_size, channels) | |
def get_random_crop_box(self, image): | |
h, w, c = image.shape | |
ch = min(self.crop_size, h) | |
cw = min(self.crop_size, w) | |
w_space = w - self.crop_size | |
h_space = h - self.crop_size | |
if w_space > 0: | |
cont_left = 0 | |
img_left = random.randrange(w_space + 1) | |
else: | |
cont_left = random.randrange(-w_space + 1) | |
img_left = 0 | |
if h_space > 0: | |
cont_top = 0 | |
img_top = random.randrange(h_space + 1) | |
else: | |
cont_top = random.randrange(-h_space + 1) | |
img_top = 0 | |
dst_bbox = { | |
'xmin' : cont_left, 'ymin' : cont_top, | |
'xmax' : cont_left+cw, 'ymax' : cont_top+ch | |
} | |
src_bbox = { | |
'xmin' : img_left, 'ymin' : img_top, | |
'xmax' : img_left+cw, 'ymax' : img_top+ch | |
} | |
return dst_bbox, src_bbox | |
def __call__(self, image, bbox_dic=None): | |
if bbox_dic is None: | |
dst_bbox, src_bbox = self.get_random_crop_box(image) | |
else: | |
dst_bbox, src_bbox = bbox_dic['dst_bbox'], bbox_dic['src_bbox'] | |
cropped_image = np.ones(self.crop_shape, image.dtype) * self.bg_value | |
cropped_image[dst_bbox['ymin']:dst_bbox['ymax'], dst_bbox['xmin']:dst_bbox['xmax']] = \ | |
image[src_bbox['ymin']:src_bbox['ymax'], src_bbox['xmin']:src_bbox['xmax']] | |
if self.with_bbox: | |
return cropped_image, {'dst_bbox':dst_bbox, 'src_bbox':src_bbox} | |
else: | |
return cropped_image | |
class RandomCrop_For_Segmentation(RandomCrop): | |
def __init__(self, crop_size): | |
super().__init__(crop_size) | |
self.crop_shape_for_mask = (self.crop_size, self.crop_size) | |
def __call__(self, data): | |
image, mask = data['image'], data['mask'] | |
dst_bbox, src_bbox = self.get_random_crop_box(image) | |
cropped_image = np.ones(self.crop_shape, image.dtype) * self.bg_value | |
cropped_image[dst_bbox['ymin']:dst_bbox['ymax'], dst_bbox['xmin']:dst_bbox['xmax']] = \ | |
image[src_bbox['ymin']:src_bbox['ymax'], src_bbox['xmin']:src_bbox['xmax']] | |
cropped_mask = np.ones(self.crop_shape_for_mask, mask.dtype) * 255 | |
cropped_mask[dst_bbox['ymin']:dst_bbox['ymax'], dst_bbox['xmin']:dst_bbox['xmax']] = \ | |
mask[src_bbox['ymin']:src_bbox['ymax'], src_bbox['xmin']:src_bbox['xmax']] | |
data['image'] = cropped_image | |
data['mask'] = cropped_mask | |
return data | |
class Transpose: | |
def __init__(self): | |
pass | |
def __call__(self, image): | |
return image.transpose((2, 0, 1)) | |
class Transpose_For_Segmentation: | |
def __init__(self): | |
pass | |
def __call__(self, data): | |
# h, w, c -> c, h, w | |
data['image'] = data['image'].transpose((2, 0, 1)) | |
return data | |
class Resize_For_Mask: | |
def __init__(self, size): | |
self.size = (size, size) | |
def __call__(self, data): | |
mask = Image.fromarray(data['mask'].astype(np.uint8)) | |
mask = mask.resize(self.size, Image.NEAREST) | |
data['mask'] = np.asarray(mask, dtype=np.uint64) | |
return data | |