File size: 4,674 Bytes
0e4f45d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import random
import math
import numpy as np
from PIL import Image, ImageFilter
from scipy.ndimage import binary_erosion, binary_dilation
import torchvision.transforms.functional as TF
from torchvision.transforms import RandomResizedCrop

random_thres = 0.8


def random_adjust_color(img, verbose=False):

    if random.random() < random_thres:
        brightness_factor = random.uniform(0.1, 1.2)
        img = TF.adjust_brightness(img, brightness_factor)
        if verbose:
            print('Brightness:', brightness_factor)

    if random.random() < random_thres:
        contrast_factor = random.uniform(0.2, 1.8)
        img = TF.adjust_contrast(img, contrast_factor)
        if verbose:
            print('Contrast:', contrast_factor)

    if random.random() < random_thres:
        # hue_factor = random.uniform(-0.1, 0.1)
        hue_factor = 0.1
        img = TF.adjust_hue(img, hue_factor)
        if verbose:
            print('Hue:', hue_factor)

    return img

def random_affine_transformation(img, mask, label, verbose=False):
    
    if random.random() < random_thres:
        degrees = random.uniform(-20, 20)
        translate_h = random.uniform(-0.2, 0.2)
        translate_v = random.uniform(-0.2, 0.2)
        scale = random.uniform(0.7, 1.3)
        shear = random.uniform(-20, 20)
        resample = TF.InterpolationMode.BICUBIC

        img = TF.affine(img, degrees, (translate_h, translate_v), scale, shear, resample)
        if mask:
            mask = TF.affine(mask, degrees, (translate_h, translate_v), scale, shear, resample)
        label = TF.affine(label, degrees, (translate_h, translate_v), scale, shear, resample)

        if verbose:
            print('Affine degrees: %.1f, T_h: %.1f, T_v: %.1f, Scale: %.1f, Shear: %.1f' % \
                (degrees, translate_h, translate_v, scale, shear))

    if random.random() < 0.5:
        
        img = TF.hflip(img)
        if mask:
            mask = TF.hflip(mask)
        label = TF.hflip(label)

        if verbose:
            print('Horizontal flip')

    if mask:
        return img, mask, label
    else:
        return img, label

def random_mask_perturbation(mask, verbose=False):

    degrees = random.uniform(-10, 10)
    translate_h = random.uniform(-0.1, 0.1)
    translate_v = random.uniform(-0.1, 0.1)
    scale = random.uniform(0.8, 1.2)
    shear = random.uniform(-10, 10)
    resample = TF.InterpolationMode.BICUBIC

    mask = TF.affine(mask, degrees, (translate_h, translate_v), scale, shear, resample)

    if verbose:
        print('Mask pertubation degrees: %.1f, T_h: %.1f, T_v: %.1f, Scale: %.1f, Shear: %.1f' % \
            (degrees, translate_h, translate_v, scale, shear))

    morphologic_times = int(random.random() * 10)
    morphologic_thres = random.random()
    filter_size = 7
    for i in range(morphologic_times):
        if random.random() < morphologic_thres:
            mask = mask.filter(ImageFilter.MinFilter(filter_size))
            if verbose:
                print(i, 'erossion')
        else:
            mask = mask.filter(ImageFilter.MaxFilter(filter_size))
            if verbose:
                print(i, 'dilation')

    mask = mask.convert('1')

    return mask

def random_resized_crop(img, mask, label, size, verbose=False):

    scale = (0.08, 1.0)
    ratio = (0.75, 1.33333333)

    sample_flag = False

    for attempt in range(10):
        area = img.size[0] * img.size[1]
        target_area = random.uniform(*scale) * area
        aspect_ratio = random.uniform(*ratio)

        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]:
            y = random.randint(0, img.size[1] - h)
            x = random.randint(0, img.size[0] - w)
            sample_flag = True
            break

    # Fallback
    if not sample_flag:
        w = min(img.size[0], img.size[1])
        y = (img.size[1] - w) // 2
        x = (img.size[0] - w) // 2
        h = w

    img = TF.resized_crop(img, y, x, h, w, size, TF.InterpolationMode.BICUBIC)
    if mask:
        mask = TF.resized_crop(mask, y, x, h, w, size, TF.InterpolationMode.BICUBIC)
    label = TF.resized_crop(label, y, x, h, w, size, TF.InterpolationMode.BICUBIC)

    if verbose:
        print('x: %d, y: %d, w: %d, h: %d' % (x, y, w, h))

    if mask:
        return img, mask, label
    else:
        return img, label

def imagenet_normalization(img_tensor):

    mean = [0.485, 0.456, 0.406]
    std = [0.229, 0.224, 0.225]
    img_tensor = TF.normalize(img_tensor, mean, std)

    return img_tensor