def _crop(image, boxes, labels): height, width, _ = image.shape if len(boxes)== 0: return image, boxes, labels while True: mode = random.choice(( None, (0.1, None), (0.3, None), (0.5, None), (0.7, None), (0.9, None), (None, None), )) if mode is None: return image, boxes, labels min_iou, max_iou = mode if min_iou is None: min_iou = float('-inf') if max_iou is None: max_iou = float('inf') for _ in range(50): scale = random.uniform(0.3,1.) min_ratio = max(0.5, scale*scale) max_ratio = min(2, 1. / scale / scale) ratio = math.sqrt(random.uniform(min_ratio, max_ratio)) w = int(scale * ratio * width) h = int((scale / ratio) * height) l = random.randrange(width - w) t = random.randrange(height - h) roi = np.array((l, t, l + w, t + h)) iou = matrix_iou(boxes, roi[np.newaxis]) if not (min_iou <= iou.min() and iou.max() <= max_iou): continue image_t = image[roi[1]:roi[3], roi[0]:roi[2]] centers = (boxes[:, :2] + boxes[:, 2:]) / 2 mask = np.logical_and(roi[:2] < centers, centers < roi[2:]) \ .all(axis=1) boxes_t = boxes[mask].copy() labels_t = labels[mask].copy() if len(boxes_t) == 0: continue boxes_t[:, :2] = np.maximum(boxes_t[:, :2], roi[:2]) boxes_t[:, :2] -= roi[:2] boxes_t[:, 2:] = np.minimum(boxes_t[:, 2:], roi[2:]) boxes_t[:, 2:] -= roi[:2] return image_t, boxes_t,labels_t
def _crop(image, boxes, labels): height, width, _ = image.shape if random.uniform(0., 1.) > 0.15 or len(boxes) == 0: return image, boxes, labels while True: mode = random.choice(( # (min_iou, max_iou, min_object_covered) (0.0, None, 0.0), (0.1, None, 0.1), (0.3, None, 0.3), (0.5, None, 0.5), (0.7, None, 0.7), (0.9, None, 0.9), (1.0, None, 1.0), )) min_iou, max_iou = mode[:2] if min_iou is None: min_iou = float('-inf') if max_iou is None: max_iou = float('inf') for _ in range(100): scale = random.uniform(0.1, 1.) min_ratio = max(0.5, scale * scale) max_ratio = min(2, 1. / scale / scale) ratio = math.sqrt(random.uniform(min_ratio, max_ratio)) w = int(scale * ratio * width) h = int((scale / ratio) * height) """ min_ratio = max(0.5, float(width) / height * scale) max_ratio = min(2., float(width) / height / scale) ratio = random.uniform(min_ratio, max_ratio) # ratio = new_w/new_h w = int(math.sqrt(scale * ratio * width * height)) h = int(math.sqrt(scale / ratio * width * height)) """ l = random.randrange(width - w) t = random.randrange(height - h) roi = np.array((l, t, l + w, t + h)) iou = matrix_iou(boxes, roi[np.newaxis]) if not (min_iou <= iou.min() and iou.max() <= max_iou): continue image_t = image[roi[1]:roi[3], roi[0]:roi[2]] centers = (boxes[:, :2] + boxes[:, 2:]) / 2 mask = np.logical_and(roi[:2] < centers, centers < roi[2:]) \ .all(axis=1) boxes_t = boxes[mask].copy() labels_t = labels[mask].copy() if float(len(boxes_t)) / len(boxes) >= mode[2]: continue boxes_t[:, :2] = np.maximum(boxes_t[:, :2], roi[:2]) boxes_t[:, :2] -= roi[:2] boxes_t[:, 2:] = np.minimum(boxes_t[:, 2:], roi[2:]) boxes_t[:, 2:] -= roi[:2] return image_t, boxes_t, labels_t # after max_attempts failures, return the entire image return image, boxes, labels
def _crop(self, image, boxes, labels): height, width, _ = image.shape min_cropped_ratio = 0.4 if _FOR_PMI_UKRAINE else 0.70 if len(boxes) == 0 or (len(boxes) == 1 and labels[0] == 0): scale = random.uniform(0.70, 1.) #just keep aspect ratio #ratio = 1.0 scale = random.uniform(min_cropped_ratio, 1.) min_ratio = max(0.8, scale * scale) max_ratio = min(1 / 0.8, 1. / scale / scale) ratio = math.sqrt(random.uniform(min_ratio, max_ratio)) w = int(scale * ratio * width) h = int((scale / ratio) * height) l = random.randrange(width - w) t = random.randrange(height - h) roi = np.array((l, t, l + w, t + h)) image_t = image[roi[1]:roi[3], roi[0]:roi[2]] return image_t, boxes, labels area = np.prod(boxes[:, 2:] - boxes[:, :2], axis=1) / (height * width) big_sku = np.mean(area) >= 0.05 if big_sku: return image, boxes, labels while True: mode = random.choice(( None, (0.001, 0.05), #0.025*0.025=0.000625 (0.002, 0.10), (0.005, 0.10), (0.01, 0.1), (0.05, 0.25), (0.1, 0.30), (0.25, 0.5), #(0.5, None), #(0.7, None), #(0.9, None), (None, None), )) if mode is None: return image, boxes, labels min_iou, max_iou = mode if min_iou is None: min_iou = float('-inf') if max_iou is None: max_iou = float('inf') for _ in range(50): #scale = random.uniform(0.50, 1.) #it is very strange, pmi ukraine has stock counter function, #the sku in such image is quite big, so need to crop out a small portion #and resize it to [800,600] to make a fake big sku in training stage. scale = random.uniform(min_cropped_ratio, 1.) min_ratio = max(0.85, scale * scale) max_ratio = min(1 / 0.85, 1. / scale / scale) ratio = math.sqrt(random.uniform(min_ratio, max_ratio)) #just keep aspect ratio #ratio = 1.0 w = int(scale * ratio * width) h = int((scale / ratio) * height) l = random.randrange(width - w) t = random.randrange(height - h) roi = np.array((l, t, l + w, t + h)) iou = matrix_iou(boxes, roi[np.newaxis]) if not (min_iou <= iou.min() and iou.max() <= max_iou): continue image_t = image[roi[1]:roi[3], roi[0]:roi[2]] #centers = (boxes[:, :2] + boxes[:, 2:]) / 2 #mask = np.logical_and(roi[:2] < centers, centers < roi[2:]).all(axis=1) mask = (iou > (1 / 2400)).squeeze(1) boxes_t = boxes[mask].copy() labels_t = labels[mask].copy() if len(boxes_t) == 0: continue old_boxes_t = boxes_t.copy() boxes_t[:, :2] = np.maximum(boxes_t[:, :2], roi[:2]) boxes_t[:, :2] -= roi[:2] boxes_t[:, 2:] = np.minimum(boxes_t[:, 2:], roi[2:]) boxes_t[:, 2:] -= roi[:2] # new_area = (boxes_t[:, 2] - boxes_t[:, 0]) * (boxes_t[:, 3] - boxes_t[:, 1]) old_area = (old_boxes_t[:, 2] - old_boxes_t[:, 0]) * ( old_boxes_t[:, 3] - old_boxes_t[:, 1]) iou = new_area / old_area mask = iou <= 0.65 bad_mask = mask #print(self.ambigous_skus) #if True: if len(self.ambigous_skus) > 0: mask_ambigous_skus_idx = [ sku in self.ambigous_skus for sku in labels_t ] #mask2 = 2<=labels_t mask_ambigous_skus_crop_ratio = iou < ( 1 - self.ambigous_skus_crop_ratio) mask_ambigous_skus = mask_ambigous_skus_idx & mask_ambigous_skus_crop_ratio bad_mask = mask | mask_ambigous_skus pp_boxes = boxes_t[mask_ambigous_skus] bad_boxes_t = boxes_t[bad_mask] if len(pp_boxes) > 1000: print(self.ambigous_skus) print(self.ambigous_skus_crop_ratio) print(iou) print(labels_t) print(mask_ambigous_skus) print(bad_mask) bad_boxes_t = boxes_t[bad_mask] for box in bad_boxes_t: #print("black out the box because iou <0.7") image_t[int(box[1]):int(box[3]), int(box[0]):int(box[2])] = random.randint(0, 255) boxes_t = boxes_t[~bad_mask] labels_t = labels_t[~bad_mask] if len(boxes_t) == 0: targets = np.zeros((1, 5)) boxes_t = targets[:, :-1].copy() labels_t = targets[:, -1].copy() return image_t, boxes_t, labels_t