keras使用albumentations自定义标准数据增强器

图像分类

import os
import cv2
import numpy as np
import sklearn
import albumentations
from albumentations import (Blur,MotionBlur,MedianBlur,GaussianBlur,GlassBlur,Flip,ShiftScaleRotate,
                            GridDistortion,ElasticTransform,RandomResizedCrop,
                            HueSaturationValue,Transpose,RandomBrightnessContrast,CLAHE,
                            CoarseDropout,Cutout,Normalize,ToFloat,OneOf,Compose)

class MyDataGenerator(keras.utils.Sequence):

    def __init__(self, image_names, labels, classes, root_directory='',image_size=(224,224),
                 batch_size=64,shuffle=True,augment=True,label_smoothing=False,mix_up=False):
        self.image_filenames = image_names
        self.labels = labels
        self.classes = classes
        self.root_directory = root_directory
        self.batch_size = batch_size
        self.image_size = image_size
        self.shuffle = shuffle
        self.is_label_smoothing = label_smoothing 
        self.is_mix_up = mix_up
        self.augment = augment
        if self.augment:
            self.generator = Compose([ 
#                                         OneOf([
#                                             MotionBlur(blur_limit=3,p=0.5),
#                                              MedianBlur(blur_limit=3, p=0.5),
#                                 Blur(blur_limit=3, p=0.5),GaussianBlur(blur_limit=3,p=0.5)]),
                                  Flip(p=0.5),
#                                 Transpose(p=0.5), 
                        #RandomResizedCrop(height=self.image_size[0],width=self.image_size[1],
#                                              scale=(0.8, 1.0), ratio=#(0.8, 1.2),p=0.5),                         
                ShiftScaleRotate(shift_limit=0.2,scale_limit=0.2,rotate_limit=45,p=0.5),
                        RandomBrightnessContrast(brightness_limit=0.2, contrast_limit=0.2,p=0.5),
#                                 HueSaturationValue(hue_shift_limit=20, sat_shift_limit=30, val_shift_limit=20,p=1.0),
#                                 CLAHE(clip_limit=4.0,tile_grid_size=(8, 8),p=0.5),
#                                 GridDistortion(num_steps=5,distort_limit=0.3,p=0.5),
#                                 ElasticTransform(alpha=1,sigma=50,alpha_affine=50,p=0.5),
                                 Cutout(num_holes=8,max_h_size=8,max_w_size=8, fill_value=0,p=0.5),
                                               Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), 
                          max_pixel_value=255.0, p=1.0)])
        else:
            self.generator = Compose([                Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), 
                          max_pixel_value=255.0, p=1.0)])
        count = 0
        for i in self.image_filenames:
            if os.path.exists(self.root_directory+i):
                count+=1
        print('Found {} validated image filenames belonging to {} classes.'
              .format(count,len(np.unique(self.labels)))

    def __len__(self):
        return int(np.ceil(len(self.image_filenames) / float(self.batch_size)))
    
    def on_epoch_end(self):
        if self.shuffle:
            self.image_filenames, self.labels = sklearn.utils.shuffle(self.image_filenames,self.labels)

    def __getitem__(self,index):
        batch_x = self.image_filenames[index*self.batch_size:(index+1)*self.batch_size]
        batch_y = self.labels[index*self.batch_size:(index+1)*self.batch_size]
        new_images = []
        new_labels = []
        
        for image_name,label in zip(batch_x,batch_y):
            image = cv2.imread(os.path.join(self.root_directory,image_name))
            image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
            image = cv2.resize(image,(self.image_size[1],self.image_size[0]))
            image = self.generator(image=image)['image']
            new_images.append(image)
            new_labels.append(label)
        new_images,new_labels = np.array(new_images), np.array(new_labels)
        
        new_labels = keras.utils.to_categorical(new_labels,num_classes=self.classes) #one-hot
       
        if self.is_mix_up:
            alpha = 0.2
            λ = np.random.beta(alpha,alpha,new_images.shape[0])
            λ1 = np.reshape(λ, (new_images.shape[0],1,1,1))
            λ2 = np.reshape(λ, (new_images.shape[0],1))
            index = np.random.permutation(new_images.shape[0])
            image1, label1 = new_images[index],new_labels[index]
            image2, label2 = new_images, new_labels
            new_images = λ1*image1 + (1 - λ1) * image2
            new_labels = λ2*label1 + (1 - λ2) * label2
        
        if self.is_label_smoothing:
            factor = 0.1
            new_labels *= (1 - factor)
            new_labels += (factor / self.classes)
            
        return new_images,new_labels 

    
class TestDataGenerator(keras.utils.Sequence):

    def __init__(self, image_names, root_directory='',image_size=(224,224), batch_size=64):
        self.image_filenames = image_names
        self.root_directory = root_directory
        self.batch_size = batch_size
        self.image_size = image_size
        self.generator = Compose([ToFloat(max_value=255.0,p=1.0)])
        count = 0
        for i in self.image_filenames:
            if os.path.exists(self.root_directory+i):
                count+=1
        print('Found {} validated image filenames.'.format(count))

    def __len__(self):
        return int(np.ceil(len(self.image_filenames) / float(self.batch_size)))
    
    def __getitem__(self,index):
        batch_x = self.image_filenames[index*self.batch_size:(index+1)*self.batch_size]
        new_images = []
        for image_name in batch_x:
            image = cv2.imread(os.path.join(self.root_directory,image_name))
            image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
            image = cv2.resize(image,(self.image_size[1],self.image_size[0]))
            img = self.generator(image=image)['image']
            new_images.append(img)
        new_images = np.array(new_images)
        return new_images 
trainDataGenerator = MyDataGenerator(image_names=train_x,labels=train_y,batch_size=batch_size,
                                image_size=(height,width),classes=len(classes),augment=True,
                                label_smoothing=True,mix_up=False,
                                root_directory='../input/images/')

validDataGenerator = MyDataGenerator(image_names=valid_x,labels=valid_y,batch_size=batch_size,
                                image_size=(height,width),classes=len(classes),augment=False,
                                root_directory='../input/images/')
testDataGenerator = TestDataGenerator(image_names=test_x,
                                batch_size=batch_size,
                                image_size=image_size,
                                root_directory='../input/images/')

目标检测

以EfficientNet(源代码: https://github.com/xuannianz/EfficientDet),coco格式输入数据为例

from albumentations import (Blur,MotionBlur,MedianBlur,GaussianBlur,GlassBlur,Flip,ShiftScaleRotate,
                            GridDistortion,ElasticTransform,RandomSizedCrop,RandomResizedCrop,
                            RandomSizedBBoxSafeCrop,RandomScale,Normalize,
                            HueSaturationValue,Transpose,RandomBrightnessContrast,CLAHE,Resize,
                            CoarseDropout,Cutout,Normalize,ToFloat,OneOf,Compose)
#Generator是EfficientNet源码里的已继承Sequence的类
class CocoGenerator(Generator):
    def __init__(self, data_dir, set_name, img_size=(224,224), classes=1024, augment=False, **kwargs):                                    
        self.coco = COCO('/input/instances_Images.json') #读取数据               
        self.image_ids = self.coco.getImgIds()
        self.load_classes()
        self.img_size = img_size
        self.data_dir = data_dir
        self.classes = classes
        if augment:
            self.generator = Compose([
                OneOf([Resize(self.img_size[0], self.img_size[1]), 
               RandomResizedCrop(height=self.img_size[0],width=self.img_size[1],scale=(0.8,1.2),ratio=(0.8,1.2))],p=1.0),
                OneOf([MotionBlur(blur_limit=3,p=0.5), MedianBlur(blur_limit=3, p=0.5),Blur(blur_limit=3, p=0.5),GaussianBlur(blur_limit=3,p=0.5)]),
                Flip(p=0.5),
                Transpose(p=0.5),                        
                ShiftScaleRotate(shift_limit=0.2,scale_limit=0.2,rotate_limit=45,p=1.0),
                RandomBrightnessContrast(brightness_limit=0.4, contrast_limit=0.4,p=1.0),
#                     HueSaturationValue(hue_shift_limit=20, sat_shift_limit=30, val_shift_limit=20,p=1.0),
                CLAHE(clip_limit=4.0,tile_grid_size=(8, 8),p=1.0),
                Cutout(num_holes=8,max_h_size=8,max_w_size=8, fill_value=0,p=0.5),
                Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), 
                          max_pixel_value=255.0, p=1.0)],
                bbox_params={'format':'pascal_voc','label_fields':['labels']})
        else:
            self.generator = Compose([
                Resize(self.img_size[0], self.img_size[1],p=1.0),                
                CLAHE(clip_limit=4.0,tile_grid_size=(8, 8),p=1.0),
                Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225), 
                          max_pixel_value=255.0, p=1.0)],
                bbox_params={'format': 'pascal_voc','label_fields':['labels']})#load_annotations已经将数据从coco格式变为pascal_voc格式
        
        super(CocoGenerator, self).__init__(**kwargs)
    def __getitem__(self, index):
        """
        Keras sequence method for generating batches.
        """
        group = self.groups[index]
        inputs, targets = self.compute_inputs_targets(group)

        return inputs, targets
    
    def compute_inputs_targets(self, group, debug=False):
        """
        Compute inputs and target outputs for the network.
        """

        # load images and annotations
        # list
        image_group = self.load_image_group(group)
        annotations_group = self.load_annotations_group(group)
        
        # check validity of annotations
        image_group, annotations_group = self.filter_annotations(image_group, annotations_group, group)       

        #         print(annotations_group)
        new_image_group = []
        new_annotations_group = []
        for image, annotations in zip(image_group, annotations_group):
            label, bbox = annotations['labels'],annotations['bboxes']
#             print(bbox,label)
            aug = self.generator(image=image,bboxes=bbox,
                                                     labels=label)
            image,bbox,label = aug['image'],aug['bboxes'],aug['labels']
            if len(bbox) == 0:
                continue
            new_image_group.append(np.array(image))
            bbox = np.array(bbox)
            new_annotations_group.append({'labels': np.array(label), 
                                          'bboxes': np.array(bbox)})
        image_group = new_image_group
        annotations_group = new_annotations_group
#         print(annotations_group)

    
        # check validity of annotations
        image_group, annotations_group = self.clip_transformed_annotations(image_group, annotations_group, group)
        


        assert len(image_group) != 0
        assert len(image_group) == len(annotations_group)

        if self.detect_quadrangle:
            # compute alphas and ratio for targets
            self.compute_alphas_and_ratios(annotations_group)

        # compute network inputs
        inputs = self.compute_inputs(image_group, annotations_group)

        # compute network targets
        targets = self.compute_targets(image_group, annotations_group)

        if debug:
            return inputs, targets, annotations_group

        return inputs, targets
    
    def load_classes(self): 
        categories = self.coco.loadCats(self.coco.getCatIds())
        categories.sort(key=lambda x: x['id'])

        self.classes = {}
        self.coco_labels = {}
        self.coco_labels_inverse = {}
        for c in categories:
            self.coco_labels[len(self.classes)] = c['id']
            self.coco_labels_inverse[c['id']] = len(self.classes)
            self.classes[c['name']] = len(self.classes)

        self.labels = {}
        for key, value in self.classes.items():
            self.labels[value] = key
            

    def size(self):
        return len(self.image_ids)

    def num_classes(self):
        return self.classes

    def has_label(self, label):
        return label in self.labels

    def has_name(self, name):
        return name in self.classes

    def name_to_label(self, name):
        return self.classes[name]

    def label_to_name(self, label):
        return self.labels[label]

    def coco_label_to_label(self, coco_label):
        return self.coco_labels_inverse[coco_label]

    def coco_label_to_name(self, coco_label):
        return self.label_to_name(self.coco_label_to_label(coco_label))

    def label_to_coco_label(self, label):
        return self.coco_labels[label]

    def image_aspect_ratio(self, image_index):
        image = self.coco.loadImgs(self.image_ids[image_index])[0]
        return float(image['width']) / float(image['height'])

    def load_image(self, image_index):        
        image_info = self.coco.loadImgs(self.image_ids[image_index])[0]        
        path = os.path.join(self.data_dir, image_info['file_name'])        
        image = cv2.imread(path)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        
#         image = preprocess_image(image)
        
        return image

    def load_annotations(self, image_index):
        annotations_ids = self.coco.getAnnIds(imgIds=self.image_ids[image_index], iscrowd=False)
        annotations = {'labels': np.empty((0,), dtype=np.float32), 'bboxes': np.empty((0, 4), dtype=np.float32)}

        if len(annotations_ids) == 0:
            return annotations

        coco_annotations = self.coco.loadAnns(annotations_ids)
        for idx, a in enumerate(coco_annotations):
            # some annotations have basically no width / height, skip them
            if a['bbox'][2] < 1 or a['bbox'][3] < 1:
                continue

            annotations['labels'] = np.concatenate(
                [annotations['labels'], [a['category_id'] - 1]], axis=0)
            annotations['bboxes'] = np.concatenate([annotations['bboxes'], [[
                a['bbox'][0],
                a['bbox'][1],
                a['bbox'][0] + a['bbox'][2],
                a['bbox'][1] + a['bbox'][3],
            ]]], axis=0)
        return annotations    

语义分割(待写)


你可能感兴趣的:(tensorflow)