Image data expansion

# import tensorflow as tf
import Augmentor

Read the original image storage path should also be PNG format, the path should be English.
p = Augmentor.Pipeline("C:\\Users\\ZWSZJC\\Desktop\\leafimage\\timagepng")
Read the mask file storage path
p.ground_truth("C:\\Users\\ZWSZJC\\Desktop\\leafimage\\tlabel")
Output folder will be generated automatically under the path after Augmentor.Pipeline, there is no need to create a new output folder.
The # output folder contains images and annotated images in PNG format

Image rotation: execute according to probability 0.8, maximum left-rotation Angle 15, maximum right-rotation Angle 15
p.rotate(probability=0.8, max_left_rotation=15, max_right_rotation=15)

# Switch between left and right images: execute according to probability 1
p.flip_left_right(probability=1)

Image zoom in and out: perform according to probability 0.8, and the area is 0.85 times of the original picture
p.zoom_random(probability=0.8, percentage_area=0.85)

# Flip up and down according to probability
p.flip_top_bottom(probability=1)

# Counterclockwise random rotation 90 degrees (random probability can be set by yourself), after specifying all operations before running, otherwise only the rotation 90 degrees operation will be performed
p.rotate90(probability=1)

# Rotate the image 90 degrees clockwise randomly (random probability can be set by yourself)
p.rotate270(probability=1)

# perspective deformation - vertical deformation: magnitude is set to (0,1), indicating the degree of deformation
# p.skew_tilt(probability=1,magnitude=1)

Angular deformation: magnitude is set to (0,1), indicating the degree of deformation
# p.skew_corner(probability=1,magnitude=1)

# Elastic distortion, similar to the feeling of regional distortion
# p.random_distortion(probability=1,grid_height=5,grid_width=16,magnitude=8)

# Mistangent transformation
# p.shear(probability=1,max_shear_left=15,max_shear_right=15)

# Random area erasure
# p.r andom_erasing (aim-listed probability = 1, rectangle_area = 0.5)

# Number of data samples for final expansion
p.sample(800)
Copy the code

Remove image background

Set the pixels of the background to 0 by comparing images and annotations

import os
from PIL import Image
import numpy as np

def removeBG(imagePath, maskPath, savePath) :
	img = np.array(Image.open(imagePath))
	mask = np.array(Image.open(maskPath))

	for x in range(img.shape[0) :# Height of the picture
		for y in range(img.shape[1) :# Width of picture
			if mask[x,y] == 0:
				img[x,y] = [0.0.0]

	image = Image.fromarray(img)
	image.save(savePath)


split = ['train'.'val'.'test']
_base_dir = "/ Users/trinasolar/Desktop/deep learning resources/personal data collection/diseases,"
_image_dir = os.path.join(_base_dir, 'Images')
_cat_dir = os.path.join(_base_dir, 'SegmentationClass')
_splits_dir = os.path.join(_base_dir, 'ImageSets')
_new_img_dir = os.path.join(_base_dir, 'ImagesNoBG')
if not os.path.exists(_new_img_dir):
	os.makedirs(_new_img_dir)

for splt in split:
	with open(os.path.join(os.path.join(_splits_dir, splt + '.txt')), "r") as f:
	    lines = f.read().splitlines()

	for ii, line in enumerate(lines):
	    _image = os.path.join(_image_dir, line)
	    _cat = os.path.join(_cat_dir, line)
	    _newImg = os.path.join(_new_img_dir, line)
	    removeBG(_image, _cat, _newImg)
Copy the code

Gets all pixel values of the image

from PIL import Image 
import numpy as np

image = Image.open("/Users/trinasolar/Downloads/SegmentationClass/001.png")
image_arr = np.array(image) # convert to numpy array
print(np.unique(image_arr))
Copy the code

The forecast is merged with the original

import cv2
from PIL import Image
from matplotlib import gridspec
import os
import numpy as np
import matplotlib.pyplot as plt

class Transformer(object) :

    def __init__(self, rootPath, std=[0.229.0.224.0.225], mean=[0.485.0.456.0.406]) :
        self.rootPath = rootPath
        if not os.path.exists(self.rootPath):
            os.makedirs(self.rootPath)
        self.std = std
        self.mean = mean

    # Inverse normalization of images
    def UnNormalize(self, x) :
        x[0] = x[0] * self.std[0] + self.mean[0]
        x[1] = x[1] * self.std[1] + self.mean[1]
        x[2] = x[2].mul(self.std[2]) + self.mean[2]
        img = x.mul(255).byte()
        img = img.numpy().transpose((1.2.0))
        return img

    # merge images
    def maskToImage(self, pred, image, index, isPred=True) :
        if isPred:
            resultPath = os.path.join(self.rootPath, 'pred')
        else:
            resultPath = os.path.join(self.rootPath, 'mask')
        if not os.path.exists(resultPath):
            os.makedirs(resultPath)

        img_path = os.path.join(resultPath, 'result_%d.png' % (index))

        # prediction
        predResult = np.reshape(pred[0], (224.224))
        # result = result.astype(np.float32) * 255.
        predResult = np.clip(predResult, 0.255).astype('uint8')
        predMask = Image.fromarray(predResult)

        # Inverse normalization of images
        x = image[0]
        img = Image.fromarray(self.UnNormalize(x))

        self.vis_segmentation(img, predMask, img_path)

    def label_to_color_image(self, label) :
        colormap = np.array([[0.0.0], [0.128.0], [255.0.0]])

        if np.max(label) >= len(colormap):
            raise ValueError('label value too large.')

        return colormap[label]

    def vis_segmentation(self, image, seg_map, imagePath) :
        """ Enter the image and segmentation mask visualization. """
        plt.figure(figsize=(15.5))
        grid_spec = gridspec.GridSpec(1.4, width_ratios=[6.6.6.1])

        LABEL_NAMES = np.asarray(['background'.'leaf'.'disease'])
        FULL_LABEL_MAP = np.arange(len(LABEL_NAMES)).reshape(len(LABEL_NAMES), 1)
        FULL_COLOR_MAP = self.label_to_color_image(FULL_LABEL_MAP)

        plt.subplot(grid_spec[0])
        plt.imshow(image)
        plt.axis('off')
        plt.title('input image')

        plt.subplot(grid_spec[1])
        seg_image = self.label_to_color_image(seg_map).astype(np.uint8)
        plt.imshow(seg_image)
        plt.axis('off')
        plt.title('segmentation map')

        plt.subplot(grid_spec[2])
        plt.imshow(image)
        plt.imshow(seg_image, alpha=0.7)
        plt.axis('off')
        plt.title('segmentation overlay')

        unique_labels = np.unique(seg_map)
        ax = plt.subplot(grid_spec[3])
        plt.imshow(FULL_COLOR_MAP[unique_labels].astype(np.uint8), interpolation='nearest')
        ax.yaxis.tick_right()
        plt.yticks(range(len(unique_labels)), LABEL_NAMES[unique_labels])
        plt.xticks([], [])
        ax.tick_params(width=0.0)
        plt.grid('off')
        plt.savefig(imagePath)
        # plt.show()
        plt.close('all')

    def vis_segmentation2(self, image, seg_map, imagePath) :
        """ Unified visualization of input images and segmentation masks. """
        seg_image = self.label_to_color_image(seg_map).astype(np.uint8)
        plt.figure()
        plt.imshow(image)
        plt.imshow(seg_image, alpha=0.6)
        plt.axis('off')
        plt.savefig(imagePath)
        # plt.show()
        plt.close('all')
Copy the code

Image preprocessor function (PyTorch)

import torch
import random
import numpy as np

from PIL import Image, ImageOps, ImageFilter

class Normalize(object) :
    """Normalize a tensor image with mean and standard deviation. Args: mean (tuple): means for each channel. std (tuple): standard deviations for each channel. """
    def __init__(self, mean=(0..0..0.), std=(1..1..1.)) :
        self.mean = mean
        self.std = std

    def __call__(self, sample) :
        img = sample['image']
        mask = sample['label']
        img = np.array(img).astype(np.float32)
        mask = np.array(mask).astype(np.float32)
        img /= 255.0
        img -= self.mean
        img /= self.std

        return {'image': img,
                'label': mask}


class ToTensor(object) :
    """Convert ndarrays in sample to Tensors."""

    def __call__(self, sample) :
        # swap color axis because
        # numpy image: H x W x C
        # torch image: C X H X W
        img = sample['image']
        mask = sample['label']
        img = np.array(img).astype(np.float32).transpose((2.0.1))
        mask = np.array(mask).astype(np.float32)

        img = torch.from_numpy(img).float()
        mask = torch.from_numpy(mask).float(a)return {'image': img,
                'label': mask}


class RandomHorizontalFlip(object) :
    def __call__(self, sample) :
        img = sample['image']
        mask = sample['label']
        if random.random() < 0.5:
            img = img.transpose(Image.FLIP_LEFT_RIGHT)
            mask = mask.transpose(Image.FLIP_LEFT_RIGHT)

        return {'image': img,
                'label': mask}


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

    def __call__(self, sample) :
        img = sample['image']
        mask = sample['label']
        rotate_degree = random.uniform(-1*self.degree, self.degree)
        img = img.rotate(rotate_degree, Image.BILINEAR)
        mask = mask.rotate(rotate_degree, Image.NEAREST)

        return {'image': img,
                'label': mask}


class RandomGaussianBlur(object) :
    def __call__(self, sample) :
        img = sample['image']
        mask = sample['label']
        if random.random() < 0.5:
            img = img.filter(ImageFilter.GaussianBlur(
                radius=random.random()))

        return {'image': img,
                'label': mask}


class RandomScaleCrop(object) :
    def __init__(self, base_size, crop_size, fill=0) :
        self.base_size = base_size
        self.crop_size = crop_size
        self.fill = fill

    def __call__(self, sample) :
        img = sample['image']
        mask = sample['label']
        # random scale (short edge)
        short_size = random.randint(int(self.base_size * 0.5), int(self.base_size * 2.0))
        w, h = img.size
        if h > w:
            ow = short_size
            oh = int(1.0 * h * ow / w)
        else:
            oh = short_size
            ow = int(1.0 * w * oh / h)
        img = img.resize((ow, oh), Image.BILINEAR)
        mask = mask.resize((ow, oh), Image.NEAREST)
        # pad crop
        if short_size < self.crop_size:
            padh = self.crop_size - oh if oh < self.crop_size else 0
            padw = self.crop_size - ow if ow < self.crop_size else 0
            img = ImageOps.expand(img, border=(0.0, padw, padh), fill=0)
            mask = ImageOps.expand(mask, border=(0.0, padw, padh), fill=self.fill)
        # random crop crop_size
        w, h = img.size
        x1 = random.randint(0, w - self.crop_size)
        y1 = random.randint(0, h - self.crop_size)
        img = img.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size))
        mask = mask.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size))

        return {'image': img,
                'label': mask}


class FixScaleCrop(object) :
    def __init__(self, crop_size) :
        self.crop_size = crop_size

    def __call__(self, sample) :
        img = sample['image']
        mask = sample['label']
        w, h = img.size
        if w > h:
            oh = self.crop_size
            ow = int(1.0 * w * oh / h)
        else:
            ow = self.crop_size
            oh = int(1.0 * h * ow / w)
        img = img.resize((ow, oh), Image.BILINEAR)
        mask = mask.resize((ow, oh), Image.NEAREST)
        # center crop
        w, h = img.size
        x1 = int(round((w - self.crop_size) / 2.))
        y1 = int(round((h - self.crop_size) / 2.))
        img = img.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size))
        mask = mask.crop((x1, y1, x1 + self.crop_size, y1 + self.crop_size))

        return {'image': img,
                'label': mask}

class FixedResize(object) :
    def __init__(self, size) :
        self.size = (size, size)  # size: (h, w)

    def __call__(self, sample) :
        img = sample['image']
        mask = sample['label']

        assert img.size == mask.size

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

        return {'image': img,
                'label': mask}
Copy the code

Calculate category weights

import os
from tqdm import tqdm
import numpy as np
from dataloaders.dataPath import Path

def calculate_weigths_labels(dataset, dataloader, num_classes) :
    # Create an instance from the data loader
    z = np.zeros((num_classes,))
    # Initialize tqdm
    tqdm_batch = tqdm(dataloader)
    print('Calculating classes weights')
    for sample in tqdm_batch:
        y = sample['label']
        y = y.detach().cpu().numpy()
        mask = (y >= 0) & (y < num_classes)
        labels = y[mask].astype(np.uint8)
        count_l = np.bincount(labels, minlength=num_classes)
        z += count_l
    tqdm_batch.close()
    total_frequency = np.sum(z)
    class_weights = []
    for frequency in z:
        class_weight = 1 / (np.log(1.02 + (frequency / total_frequency)))
        class_weights.append(class_weight)
    ret = np.array(class_weights)
    classes_weights_path = os.path.join(Path.db_root_dir(dataset), dataset+'_classes_weights.npy')
    np.save(classes_weights_path, ret)

    return ret
Copy the code

Generate data set document (TXT)

def getAllImageNames() :
    face_path = "E:\\myself\\papercode\\1. Dataset \\1. Personal Data Set \\disease-nobg\\Images"

    fileTrain = open("E:\\myself\\papercode\\1. Dataset \\1. Personal Data set \\disease-nobg\\ImageSets\\train.txt".'w')
    fileVal = open("E:\\myself\\papercode\\1. Dataset \\1. Personal Data set \\disease-nobg\\ImageSets\\val.txt".'w')
    for dirname, dirnames, filenames in os.walk(face_path):
        list = filenames
        random.shuffle(list)
        total = len(list)
        trainNum = int(total * 0.9)
        train = list[:trainNum]
        val = list[trainNum:]

        print(len(train))
        print(len(val))

        for filename in train:
            fileTrain.write(filename)
            fileTrain.write("\n")

        for filename in val:
            fileVal.write(filename)
            fileVal.write("\n")

    fileVal.close()
    fileTrain.close()
Copy the code

Check the annotation file for errors

#! /usr/bin/python
# -*- coding: UTF-8 -*-
import argparse
import time
import os
from PIL import Image
from matplotlib import gridspec
import numpy as np
import matplotlib.pyplot as plt

def main() :

    # loading images
    imageDir = '/ Users/trinasolar/Desktop/deep learning resources/personal data collection/diseases/Images'
    maskDir = '/ Users/trinasolar/Desktop/deep learning resources/personal data collection/diseases/SegmentationClass'
    resultDir = '/ Users/trinasolar/Desktop/deep learning resources/personal data collection/diseases/mergeResult'
    if not os.path.exists(resultDir):
        os.makedirs(resultDir)

    onlyPredMaskPath = os.path.join(resultDir, 'onlymask')
    if not os.path.exists(onlyPredMaskPath):
        os.makedirs(onlyPredMaskPath)

    # assert 1==2, '1 does not equal 2'
    for root, dirs, files in os.walk(maskDir):
        for f in files:
            imagePath = os.path.join(imageDir, f)
            maskPath = os.path.join(maskDir, f)
            assert os.path.exists(imagePath), '%s image does not exist ' % imagePath
            _img = Image.open(imagePath).convert('RGB')
            _target = Image.open(maskPath)

            resultPath = os.path.join(resultDir, f)

            # display mask
            onlyMaskPath = os.path.join(onlyPredMaskPath, f)
            seg_mask = label_to_color_image(_target).astype(np.uint8)
            seg_image = Image.fromarray(seg_mask)
            seg_image.save(onlyMaskPath)

            vis_segmentation(_img, _target, resultPath)


def label_to_color_image(label) :
    colormap = np.array([[0.0.0], [0.128.0], [255.0.0]])

    if np.max(label) >= len(colormap):
        raise ValueError('label value too large.')

    return colormap[label]

def vis_segmentation(image, seg_map, imagePath) :
    """ Enter the image and segmentation mask visualization. """
    plt.figure(figsize=(15.5))
    grid_spec = gridspec.GridSpec(1.4, width_ratios=[6.6.6.1])

    LABEL_NAMES = np.asarray(['background'.'leaf'.'disease'])
    FULL_LABEL_MAP = np.arange(len(LABEL_NAMES)).reshape(len(LABEL_NAMES), 1)
    FULL_COLOR_MAP = label_to_color_image(FULL_LABEL_MAP)

    plt.subplot(grid_spec[0])
    plt.imshow(image)
    plt.axis('off')
    plt.title('input image')

    plt.subplot(grid_spec[1])
    seg_image = label_to_color_image(seg_map).astype(np.uint8)
    plt.imshow(seg_image)
    plt.axis('off')
    plt.title('segmentation map')

    plt.subplot(grid_spec[2])
    plt.imshow(image)
    plt.imshow(seg_image, alpha=0.3)
    plt.axis('off')
    plt.title('segmentation overlay')

    unique_labels = np.unique(seg_map)
    ax = plt.subplot(grid_spec[3])
    plt.imshow(FULL_COLOR_MAP[unique_labels].astype(np.uint8), interpolation='nearest')
    ax.yaxis.tick_right()
    plt.yticks(range(len(unique_labels)), LABEL_NAMES[unique_labels])
    plt.xticks([], [])
    ax.tick_params(width=0.0)
    plt.grid('off')
    plt.savefig(imagePath)
    Manually clear images in memory
    plt.close('all')
    # plt.show()


if __name__ == "__main__":
    main()
Copy the code