zoo3d
/
MaskClustering
/third_party
/Entity
/High-Quality-Segmention
/util
/boundary_modification.py
| import cv2 | |
| import numpy as np | |
| import random | |
| import math | |
| try: | |
| from util.de_transform import perturb_seg | |
| except: | |
| from de_transform import perturb_seg | |
| def modify_boundary(image, regional_sample_rate=0.1, sample_rate=0.1, move_rate=0.0, iou_target = 0.8): | |
| # modifies boundary of the given mask. | |
| # remove consecutive vertice of the boundary by regional sample rate | |
| # -> | |
| # remove any vertice by sample rate | |
| # -> | |
| # move vertice by distance between vertice and center of the mask by move rate. | |
| # input: np array of size [H,W] image | |
| # output: same shape as input | |
| # get boundaries | |
| if int(cv2.__version__[0]) >= 4: | |
| contours, _ = cv2.findContours(image, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) | |
| else: | |
| _, contours, _ = cv2.findContours(image, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) | |
| #only modified contours is needed actually. | |
| sampled_contours = [] | |
| modified_contours = [] | |
| for contour in contours: | |
| if contour.shape[0] < 10: | |
| continue | |
| M = cv2.moments(contour) | |
| #remove region of contour | |
| number_of_vertices = contour.shape[0] | |
| number_of_removes = int(number_of_vertices * regional_sample_rate) | |
| idx_dist = [] | |
| for i in range(number_of_vertices-number_of_removes): | |
| idx_dist.append([i, np.sum((contour[i] - contour[i+number_of_removes])**2)]) | |
| idx_dist = sorted(idx_dist, key=lambda x:x[1]) | |
| remove_start = random.choice(idx_dist[:math.ceil(0.1*len(idx_dist))])[0] | |
| #remove_start = random.randrange(0, number_of_vertices-number_of_removes, 1) | |
| new_contour = np.concatenate([contour[:remove_start], contour[remove_start+number_of_removes:]], axis=0) | |
| contour = new_contour | |
| #sample contours | |
| number_of_vertices = contour.shape[0] | |
| indices = random.sample(range(number_of_vertices), int(number_of_vertices * sample_rate)) | |
| indices.sort() | |
| sampled_contour = contour[indices] | |
| sampled_contours.append(sampled_contour) | |
| modified_contour = np.copy(sampled_contour) | |
| if (M['m00'] != 0): | |
| center = round(M['m10'] / M['m00']), round(M['m01'] / M['m00']) | |
| #modify contours | |
| for idx, coor in enumerate(modified_contour): | |
| change = np.random.normal(0,move_rate) # 0.1 means change position of vertex to 10 percent farther from center | |
| x,y = coor[0] | |
| new_x = x + (x-center[0]) * change | |
| new_y = y + (y-center[1]) * change | |
| modified_contour[idx] = [new_x,new_y] | |
| modified_contours.append(modified_contour) | |
| #draw boundary | |
| gt = np.copy(image) | |
| image = np.zeros_like(image) | |
| modified_contours = [cont for cont in modified_contours if len(cont) > 0] | |
| if len(modified_contours) == 0: | |
| image = gt.copy() | |
| else: | |
| image = cv2.drawContours(image, modified_contours, -1, (255, 0, 0), -1) | |
| image = perturb_seg(image, iou_target) | |
| return image | |