def __call__(self, img, boxes, segments, labels): ''' apply transform when calling :param img: numpy.ndarray,(h,w,c) :param boxes: numpy.ndarray,(n,4), x1,y1,x2,y2 :param segments: list(list),(n)(x),x is variant :param labels: numpy.ndarray,(n) :return: ''' h, w, c = img.shape while True: mode = random.choice(self.sample_mode) if mode == 1: return img, boxes, segments, labels min_iou = mode for i in range(50): new_w = random.uniform(self.min_crop_size * w, w) new_h = random.uniform(self.min_crop_size * h, h) # h / w in [0.5, 2] if new_h / new_w < 0.5 or new_h / new_w > 2: continue left = random.uniform(w - new_w) top = random.uniform(h - new_h) patch = np.array( (int(left), int(top), int(left + new_w), int(top + new_h))) overlaps = bbox_overlaps(patch.reshape(-1, 4), boxes.reshape(-1, 4)).reshape(-1) if overlaps.min() < min_iou: continue # center of boxes should inside the crop img center = (boxes[:, :2] + boxes[:, 2:]) / 2 mask = (center[:, 0] > patch[0]) * ( center[:, 1] > patch[1]) * (center[:, 0] < patch[2]) * ( center[:, 1] < patch[3]) if not mask.any(): continue # adjust boxes img = img[patch[1]:patch[3], patch[0]:patch[2]] # box here is not valid enough # we shound use mask to generate the new box # boxes[:, 2:] = boxes[:, 2:].clip(max=patch[2:]) # boxes[:, :2] = boxes[:, :2].clip(min=patch[:2]) # boxes -= np.tile(patch[:2], 2) boxes = [] out_segments = [] out_labels = [] for j, segment in enumerate(segments): if not mask[j]: continue segment = np.array(segment).reshape(-1, 2) segment = Polygon(segment) bound = patch.copy() bound = bound + np.array([1, 1, -1, -1]) bound = np.vstack((bound[[0, 2, 2, 0]], bound[[1, 1, 3, 3]])).transpose() bound = Polygon(bound) segment = bound.intersection(segment) try: segment = np.array(segment.exterior.coords) except Exception as e: print(e) continue segment -= patch[:2] x1, y1 = np.min(segment, 0) x2, y2 = np.max(segment, 0) boxes.append([x1, y1, x2, y2]) out_labels.append(labels[j]) out_segments.append(list(segment.reshape(-1))) boxes = np.array(boxes).astype(np.int32) return img, boxes, out_segments, np.array(out_labels)