Ejemplo n.º 1
0
    def _augment(self, item, dsize):
        image = item['image']
        boxes = item['bbox']  # [n, 4]
        h, w = image.shape[:2]
        dw, dh = dsize
        # random choose one face as interest region,
        box = random.choice(boxes)
        size = np.random.choice(
            np.sqrt(np.prod(boxes[:, 2:] - boxes[:, :2], axis=-1)))
        max_size = min(size, self.max_face)
        max_scale = max_size / size
        min_scale = min(dw / w, dh / h)
        scale = random.uniform(min_scale, max_scale)
        ibox = np.array([0, 0, w, h], dtype=np.float32)
        matrix = matrix2d.scale(scale)
        tbox = bbox_affine(ibox, matrix)
        dbox = np.array([0, 0, dw, dh], dtype=np.float32)
        fbox = bbox_affine(box, matrix)

        # determine translation bound
        tlow = tbox[:2] - dbox[:2]
        thigh = tbox[2:] - dbox[2:]
        flow = fbox[2:] - dbox[2:]
        fhigh = fbox[:2] - dbox[:2]

        thigh = np.minimum(thigh, fhigh)
        tlow = np.maximum(tlow, flow)

        high = np.maximum(tlow, thigh)
        low = np.minimum(tlow, thigh)
        txty = np.random.uniform(low, high)
        translate = matrix2d.translate(-txty)
        matrix = translate @ matrix
        angle = np.random.uniform(-self.rotation, self.rotation)
        rotate = matrix2d.center_rotate_scale_cw([dw / 2, dh / 2], angle, 1.0)
        matrix = rotate @ matrix

        mirror = random.choice([True, False])
        if mirror:
            matrix = matrix2d.hflip(dw) @ matrix

        item = self._transform(item, matrix, random.choice(self.inters),
                               mirror)
        # remove face exceed image
        boxes = item['bbox'].copy()
        area = np.prod(boxes[:, 2:] - boxes[:, :2], axis=-1)
        boxes[boxes < 0] = 0
        boxes[:, 2:] = np.minimum(boxes[:, 2:], [[dw, dh]])
        inner = np.prod(boxes[:, 2:] - boxes[:, :2], axis=-1)
        ratio = inner / area
        discard = ratio < 0.4
        item['label'][discard] = 0
        return item
Ejemplo n.º 2
0
    def _transform(self, item, matrix, inter, mirror):
        image = item['image']
        bboxes = item['bbox']
        image = warp_affine(image,
                            matrix,
                            self.dsize,
                            flags=inter,
                            borderMode=cv2.BORDER_REPLICATE)
        bboxes = bbox_affine(bboxes, matrix).astype(np.float32)

        ret = {
            'image': image,
            'bbox': bboxes,
            'label': np.ones(bboxes.shape[0], dtype=np.int64)
        }

        if 'shape' in item:
            points = item['shape'].reshape(-1, 2)
            points = points @ matrix[:2, :2].T + matrix[:2, 2]
            points = points.reshape(bboxes.shape[0], -1, 2).astype(np.float32)
            if mirror:
                points = points[:, self.symmetry, :]
            ret['shape'] = points
            ret['mask'] = item['mask']
        return ret
Ejemplo n.º 3
0
 def meanbbox(self):
     meanshape = self.meanshape
     bboxes = []
     for item in self.data:
         shape = item['shape']
         bbox = item['bbox']  # n, 4
         matrix = umeyama(shape, meanshape)
         bbox = bbox_affine(bbox, matrix)
         bboxes.append(bbox)
     return np.stack(bboxes, 0).mean(0)
Ejemplo n.º 4
0
def main(args):
    workdir = Path(args.workdir)
    workdir.mkdir(parents=True, exist_ok=True)
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    model = models.__dict__[args.model.name](phase='train').to(device)
    prior = BBoxShapePrior(args.num_classes, 5, args.anchors,
                           args.iou_threshold, args.encode_mean,
                           args.encode_std)

    detector = Detector(prior, model)

    state = Saver.load_best_from_folder(workdir, map_location='cpu')
    detector.load_state_dict(state['model'])
    predictor = Predictor(detector, args.test.score_threshold,
                          args.test.iou_threshold, device)
    output_dir = workdir / 'result'
    image_dir = Path(args.test.image_dir)
    for imagefile in tqdm.tqdm(image_dir.rglob('*.jpg')):
        relpath = imagefile.relative_to(image_dir)
        outpath = output_dir / relpath
        outpath.parent.mkdir(parents=True, exist_ok=True)
        image = cv2.imread(str(imagefile), cv2.IMREAD_COLOR)
        scale = (args.test.long_size / np.array(image.shape[:2])).min()
        w, h = (np.array(image.shape[:2]) * scale).astype(np.int32)[::-1]

        matrix = matrix2d.scale(scale)
        warped = warp_affine(image, matrix, (w, h))
        score, boxes, points = predictor.predict(warped)

        n = score.size
        if n > 0:
            matrix = np.linalg.inv(matrix)
            boxes = bbox_affine(boxes, matrix)
            # k, p, 2
            points = points.reshape(-1, 2) @ matrix[:2, :2].T + matrix[:2, 2]
            points = points.reshape(score.size, -1, 2)

            # draw result
            draw_bbox(image, boxes)
            draw_points(image, points)

        cv2.imwrite(str(outpath), image)

        # write output txt
        resfile = outpath.with_suffix('.txt')
        with open(resfile, 'wt') as f:
            f.write('{}\n'.format(imagefile.name))
            f.write(f'{n}\n')
            if n > 0:
                boxes = bbox2rect(boxes)
                for score, box in zip(score.tolist(), boxes):
                    box = box.reshape(-1).tolist()
                    line = ' '.join(str(v) for v in box)
                    f.write(f'{line} {score}\n')
Ejemplo n.º 5
0
 def __init__(self,
              dsize,
              padding,
              meanshape,
              meanbbox=None,
              symmetry=None,
              augments=None) -> None:
     super().__init__()
     dsize = _to_size(dsize)
     meanshape = np.array(meanshape)
     unit = to_unit_shape(meanshape)
     ref = (unit - 0.5) * (1 - padding) * \
         np.array(dsize).min() + np.array(dsize) / 2
     if meanbbox:
         meanbbox = np.array(meanbbox)
         matrix = umeyama(meanshape, ref)
         meanbbox = bbox_affine(meanbbox, matrix)
     self.meanbbox = meanbbox
     self.ref = ref
     self.dsize = dsize
     self.padding = padding
     self.augments = augments
     self.symmetry = symmetry
Ejemplo n.º 6
0
    def __call__(self, item):
        image = item['image']
        bboxes = item['bbox'].reshape(-1, 4)
        # calc transform matrix
        h, w = image.shape[:2]
        dw, dh = self.dsize
        scale = min(dw / w, dh / h)
        matrix = matrix2d.scale(scale)
        image = warp_affine(image, matrix, self.dsize)
        bboxes = bbox_affine(bboxes, matrix).astype(np.float32)

        ret = {
            'image': image,
            'bbox': bboxes,
            'label': np.ones(bboxes.shape[0], dtype=np.int64)
        }

        if 'shape' in item:
            shapes = item['shape'].reshape(-1, 2)
            shapes = shapes @ matrix[:2, :2].T + matrix[:2, 2]
            ret['shape'] = shapes.reshape(bboxes.shape[0], -1,
                                          2).astype(np.float32)
            ret['mask'] = item['mask']
        return ret