def _generate_trapezium_mask(point, image, size, p, random, OorA, lean, angle=0): if OorA < 0.5: B = int(math.sqrt(size * 2 / p / (lean + 1))) H = int(B * p) d = int(B * (1 - lean) / 2) else: B = int(math.sqrt(size * 2 * p / (lean + 1))) H = int(B / p) d = int(B * (1 - lean) / 2) if image[1] - point[1] < H: raise ArithmeticError('cannot fit shape to image') if image[0] - point[0] < B: raise ArithmeticError('cannot fit shape to image') p1r = point[0] p2r = point[0] + B * math.cos(angle) p3r = point[0] + B * math.cos(angle) - H * math.sin(angle) - d * math.cos( angle) p4r = point[0] - H * math.sin(angle) + d * math.cos(angle) p1c = point[1] p2c = point[1] + B * math.sin(angle) p3c = point[1] + B * math.sin(angle) + H * math.cos(angle) - d * math.sin( angle) p4c = point[1] + H * math.cos(angle) + d * math.sin(angle) # 判断旋转后是否在边框内 if p1r < 0 or p2r < 0 or p3r < 0 or p4r < 0 or p1c < 0 or p2c < 0 or p3c < 0 or p4c < 0: raise ArithmeticError('cannot fit shape to image') if p1r > image[0] or p2r > image[0] or p3r > image[0] or p4r > image[ 0] or p1c > image[1] or p2c > image[1] or p3c > image[ 1] or p4c > image[1]: raise ArithmeticError('cannot fit shape to image') trapezium = draw_polygon([ p1r, p2r, p3r, p4r, ], [ p1c, p2c, p3c, p4c, ]) location = [(p1r + p3r + d * math.cos(angle)) / 2, (p1c + p3c + d * math.sin(angle)) / 2] label = ('trapezium', (p1r, p3r + d * math.cos(angle)), (p1c, p3c + d * math.sin(angle)), (location[0], location[1])) return trapezium, label
def _rasterise_convex(ex, ey, canvas, fill_value, xmin, ymin, scale_x, dimscale_x, scale_y, dimscale_y): ex = np.asarray(ex) * scale_x * dimscale_x ex = np.minimum(np.maximum(0, ex - xmin), canvas.shape[1] - 1) ey = np.asarray(ey) * scale_y * dimscale_y ey = np.minimum(np.maximum(0, ey - ymin), canvas.shape[0] - 1) rr, cc = draw_polygon(ey, ex, canvas.shape) canvas[rr, cc] = fill_value return canvas
def _generate_trapezium_mask(point, image, shape, random, angle=0): available_width = min(image[1] - point[1], shape[1]) if available_width < shape[0]: raise ArithmeticError('cannot fit shape to image') available_height = min(image[0] - point[0], shape[1]) if available_height < shape[0]: raise ArithmeticError('cannot fit shape to image') # Pick random widths and heights. r = random.randint(shape[0], available_height + 1) c = random.randint(shape[0], available_width + 1) d1 = random.randint(-r, available_width + 1) d2 = random.randint(-r, available_width + 1) p1r = point[0] p2r = point[0] + r * math.cos(angle) - d1 * math.sin(angle) p3r = point[0] + r * math.cos(angle) + c * math.sin(angle) + d2 * math.sin( angle) p4r = point[0] + c * math.sin(angle) p1c = point[1] p2c = point[1] - r * math.sin(angle) - d1 * math.cos(angle) p3c = point[1] + c * math.cos(angle) - r * math.sin(angle) + d2 * math.cos( angle) p4c = point[1] + c * math.cos(angle) # 判断旋转后是否在边框内 if p1r < 0 or p2r < 0 or p3r < 0 or p4r < 0 or p1c < 0 or p2c < 0 or p3c < 0 or p4c < 0: raise ArithmeticError('cannot fit shape to image') if p1r > image[0] or p2r > image[0] or p3r > image[0] or p4r > image[ 0] or p1c > image[1] or p2c > image[1] or p3c > image[ 1] or p4c > image[1]: raise ArithmeticError('cannot fit shape to image') #判断梯形下边两点不接触 if (d1 + d2) <= -r: raise ArithmeticError('cannot fit shape to image') trapezium = draw_polygon([ p1r, p2r, p3r, p4r, ], [ p1c, p2c, p3c, p4c, ]) label = ('trapezium', ((point[0], point[0] + r * math.cos(angle) + c * math.sin(angle) + d2 * math.sin(angle)), (point[1] - r * math.sin(angle) - d1 * math.cos(angle), point[1] + c * math.cos(angle)))) return trapezium, label
def _generate_rectangle_mask(point, image, shape, random): """Generate a mask for a filled rectangle shape. The height and width of the rectangle are generated randomly. Parameters ---------- point : tuple The row and column of the top left corner of the rectangle. image : tuple The height, width and depth of the image into which the shape is placed. shape : tuple The minimum and maximum size of the shape to fit. random : np.random.RandomState The random state to use for random sampling. Raises ------ ArithmeticError When a shape cannot be fit into the image with the given starting coordinates. This usually means the image dimensions are too small or shape dimensions too large. Returns ------- label : tuple A (category, ((r0, r1), (c0, c1))) tuple specifying the category and bounding box coordinates of the shape. indices : 2-D array A mask of indices that the shape fills. """ available_width = min(image[1] - point[1], shape[1]) if available_width < shape[0]: raise ArithmeticError('cannot fit shape to image') available_height = min(image[0] - point[0], shape[1]) if available_height < shape[0]: raise ArithmeticError('cannot fit shape to image') # Pick random widths and heights. r = random.randint(shape[0], available_height + 1) c = random.randint(shape[0], available_width + 1) rectangle = draw_polygon([ point[0], point[0] + r, point[0] + r, point[0], ], [ point[1], point[1], point[1] + c, point[1] + c, ]) label = ('rectangle', ((point[0], point[0] + r), (point[1], point[1] + c))) return rectangle, label
def _generate_parallelogram_mask(point, image, size, p, random, OorA, lean, angle=0): r = int(math.sqrt(size / p)) c = int(math.sqrt(size * p)) d = int(OorA * c) p1r = point[0] p2r = point[0] + r * math.cos(angle) - d * math.sin(angle) p3r = point[0] + r * math.cos(angle) + c * math.sin(angle) - d * math.sin( angle) p4r = point[0] + c * math.sin(angle) p1c = point[1] p2c = point[1] - r * math.sin(angle) - d * math.cos(angle) p3c = point[1] + c * math.cos(angle) - r * math.sin(angle) - d * math.cos( angle) p4c = point[1] + c * math.cos(angle) # 判断旋转后是否在边框内 if p1r < 0 or p2r < 0 or p3r < 0 or p4r < 0 or p1c < 0 or p2c < 0 or p3c < 0 or p4c < 0: raise ArithmeticError('cannot fit shape to image') if p1r > image[0] or p2r > image[0] or p3r > image[0] or p4r > image[ 0] or p1c > image[1] or p2c > image[1] or p3c > image[ 1] or p4c > image[1]: raise ArithmeticError('cannot fit shape to image') parallelogram = draw_polygon([ p1r, p2r, p3r, p4r, ], [ p1c, p2c, p3c, p4c, ]) location = [(p1r + p3r) / 2, (p1c + p3c) / 2] label = ('parallelogram', (p1r, p3r), (p1c, p3c), (location[0], location[1])) return parallelogram, label
def _generate_triangle_mask(point, image, size, p, random, OorA, lean, angle=0): if size == 1: raise ValueError('dimension must be > 1 for triangles') r = int(math.sqrt(2 * size / p)) c = int(math.sqrt(2 * size * p)) if OorA < 0.5: B = r H = c else: B = c H = r p1r = point[0] p2r = point[0] + B * math.cos(angle) p3r = point[0] + B * math.cos(angle) / 2 - H * math.sin(angle) p1c = point[1] p2c = point[1] + B * math.sin(angle) p3c = point[1] + H * math.cos(angle) + B * math.sin(angle) / 2 if p1r < 0 or p2r < 0 or p3r < 0 or p1c < 0 or p2c < 0 or p3c < 0: raise ArithmeticError('cannot fit shape to image') if p1r > image[0] or p2r > image[0] or p3r > image[0] or p1c > image[ 1] or p2c > image[1] or p3c > image[1]: raise ArithmeticError('cannot fit shape to image') triangle = draw_polygon([ p1r, p2r, p3r, ], [ p1c, p2c, p3c, ]) location = [(p1r + p3r + B / 2 * math.sin(angle)) / 2, (p1c + p3c) / 2] label = ('triangle', (p1r, p3r + B / 2 * math.sin(angle)), (p1c, p3c), (location[0], location[1])) return triangle, label
def _generate_triangle_mask(point, image, shape, random): """Generate a mask for a filled equilateral triangle shape. The length of the sides of the triangle is generated randomly. Parameters ---------- point : tuple The row and column of the top left corner of a down-pointing triangle. image : tuple The height, width and depth of the image into which the shape is placed. shape : tuple The minimum and maximum size and color of the shape to fit. random : np.random.RandomState The random state to use for random sampling. Raises ------ ArithmeticError When a shape cannot be fit into the image with the given starting coordinates. This usually means the image dimensions are too small or shape dimensions too large. Returns ------- label : tuple A (category, ((r0, r1), (c0, c1))) tuple specifying the category and bounding box coordinates of the shape. indices : 2-D array A mask of indices that the shape fills. """ if shape[0] == 1 or shape[1] == 1: raise ValueError('dimension must be > 1 for triangles') available_side = min(image[1] - point[1], point[0] + 1, shape[1]) if available_side < shape[0]: raise ArithmeticError('cannot fit shape to image') side = random.randint(shape[0], available_side + 1) triangle_height = int(np.ceil(np.sqrt(3 / 4.0) * side)) triangle = draw_polygon([ point[0], point[0] - triangle_height, point[0], ], [ point[1], point[1] + side // 2, point[1] + side, ]) label = ('triangle', ((point[0] - triangle_height, point[0]), (point[1], point[1] + side))) return triangle, label
def build_mask_from_mini_boxes(img_size, boxes): def clip_quad(quads, img_size): quads[:, 0] = np.minimum(np.maximum(quads[:, 0], 0), img_size[1]) # 0<= x <= w quads[:, 1] = np.minimum(np.maximum(quads[:, 1], 0), img_size[0]) # 0<= y <= h return quads mask = np.zeros(img_size, dtype=np.uint8) scores = [] for b in boxes: quads = clip_quad(quads=b.box2quad(), img_size=img_size) rr, cc = draw_polygon(quads[:, 1], quads[:, 0]) mask[rr, cc] = 255 scores.append(b.score) return mask, np.mean(scores)
def _generate_triangle_mask(point, image, size,p, random,angle=0): if size == 1 : raise ValueError('dimension must be > 1 for triangles') r = math.sqrt(2*size / p) c = math.sqrt(2*size * p) if random.randint(1,2)==1: side0 = math.sqrt(r*r + (c/2)*(c/2)) side = c else: side0 = math.sqrt(c*c + (r/2)*(r/2)) side = r angle2=math.pi/2-angle-math.acos(math.sqrt((2*side**2-side0**2)/(2*side**2))) #angle2=math.pi/2-angle-math.pi/3 triangle_height = int(np.ceil(np.sqrt(3 / 4.0) * side)) p1r=point[0] p2r=point[0] - side*math.sin(angle) p3r=point[0] - side*math.cos(angle2) p1c=point[1] p2c=point[1] + side*math.cos(angle) p3c=point[1] + side*math.sin(angle2) if p1r<0 or p2r<0 or p3r<0 or p1c<0 or p2c<0 or p3c<0 : raise ArithmeticError('cannot fit shape to image') if p1r>image[0] or p2r>image[0] or p3r>image[0] or p1c>image[1] or p2c>image[1] or p3c>image[1] : raise ArithmeticError('cannot fit shape to image') triangle = draw_polygon([ p1r, p2r, p3r, ], [ p1c, p2c, p3c, ]) label = ('triangle', ((point[0] - triangle_height, point[0]), (point[1], point[1] + side))) return triangle, label
def _generate_rectangle_mask(point, image, size, p, random, OorA, lean, angle=0): r = int(math.sqrt(size / p)) c = int(math.sqrt(size * p)) p1r = point[0] p2r = point[0] + r * math.cos(angle) p3r = point[0] + r * math.cos(angle) + c * math.sin(angle) p4r = point[0] + c * math.sin(angle) p1c = point[1] p2c = point[1] - r * math.sin(angle) p3c = point[1] + c * math.cos(angle) - r * math.sin(angle) p4c = point[1] + c * math.cos(angle) # 判断旋转后是否在边框内 if p1r < 0 or p2r < 0 or p3r < 0 or p4r < 0 or p1c < 0 or p2c < 0 or p3c < 0 or p4c < 0: raise ArithmeticError('cannot fit shape to image') if p1r > image[0] or p2r > image[0] or p3r > image[0] or p4r > image[ 0] or p1c > image[1] or p2c > image[1] or p3c > image[ 1] or p4c > image[1]: raise ArithmeticError('cannot fit shape to image') rectangle = draw_polygon([ p1r, p2r, p3r, p4r, ], [ p1c, p2c, p3c, p4c, ]) label = ('rectangle', ((p1r, p3r), (p1c, p3c))) return rectangle, label
def _generate_parallelogram_mask(point, image, size,p, random,angle=0): available_width = min(image[1] - point[1], shape[1]) if available_width < shape[0]: raise ArithmeticError('cannot fit shape to image') available_height = min(image[0] - point[0], shape[1]) if available_height < shape[0]: raise ArithmeticError('cannot fit shape to image') # Pick random widths and heights. r = random.randint(shape[0], available_height + 1) c = random.randint(shape[0], available_width + 1) d = random.randint( 1 , available_width + 1) p1r=point[0] p2r=point[0] + r*math.cos(angle) - d*math.sin(angle) p3r=point[0] + r*math.cos(angle) + c*math.sin(angle) - d*math.sin(angle) p4r=point[0] + c*math.sin(angle) p1c=point[1] p2c=point[1] - r*math.sin(angle) - d*math.cos(angle) p3c=point[1] + c*math.cos(angle) - r*math.sin(angle) - d*math.cos(angle) p4c=point[1] + c*math.cos(angle) # 判断旋转后是否在边框内 if p1r<0 or p2r<0 or p3r<0 or p4r<0 or p1c<0 or p2c<0 or p3c<0 or p4c<0 : raise ArithmeticError('cannot fit shape to image') if p1r>image[0] or p2r>image[0] or p3r>image[0] or p4r>image[0] or p1c>image[1] or p2c>image[1] or p3c>image[1] or p4c>image[1]: raise ArithmeticError('cannot fit shape to image') parallelogram = draw_polygon([ p1r, p2r, p3r, p4r, ], [ p1c, p2c, p3c, p4c, ]) label = ('parallelogram', ((point[0], point[0] + r*math.cos(angle) + c*math.sin(angle)- d*math.sin(angle)), (point[1] - r*math.sin(angle)- d*math.cos(angle), point[1] + c*math.cos(angle)))) return parallelogram, label
def _generate_triangle_mask(point, image, shape, random, angle=0): if shape[0] == 1 or shape[1] == 1: raise ValueError('dimension must be > 1 for triangles') available_side = min(image[1] - point[1], point[0] + 1, shape[1]) if available_side < shape[0]: raise ArithmeticError('cannot fit shape to image') side0 = random.randint(shape[0], available_side + 1) side = random.randint(shape[0], available_side + 1) angle2 = math.pi / 2 - angle - math.acos( math.sqrt((2 * side**2 - side0**2) / (2 * side**2))) #angle2=math.pi/2-angle-math.pi/3 triangle_height = int(np.ceil(np.sqrt(3 / 4.0) * side)) p1r = point[0] p2r = point[0] - side * math.sin(angle) p3r = point[0] - side * math.cos(angle2) p1c = point[1] p2c = point[1] + side * math.cos(angle) p3c = point[1] + side * math.sin(angle2) if p1r < 0 or p2r < 0 or p3r < 0 or p1c < 0 or p2c < 0 or p3c < 0: raise ArithmeticError('cannot fit shape to image') if p1r > image[0] or p2r > image[0] or p3r > image[0] or p1c > image[ 1] or p2c > image[1] or p3c > image[1]: raise ArithmeticError('cannot fit shape to image') triangle = draw_polygon([ p1r, p2r, p3r, ], [ p1c, p2c, p3c, ]) label = ('triangle', ((point[0] - triangle_height, point[0]), (point[1], point[1] + side))) return triangle, label