Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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