File size: 5,576 Bytes
d4b77ac
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
153
154
155
156
157
158
159
import random
import numpy as np
import cv2

def random_bbox(img_height, img_width, vertical_margin, horizontal_margin, mask_height, mask_width):
    maxt = img_height - vertical_margin - mask_height
    maxl = img_width - horizontal_margin - mask_width

    t = random.randint(vertical_margin, maxt)
    l = random.randint(horizontal_margin, maxl)
    h = random.randint(mask_height // 2, mask_height)
    w = random.randint(mask_width // 2, mask_width)
    return (t, l, h, w)  # 产生随机块状box,这个box后面会发展成为mask


def mid_bbox_mask(img_height, img_width, mask_height, mask_width):
    def npmask(bbox, height, width):
        mask = np.zeros((height, width, 1), np.float32)
        mask[bbox[0]: bbox[0] + bbox[2], bbox[1]: bbox[1] + bbox[3], :] = 255.
        return mask

    bbox = (img_height * 3 // 8, img_width * 3 // 8, mask_height, mask_width)
    mask = npmask(bbox, img_height, img_width)

    return mask


def bbox2mask(img_height, img_width, max_delta_height, max_delta_width, bbox):
    """Generate mask tensor from bbox.

    Args:
        bbox: configuration tuple, (top, left, height, width)
        config: Config should have configuration including IMG_SHAPES,
            MAX_DELTA_HEIGHT, MAX_DELTA_WIDTH.

    Returns:
        tf.Tensor: output with shape [B, 1, H, W]

    """

    def npmask(bbox, height, width, delta_h, delta_w):
        mask = np.zeros((height, width, 1), np.float32)
        h = np.random.randint(delta_h // 2 + 1)  # 防止有0产生
        w = np.random.randint(delta_w // 2 + 1)
        mask[bbox[0] + h: bbox[0] + bbox[2] - h, bbox[1] + w: bbox[1] + bbox[3] - w, :] = 255.  # height_true = height - 2 * h, width_true = width - 2 * w
        return mask

    mask = npmask(bbox, img_height, img_width,
                  max_delta_height,
                  max_delta_width)

    return mask


def matrix2bbox(img_height, img_width, mask_height, mask_width, row, column):
    """Generate masks with a matrix form
    @param img_height
    @param img_width
    @param mask_height
    @param mask_width
    @param row: number of blocks in row
    @param column: number of blocks in column
    @return mbbox: multiple bboxes in (y, h, h, w) manner
    """
    assert img_height - column * mask_height > img_height // 2, "Too many masks across a column"
    assert img_width - row * mask_width > img_width // 2, "Too many masks across a row"

    interval_height = (img_height - column * mask_height) // (column + 1)
    interval_width = (img_width - row * mask_width) // (row + 1)

    mbbox = []
    for i in range(row):
        for j in range(column):
            y = interval_height * (j+1) + j * mask_height
            x = interval_width * (i+1) + i * mask_width
            mbbox.append((y, x, mask_height, mask_width))
    return mbbox


def mbbox2masks(img_height, img_width, mbbox):

    def npmask(mbbox, height, width):
        mask = np.zeros((height, width, 1), np.float32)
        for bbox in mbbox:
            mask[bbox[0]: bbox[0] + bbox[2], bbox[1]: bbox[1] + bbox[3], :] = 255.  # height_true = height - 2 * h, width_true = width - 2 * w
        return mask

    mask = npmask(mbbox, img_height, img_width)

    return mask


def draw_line(mask, startX, startY, angle, length, brushWidth):
    """assume the size of mask is (H,W,1)
    """
    assert len(mask.shape) == 2 or mask.shape[2] == 1, "The channel of mask doesn't fit the opencv format"
    offsetX = int(np.round(length * np.cos(angle)))
    offsetY = int(np.round(length * np.sin(angle)))
    endX = startX + offsetX
    endY = startY + offsetY
    if endX > mask.shape[1]:
        endX = mask.shape[1]
    if endY > mask.shape[0]:
        endY = mask.shape[0]
    mask_processed = cv2.line(mask, (startX, startY), (endX, endY), 255, brushWidth)
    return mask_processed, endX, endY


def draw_circle(mask, circle_x, circle_y, brushWidth):
    radius = brushWidth // 2
    assert len(mask.shape) == 2 or mask.shape[2] == 1, "The channel of mask doesn't fit the opencv format"
    mask_processed = cv2.circle(mask, (circle_x, circle_y), radius, 255)
    return mask_processed


def freeFormMask(img_height, img_width, maxVertex, maxLength, maxBrushWidth, maxAngle):
    mask = np.zeros((img_height, img_width))
    numVertex = random.randint(1, maxVertex)
    startX = random.randint(10, img_width)
    startY = random.randint(10, img_height)
    brushWidth = random.randint(10, maxBrushWidth)
    for i in range(numVertex):
        angle = random.uniform(0, maxAngle)
        if i % 2 == 0:
            angle = 2 * np.pi - angle
        length = random.randint(10, maxLength)
        mask, endX, endY = draw_line(mask, startX, startY, angle, length, brushWidth)
        startX = startX + int(length * np.sin(angle))
        startY = startY + int(length * np.cos(angle))
        mask = draw_circle(mask, endX, endY, brushWidth)

    if random.random() < 0.5:
        mask = np.fliplr(mask)
    if random.random() < 0.5:
        mask = np.flipud(mask)

    if len(mask.shape) == 2:
        mask = mask[:, :, np.newaxis]

    return mask


if __name__ == "__main__":
    # for stationary mask generation
    # stationary_mask_generator(240, 480, 50, 120)

    # for free-form mask generation
    # mask = freeFormMask(240, 480, 30, 50, 20, np.pi)
    # cv2.imwrite('mask.png', mask)

    # for matrix mask generation
    # img_height, img_width = 240, 480
    # masks = matrix2bbox(240, 480, 20, 20, 5, 4)
    # matrixMask = mbbox2masks(img_height, img_width, masks)
    # cv2.imwrite('matrixMask.png', matrixMask)
    pass