text: import os
  from random import shuffle
  
  import cv2
  import numpy as np
  from PIL import Image
  from torch.utils.data.dataset import Dataset
  
  
  def letterbox_image(image, label , size):
      label = Image.fromarray(np.array(label))
      '''resize image with unchanged aspect ratio using padding'''
      iw, ih = image.size
      w, h = size
      scale = min(w/iw, h/ih)
      nw = int(iw*scale)
      nh = int(ih*scale)
  
      image = image.resize((nw,nh), Image.BICUBIC)
      new_image = Image.new('RGB', size, (128,128,128))
      new_image.paste(image, ((w-nw)//2, (h-nh)//2))
  
      label = label.resize((nw,nh), Image.NEAREST)
      new_label = Image.new('L', size, (0))
      new_label.paste(label, ((w-nw)//2, (h-nh)//2))
  
      return new_image, new_label
  
  def rand(a=0, b=1):
      return np.random.rand()*(b-a) + a
  
  class DeeplabDataset(Dataset):
      def __init__(self,train_lines,image_size,num_classes,random_data,dataset_path):
          super(DeeplabDataset, self).__init__()
  
          self.train_lines    = train_lines
          self.train_batches  = len(train_lines)
          self.image_size     = image_size
          self.num_classes    = num_classes
          self.random_data    = random_data
          self.dataset_path   = dataset_path
  
      def __len__(self):
          return self.train_batches
  
      def rand(self, a=0, b=1):
          return np.random.rand() * (b - a) + a
  
      def get_random_data(self, image, label, input_shape, jitter=.1, hue=.0, sat=1.1, val=1.1):
          image = image.convert("RGB")
          label = Image.fromarray(np.array(label))
  
          h, w = input_shape
          # resize image
          rand_jit1 = rand(1-jitter,1+jitter)
          rand_jit2 = rand(1-jitter,1+jitter)
          new_ar = w/h * rand_jit1/rand_jit2
  
          scale = rand(0.5,1.5)
          if new_ar < 1:
              nh = int(scale*h)
              nw = int(nh*new_ar)
          else:
              nw = int(scale*w)
              nh = int(nw/new_ar)
          image = image.resize((nw,nh), Image.BICUBIC)
          label = label.resize((nw,nh), Image.NEAREST)
          label = label.convert("L")
          
          # flip image or not
          flip = rand()<.5
          if flip: 
              image = image.transpose(Image.FLIP_LEFT_RIGHT)
              label = label.transpose(Image.FLIP_LEFT_RIGHT)
          
          # place image
          dx = int(rand(0, w-nw))
          dy = int(rand(0, h-nh))
          new_image = Image.new('RGB', (w,h), (128,128,128))
          new_label = Image.new('L', (w,h), (0))
          new_image.paste(image, (dx, dy))
          new_label.paste(label, (dx, dy))
          image = new_image
          label = new_label
  
          # distort image
          hue = rand(-hue, hue)
          sat = rand(1, sat) if rand()<.5 else 1/rand(1, sat)
          val = rand(1, val) if rand()<.5 else 1/rand(1, val)
          x = cv2.cvtColor(np.array(image,np.float32)/255, cv2.COLOR_RGB2HSV)
          x[..., 0] += hue*360
          x[..., 0][x[..., 0]>1] -= 1
          x[..., 0][x[..., 0]<0] += 1
          x[..., 1] *= sat
          x[..., 2] *= val
          x[x[:,:, 0]>360, 0] = 360
          x[:, :, 1:][x[:, :, 1:]>1] = 1
          x[x<0] = 0
          image_data = cv2.cvtColor(x, cv2.COLOR_HSV2RGB)*255
          return image_data,label
  
      def __getitem__(self, index):
          if index == 0:
              shuffle(self.train_lines)
              
          annotation_line = self.train_lines[index]
          name = annotation_line.split()[0]
          # 从文件中读取图像
          jpg = Image.open(os.path.join(os.path.join(self.dataset_path, "Images"), name + ".png"))
          png = Image.open(os.path.join(os.path.join(self.dataset_path, "Labels"), name + ".png"))
  
          if self.random_data:
              jpg, png = self.get_random_data(jpg,png,(int(self.image_size[1]),int(self.image_size[0])))
          else:
              jpg, png = letterbox_image(jpg, png, (int(self.image_size[1]),int(self.image_size[0])))
  
          # 从文件中读取图像
          png = np.array(png)
  
          modify_png               = np.zeros_like(png)
          modify_png[png <= 127.5] = 1
          
          seg_labels = modify_png
          seg_labels = np.eye(self.num_classes+1)[seg_labels.reshape([-1])]
          seg_labels = seg_labels.reshape((int(self.image_size[1]),int(self.image_size[0]),self.num_classes+1))
  
          jpg = np.transpose(np.array(jpg),[2,0,1])/255
  
          return jpg, modify_png, seg_labels
  
  
  # DataLoader中collate_fn使用
  def deeplab_dataset_collate(batch):
      images = []
      pngs = []
      seg_labels = []
      for img, png, labels in batch:
          images.append(img)
          pngs.append(png)
          seg_labels.append(labels)
      images = np.array(images)
      pngs = np.array(pngs)
      seg_labels = np.array(seg_labels)
      return images, pngs, seg_labels
  