Esempio n. 1
0
    def detect_onet(self, im, bboxes):
        """Get face candidates using onet

        Parameters:
        ----------
        im: numpy array
            input image array
        bboxes: numpy array
            detection results of rnet

        Returns:
        -------
        bboxes_align: numpy array
            bboxes after calibration
        """
        net_size = config.ONET_SIZE
        h, w, c = im.shape
        if bboxes is None:
            return None

        [dy, edy, dx, edx, y, ey, x, ex, tmpw,
         tmph] = utils.correct_bboxes(bboxes, w, h)
        num_bboxes = bboxes.shape[0]

        # crop face using rnet proposal
        cropped_ims_tensors = []
        for i in range(num_bboxes):
            try:
                if tmph[i] > 0 and tmpw[i] > 0:
                    tmp = np.zeros((tmph[i], tmpw[i], 3), dtype=np.uint8)
                    tmp[dy[i]:edy[i], dx[i]:edx[i], :] = im[y[i]:ey[i],
                                                            x[i]:ex[i], :]
                    crop_im = cv2.resize(tmp, (net_size, net_size))
                    crop_im_tensor = utils.convert_image_to_tensor(crop_im)
                    cropped_ims_tensors.append(crop_im_tensor)
            except ValueError as e:
                print(e)

        feed_imgs = torch.stack(cropped_ims_tensors)
        feed_imgs = feed_imgs.to(self.device)

        cls, reg = self.onet_detector(feed_imgs)
        cls = cls.cpu().data.numpy()
        reg = reg.cpu().data.numpy()

        keep_inds = np.where(cls[:, 1] > self.thresh[2])[0]
        if len(keep_inds) > 0:
            keep_bboxes = bboxes[keep_inds]
            keep_cls = cls[keep_inds, :]
            keep_reg = reg[keep_inds]
            keep_bboxes[:, 4] = keep_cls[:, 1].reshape((-1, ))
        else:
            return None

        bboxes_align = utils.calibrate_box(keep_bboxes, keep_reg)
        keep = utils.nms(bboxes_align, 0.7, mode='Minimum')

        if len(keep) == 0:
            return None

        bboxes_align = bboxes_align[keep]
        bboxes_align = utils.convert_to_square(bboxes_align)
        return bboxes_align
Esempio n. 2
0
    def detect_rnet(self, im, bboxes):
        """Get face candidates using rnet

        Parameters:
        ----------
        im: numpy array
            input image array
        bboxes: numpy array
            detection results of pnet

        Returns:
        -------
        bboxes_align: numpy array
            bboxes after calibration
        """
        net_size = config.RNET_SIZE
        h, w, c = im.shape
        if bboxes is None:
            return None

        num_bboxes = bboxes.shape[0]

        [dy, edy, dx, edx, y, ey, x, ex, tmpw,
         tmph] = utils.correct_bboxes(bboxes, w, h)

        # crop face using pnet proposals
        cropped_ims_tensors = []
        for i in range(num_bboxes):
            try:
                if tmph[i] > 0 and tmpw[i] > 0:
                    tmp = np.zeros((tmph[i], tmpw[i], 3), dtype=np.uint8)
                    tmp[dy[i]:edy[i], dx[i]:edx[i], :] = im[y[i]:ey[i],
                                                            x[i]:ex[i], :]
                    crop_im = cv2.resize(tmp, (net_size, net_size))
                    crop_im_tensor = utils.convert_image_to_tensor(crop_im)
                    cropped_ims_tensors.append(crop_im_tensor)
            except ValueError as e:
                print('dy: {}, edy: {}, dx: {}, edx: {}'.format(
                    dy[i], edy[i], dx[i], edx[i]))
                print('y: {}, ey: {}, x: {}, ex: {}'.format(
                    y[i], ey[i], x[i], ex[i]))
                print(e)

        # provide input tensor, if there are too many proposals in PNet
        # there might be OOM
        feed_imgs = torch.stack(cropped_ims_tensors)
        feed_imgs = feed_imgs.to(self.device)

        cls, reg = self.rnet_detector(feed_imgs)
        cls = cls.cpu().data.numpy()
        reg = reg.cpu().data.numpy()

        keep_inds = np.where(cls[:, 1] > self.thresh[1])[0]
        if len(keep_inds) > 0:
            keep_bboxes = bboxes[keep_inds]
            keep_cls = cls[keep_inds, :]
            keep_reg = reg[keep_inds]
            # using softmax 1 as cls score
            keep_bboxes[:, 4] = keep_cls[:, 1].reshape((-1, ))
        else:
            return None

        keep = utils.nms(keep_bboxes, 0.7)
        if len(keep) == 0:
            return None

        keep_cls = keep_cls[keep]
        keep_bboxes = keep_bboxes[keep]
        keep_reg = keep_reg[keep]

        bboxes_align = utils.calibrate_box(keep_bboxes, keep_reg)
        bboxes_align = utils.convert_to_square(bboxes_align)
        bboxes_align[:, 0:4] = np.round(bboxes_align[:, 0:4])

        return bboxes_align