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 | |