Spaces:
Runtime error
Runtime error
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 | |