网络编程
位置:首页>> 网络编程>> Python编程>> 详解Python实现图像分割增强的两种方法

详解Python实现图像分割增强的两种方法

作者:AI浩  发布时间:2022-08-16 20:23:50 

标签:Python,图像,分割,增强

方法一

import random
import numpy as np
from PIL import Image, ImageOps, ImageFilter
from skimage.filters import gaussian
import torch
import math
import numbers
import random

class RandomVerticalFlip(object):
   def __call__(self, img):
       if random.random() < 0.5:
           return img.transpose(Image.FLIP_TOP_BOTTOM)
       return img

class DeNormalize(object):
   def __init__(self, mean, std):
       self.mean = mean
       self.std = std

def __call__(self, tensor):
       for t, m, s in zip(tensor, self.mean, self.std):
           t.mul_(s).add_(m)
       return tensor

class MaskToTensor(object):
   def __call__(self, img):
       return torch.from_numpy(np.array(img, dtype=np.int32)).long()

class FreeScale(object):
   def __init__(self, size, interpolation=Image.BILINEAR):
       self.size = tuple(reversed(size))  # size: (h, w)
       self.interpolation = interpolation

def __call__(self, img):
       return img.resize(self.size, self.interpolation)

class FlipChannels(object):
   def __call__(self, img):
       img = np.array(img)[:, :, ::-1]
       return Image.fromarray(img.astype(np.uint8))

class RandomGaussianBlur(object):
   def __call__(self, img):
       sigma = 0.15 + random.random() * 1.15
       blurred_img = gaussian(np.array(img), sigma=sigma, multichannel=True)
       blurred_img *= 255
       return Image.fromarray(blurred_img.astype(np.uint8))
# 组合
class Compose(object):
   def __init__(self, transforms):
       self.transforms = transforms

def __call__(self, img, mask):
       assert img.size == mask.size
       for t in self.transforms:
           img, mask = t(img, mask)
       return img, mask
# 随机裁剪
class RandomCrop(object):
   def __init__(self, size, padding=0):
       if isinstance(size, numbers.Number):
           self.size = (int(size), int(size))
       else:
           self.size = size
       self.padding = padding

def __call__(self, img, mask):
       if self.padding > 0:
           img = ImageOps.expand(img, border=self.padding, fill=0)
           mask = ImageOps.expand(mask, border=self.padding, fill=0)

assert img.size == mask.size
       w, h = img.size
       th, tw = self.size
       if w == tw and h == th:
           return img, mask
       if w < tw or h < th:
           return img.resize((tw, th), Image.BILINEAR), mask.resize((tw, th), Image.NEAREST)

x1 = random.randint(0, w - tw)
       y1 = random.randint(0, h - th)
       return img.crop((x1, y1, x1 + tw, y1 + th)), mask.crop((x1, y1, x1 + tw, y1 + th))

#  中心裁剪
class CenterCrop(object):
   def __init__(self, size):
       if isinstance(size, numbers.Number):
           self.size = (int(size), int(size))
       else:
           self.size = size

def __call__(self, img, mask):
       assert img.size == mask.size
       w, h = img.size
       th, tw = self.size
       x1 = int(round((w - tw) / 2.))
       y1 = int(round((h - th) / 2.))
       return img.crop((x1, y1, x1 + tw, y1 + th)), mask.crop((x1, y1, x1 + tw, y1 + th))

class RandomHorizontallyFlip(object):
   def __call__(self, img, mask):
       if random.random() < 0.5:
           return img.transpose(Image.FLIP_LEFT_RIGHT), mask.transpose(Image.FLIP_LEFT_RIGHT)
       return img, mask

class Scale(object):
   def __init__(self, size):
       self.size = size

def __call__(self, img, mask):
       assert img.size == mask.size
       w, h = img.size
       if (w >= h and w == self.size) or (h >= w and h == self.size):
           return img, mask
       if w > h:
           ow = self.size
           oh = int(self.size * h / w)
           return img.resize((ow, oh), Image.BILINEAR), mask.resize((ow, oh), Image.NEAREST)
       else:
           oh = self.size
           ow = int(self.size * w / h)
           return img.resize((ow, oh), Image.BILINEAR), mask.resize((ow, oh), Image.NEAREST)

class RandomSizedCrop(object):
   def __init__(self, size):
       self.size = size

def __call__(self, img, mask):
       assert img.size == mask.size
       for attempt in range(10):
           area = img.size[0] * img.size[1]
           target_area = random.uniform(0.45, 1.0) * area
           aspect_ratio = random.uniform(0.5, 2)

w = int(round(math.sqrt(target_area * aspect_ratio)))
           h = int(round(math.sqrt(target_area / aspect_ratio)))

if random.random() < 0.5:
               w, h = h, w

if w <= img.size[0] and h <= img.size[1]:
               x1 = random.randint(0, img.size[0] - w)
               y1 = random.randint(0, img.size[1] - h)

img = img.crop((x1, y1, x1 + w, y1 + h))
               mask = mask.crop((x1, y1, x1 + w, y1 + h))
               assert (img.size == (w, h))

return img.resize((self.size, self.size), Image.BILINEAR), mask.resize((self.size, self.size),
                                                                                      Image.NEAREST)

# Fallback
       scale = Scale(self.size)
       crop = CenterCrop(self.size)
       return crop(*scale(img, mask))

class RandomRotate(object):
   def __init__(self, degree):
       self.degree = degree

def __call__(self, img, mask):
       rotate_degree = random.random() * 2 * self.degree - self.degree
       return img.rotate(rotate_degree, Image.BILINEAR), mask.rotate(rotate_degree, Image.NEAREST)

class RandomSized(object):
   def __init__(self, size):
       self.size = size
       self.scale = Scale(self.size)
       self.crop = RandomCrop(self.size)

def __call__(self, img, mask):
       assert img.size == mask.size

w = int(random.uniform(0.5, 2) * img.size[0])
       h = int(random.uniform(0.5, 2) * img.size[1])

img, mask = img.resize((w, h), Image.BILINEAR), mask.resize((w, h), Image.NEAREST)

return self.crop(*self.scale(img, mask))

class SlidingCropOld(object):
   def __init__(self, crop_size, stride_rate, ignore_label):
       self.crop_size = crop_size
       self.stride_rate = stride_rate
       self.ignore_label = ignore_label

def _pad(self, img, mask):
       h, w = img.shape[: 2]
       pad_h = max(self.crop_size - h, 0)
       pad_w = max(self.crop_size - w, 0)
       img = np.pad(img, ((0, pad_h), (0, pad_w), (0, 0)), 'constant')
       mask = np.pad(mask, ((0, pad_h), (0, pad_w)), 'constant', constant_values=self.ignore_label)
       return img, mask

def __call__(self, img, mask):
       assert img.size == mask.size

w, h = img.size
       long_size = max(h, w)

img = np.array(img)
       mask = np.array(mask)

if long_size > self.crop_size:
           stride = int(math.ceil(self.crop_size * self.stride_rate))
           h_step_num = int(math.ceil((h - self.crop_size) / float(stride))) + 1
           w_step_num = int(math.ceil((w - self.crop_size) / float(stride))) + 1
           img_sublist, mask_sublist = [], []
           for yy in range(h_step_num):
               for xx in range(w_step_num):
                   sy, sx = yy * stride, xx * stride
                   ey, ex = sy + self.crop_size, sx + self.crop_size
                   img_sub = img[sy: ey, sx: ex, :]
                   mask_sub = mask[sy: ey, sx: ex]
                   img_sub, mask_sub = self._pad(img_sub, mask_sub)
                   img_sublist.append(Image.fromarray(img_sub.astype(np.uint8)).convert('RGB'))
                   mask_sublist.append(Image.fromarray(mask_sub.astype(np.uint8)).convert('P'))
           return img_sublist, mask_sublist
       else:
           img, mask = self._pad(img, mask)
           img = Image.fromarray(img.astype(np.uint8)).convert('RGB')
           mask = Image.fromarray(mask.astype(np.uint8)).convert('P')
           return img, mask

class SlidingCrop(object):
   def __init__(self, crop_size, stride_rate, ignore_label):
       self.crop_size = crop_size
       self.stride_rate = stride_rate
       self.ignore_label = ignore_label

def _pad(self, img, mask):
       h, w = img.shape[: 2]
       pad_h = max(self.crop_size - h, 0)
       pad_w = max(self.crop_size - w, 0)
       img = np.pad(img, ((0, pad_h), (0, pad_w), (0, 0)), 'constant')
       mask = np.pad(mask, ((0, pad_h), (0, pad_w)), 'constant', constant_values=self.ignore_label)
       return img, mask, h, w

def __call__(self, img, mask):
       assert img.size == mask.size

w, h = img.size
       long_size = max(h, w)

img = np.array(img)
       mask = np.array(mask)

if long_size > self.crop_size:
           stride = int(math.ceil(self.crop_size * self.stride_rate))
           h_step_num = int(math.ceil((h - self.crop_size) / float(stride))) + 1
           w_step_num = int(math.ceil((w - self.crop_size) / float(stride))) + 1
           img_slices, mask_slices, slices_info = [], [], []
           for yy in range(h_step_num):
               for xx in range(w_step_num):
                   sy, sx = yy * stride, xx * stride
                   ey, ex = sy + self.crop_size, sx + self.crop_size
                   img_sub = img[sy: ey, sx: ex, :]
                   mask_sub = mask[sy: ey, sx: ex]
                   img_sub, mask_sub, sub_h, sub_w = self._pad(img_sub, mask_sub)
                   img_slices.append(Image.fromarray(img_sub.astype(np.uint8)).convert('RGB'))
                   mask_slices.append(Image.fromarray(mask_sub.astype(np.uint8)).convert('P'))
                   slices_info.append([sy, ey, sx, ex, sub_h, sub_w])
           return img_slices, mask_slices, slices_info
       else:
           img, mask, sub_h, sub_w = self._pad(img, mask)
           img = Image.fromarray(img.astype(np.uint8)).convert('RGB')
           mask = Image.fromarray(mask.astype(np.uint8)).convert('P')
           return [img], [mask], [[0, sub_h, 0, sub_w, sub_h, sub_w]]

方法二

import numpy as np
import random

import torch
from torchvision import transforms as T
from torchvision.transforms import functional as F

def pad_if_smaller(img, size, fill=0):
   # 如果图像最小边长小于给定size,则用数值fill进行padding
   min_size = min(img.size)
   if min_size < size:
       ow, oh = img.size
       padh = size - oh if oh < size else 0
       padw = size - ow if ow < size else 0
       img = F.pad(img, (0, 0, padw, padh), fill=fill)
   return img

class Compose(object):
   def __init__(self, transforms):
       self.transforms = transforms

def __call__(self, image, target):
       for t in self.transforms:
           image, target = t(image, target)
       return image, target

class RandomResize(object):
   def __init__(self, min_size, max_size=None):
       self.min_size = min_size
       if max_size is None:
           max_size = min_size
       self.max_size = max_size

def __call__(self, image, target):
       size = random.randint(self.min_size, self.max_size)
       # 这里size传入的是int类型,所以是将图像的最小边长缩放到size大小
       image = F.resize(image, size)
       # 这里的interpolation注意下,在torchvision(0.9.0)以后才有InterpolationMode.NEAREST
       # 如果是之前的版本需要使用PIL.Image.NEAREST
       target = F.resize(target, size, interpolation=T.InterpolationMode.NEAREST)
       return image, target

class RandomHorizontalFlip(object):
   def __init__(self, flip_prob):
       self.flip_prob = flip_prob

def __call__(self, image, target):
       if random.random() < self.flip_prob:
           image = F.hflip(image)
           target = F.hflip(target)
       return image, target

class RandomCrop(object):
   def __init__(self, size):
       self.size = size

def __call__(self, image, target):
       image = pad_if_smaller(image, self.size)
       target = pad_if_smaller(target, self.size, fill=255)
       crop_params = T.RandomCrop.get_params(image, (self.size, self.size))
       image = F.crop(image, *crop_params)
       target = F.crop(target, *crop_params)
       return image, target

class CenterCrop(object):
   def __init__(self, size):
       self.size = size

def __call__(self, image, target):
       image = F.center_crop(image, self.size)
       target = F.center_crop(target, self.size)
       return image, target

class ToTensor(object):
   def __call__(self, image, target):
       image = F.to_tensor(image)
       target = torch.as_tensor(np.array(target), dtype=torch.int64)
       return image, target

class Normalize(object):
   def __init__(self, mean, std):
       self.mean = mean
       self.std = std

def __call__(self, image, target):
       image = F.normalize(image, mean=self.mean, std=self.std)
       return image, target

来源:https://blog.csdn.net/hhhhhhhhhhwwwwwwwwww/article/details/123233333

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com