Exemplo n.º 1
0
    def detect_onet(self, im, dets, mode='test'):
        """Get face candidates using onet

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

        Returns:
        -------
        boxes: numpy array
            detected boxes before calibration
        boxes_c: numpy array
            boxes after calibration
        """
        h, w, c = im.shape
        dets = self.convert_to_square(dets)
        dets[:, 0:4] = np.round(dets[:, 0:4])

        [dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph] = self.pad(dets, w, h)
        num_boxes = dets.shape[0]
        '''
        # helper for setting ONet batch size
        batch_size = self.onet_detector.batch_size
        ratio = float(num_boxes) / batch_size
        if ratio > 3 or ratio < 0.3:
            print "You may need to reset ONet batch size if this info appears frequently, \
face candidates:%d, current batch_size:%d"%(num_boxes, batch_size)
        '''

        cropped_ims = np.zeros((num_boxes, 3, 48, 48), dtype=np.float32)
        for i in range(num_boxes):
            if tmph[i] >= 2 and tmpw[i] >= 2:
                tmp = np.zeros((tmph[i], tmpw[i], 3), dtype=np.uint8)
                tmp[dy[i]:edy[i] + 1,
                    dx[i]:edx[i] + 1, :] = im[y[i]:ey[i] + 1,
                                              x[i]:ex[i] + 1, :]
                cropped_ims[i, :, :, :] = image_processing.transform(
                    cv2.resize(tmp, (48, 48)))
        cls_scores, reg = self.onet_detector.predict(cropped_ims)

        cls_scores = cls_scores[:, 1].flatten()
        keep_inds = np.where(cls_scores > self.thresh[2])[0]

        if len(keep_inds) > 0:
            boxes = dets[keep_inds]
            boxes[:, 4] = cls_scores[keep_inds]
            reg = reg[keep_inds]
        else:
            return None, None

        boxes_c = self.calibrate_box(boxes, reg)

        if mode == 'test':
            keep = py_nms(boxes_c, 0.7, "Minimum")
            boxes_c = boxes_c[keep]

        return boxes, boxes_c
Exemplo n.º 2
0
    def detect_onet(self, im, dets):
        """Get face candidates using onet

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

        Returns:
        -------
        boxes: numpy array
            detected boxes before calibration
        boxes_c: numpy array
            boxes after calibration
        """
        if dets is None:
            return None, None
        h, w, c = im.shape
        dets = self.convert_to_square(dets)
        dets[:, 0:4] = np.round(dets[:, 0:4])

        [dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph] = self.pad(dets, w, h)
        num_boxes = dets.shape[0]

        '''
        # helper for setting ONet batch size
        batch_size = self.onet_detector.batch_size
        ratio = float(num_boxes) / batch_size
        if ratio > 3 or ratio < 0.3:
            print("You may need to reset ONet batch size if this info appears frequently, \)
face candidates:%d, current batch_size:%d"%(num_boxes, batch_size)
        '''

        cropped_ims = np.zeros((num_boxes, 3, 48, 48), dtype=np.float32)
        for i in range(num_boxes):
            tmp = np.zeros((tmph[i], tmpw[i], 3), dtype=np.uint8)
            tmp[dy[i]:edy[i]+1, dx[i]:edx[i]+1, :] = im[y[i]:ey[i]+1, x[i]:ex[i]+1, :]
            cropped_ims[i, :, :, :] = image_processing.transform(cv2.resize(tmp, (48, 48)))
        cls_scores, reg = self.onet_detector.predict(cropped_ims)

        cls_scores = cls_scores[:, 1].flatten()
        keep_inds = np.where(cls_scores > self.thresh[2])[0]

        if len(keep_inds) > 0:
            boxes = dets[keep_inds]
            boxes[:, 4] = cls_scores[keep_inds]
            reg = reg[keep_inds]
        else:
            return None, None

        boxes_c = self.calibrate_box(boxes, reg)

        keep = py_nms(boxes_c, 0.7, "Minimum")
        boxes_c = boxes_c[keep]

        return boxes, boxes_c
Exemplo n.º 3
0
    def detect_pnet(self, im):
        """Get face candidates through pnet

        Parameters:
        ----------
        im: numpy array
            input image array

        Returns:
        -------
        boxes: numpy array
            detected boxes before calibration
        boxes_c: numpy array
            boxes after calibration
        """
        h, w, c = im.shape
        net_size = 12

        current_scale = float(
            net_size) / self.min_face_size  # find initial scale
        im_resized = self.resize_image(im, current_scale)
        _, _, current_height, current_width = im_resized.shape

        if self.slide_window:
            # sliding window
            temp_rectangles = list()
            rectangles = list(
            )  # list of rectangles [x11, y11, x12, y12, confidence] (corresponding to original image)
            all_cropped_ims = list()
            while min(current_height, current_width) > net_size:
                current_y_list = range(0, current_height - net_size + 1, self.stride) if (current_height - net_size) % self.stride == 0 \
                else range(0, current_height - net_size + 1, self.stride) + [current_height - net_size]
                current_x_list = range(0, current_width - net_size + 1, self.stride) if (current_width - net_size) % self.stride == 0 \
                else range(0, current_width - net_size + 1, self.stride) + [current_width - net_size]

                for current_y in current_y_list:
                    for current_x in current_x_list:
                        cropped_im = im_resized[:, :,
                                                current_y:current_y + net_size,
                                                current_x:current_x + net_size]

                        current_rectangle = [
                            int(w * float(current_x) / current_width),
                            int(h * float(current_y) / current_height),
                            int(w * float(current_x) / current_width) +
                            int(w * float(net_size) / current_width),
                            int(h * float(current_y) / current_height) +
                            int(w * float(net_size) / current_width), 0.0
                        ]
                        temp_rectangles.append(current_rectangle)
                        all_cropped_ims.append(cropped_im)

                current_scale *= self.scale_factor
                im_resized = self.resize_image(im, current_scale)
                _, _, current_height, current_width = im_resized.shape
            '''
            # helper for setting PNet batch size
            num_boxes = len(all_cropped_ims)
            batch_size = self.pnet_detector.batch_size
            ratio = float(num_boxes) / batch_size
            if ratio > 3 or ratio < 0.3:
                print "You may need to reset PNet batch size if this info appears frequently, \
face candidates:%d, current batch_size:%d"%(num_boxes, batch_size)
            '''
            all_cropped_ims = np.vstack(all_cropped_ims)
            cls_scores, reg = self.pnet_detector.predict(all_cropped_ims)

            cls_scores = cls_scores[:, 1].flatten()
            keep_inds = np.where(cls_scores > self.thresh[0])[0]

            if len(keep_inds) > 0:
                boxes = np.vstack(temp_rectangles[ind] for ind in keep_inds)
                boxes[:, 4] = cls_scores[keep_inds]
                reg = reg[keep_inds].reshape(-1, 4)
            else:
                return None, None

            keep = py_nms(boxes, 0.7, 'Union')
            boxes = boxes[keep]

            boxes_c = self.calibrate_box(boxes, reg[keep])

        else:
            # fcn
            all_boxes = list()
            while min(current_height, current_width) > net_size:
                cls_map, reg = self.pnet_detector.predict(im_resized)
                cls_map = cls_map.asnumpy()
                reg = reg.asnumpy()
                boxes = self.generate_bbox(cls_map[0, 1, :, :], reg,
                                           current_scale, self.thresh[0])

                current_scale *= self.scale_factor
                im_resized = self.resize_image(im, current_scale)
                _, _, current_height, current_width = im_resized.shape

                if boxes.size == 0:
                    continue
                keep = py_nms(boxes[:, :5], 0.5, 'Union')
                boxes = boxes[keep]
                all_boxes.append(boxes)

            if len(all_boxes) == 0:
                return None, None

            all_boxes = np.vstack(all_boxes)

            # merge the detection from first stage
            keep = py_nms(all_boxes[:, 0:5], 0.7, 'Union')
            all_boxes = all_boxes[keep]
            boxes = all_boxes[:, :5]

            bbw = all_boxes[:, 2] - all_boxes[:, 0] + 1
            bbh = all_boxes[:, 3] - all_boxes[:, 1] + 1

            # refine the boxes
            boxes_c = np.vstack([
                all_boxes[:, 0] + all_boxes[:, 5] * bbw,
                all_boxes[:, 1] + all_boxes[:, 6] * bbh,
                all_boxes[:, 2] + all_boxes[:, 7] * bbw,
                all_boxes[:, 3] + all_boxes[:, 8] * bbh, all_boxes[:, 4]
            ])
            boxes_c = boxes_c.T

        return boxes, boxes_c
Exemplo n.º 4
0
    def detect_pnet(self, im):
        """Get face candidates through pnet

        Parameters:
        ----------
        im: numpy array
            input image array

        Returns:
        -------
        boxes: numpy array
            detected boxes before calibration
        boxes_c: numpy array
            boxes after calibration
        """
        h, w, c = im.shape
        net_size = 12

        current_scale = float(net_size) / self.min_face_size    # find initial scale
        im_resized = self.resize_image(im, current_scale)
        _, _, current_height, current_width = im_resized.shape

        if self.slide_window:
            # sliding window
            temp_rectangles = list()
            rectangles = list()     # list of rectangles [x11, y11, x12, y12, confidence] (corresponding to original image)
            all_cropped_ims = list()
            while min(current_height, current_width) > net_size:
                current_y_list = range(0, current_height - net_size + 1, self.stride) if (current_height - net_size) % self.stride == 0 \
                    else range(0, current_height - net_size + 1, self.stride) + [current_height - net_size]
                current_x_list = range(0, current_width - net_size + 1, self.stride) if (current_width - net_size) % self.stride == 0 \
                    else range(0, current_width - net_size + 1, self.stride) + [current_width - net_size]

                for current_y in current_y_list:
                    for current_x in current_x_list:
                        cropped_im = im_resized[:, :, current_y:current_y + net_size, current_x:current_x + net_size]

                        current_rectangle = [int(w * float(current_x) / current_width), int(h * float(current_y) / current_height),
                                             int(w * float(current_x) / current_width) + int(w * float(net_size) / current_width),
                                             int(h * float(current_y) / current_height) + int(w * float(net_size) / current_width),
                                             0.0]
                        temp_rectangles.append(current_rectangle)
                        all_cropped_ims.append(cropped_im)

                current_scale *= self.scale_factor
                im_resized = self.resize_image(im, current_scale)
                _, _, current_height, current_width = im_resized.shape

            '''
            # helper for setting PNet batch size
            num_boxes = len(all_cropped_ims)
            batch_size = self.pnet_detector.batch_size
            ratio = float(num_boxes) / batch_size
            if ratio > 3 or ratio < 0.3:
                print("You may need to reset PNet batch size if this info appears frequently, \)
face candidates:%d, current batch_size:%d"%(num_boxes, batch_size)
            '''
            all_cropped_ims = np.vstack(all_cropped_ims)
            cls_scores, reg = self.pnet_detector.predict(all_cropped_ims)

            cls_scores = cls_scores[:, 1].flatten()
            keep_inds = np.where(cls_scores > self.thresh[0])[0]

            if len(keep_inds) > 0:
                boxes = np.vstack(temp_rectangles[ind] for ind in keep_inds)
                boxes[:, 4] = cls_scores[keep_inds]
                reg = reg[keep_inds].reshape(-1, 4)
            else:
                return None, None

            keep = py_nms(boxes, 0.7, 'Union')
            boxes = boxes[keep]

            boxes_c = self.calibrate_box(boxes, reg[keep])

        else:
            # fcn
            all_boxes = list()
            while min(current_height, current_width) > net_size:
                cls_map, reg = self.pnet_detector.predict(im_resized)
                cls_map = cls_map.asnumpy()
                reg = reg.asnumpy()
                boxes = self.generate_bbox(cls_map[0, 1, :, :], reg, current_scale, self.thresh[0])

                current_scale *= self.scale_factor
                im_resized = self.resize_image(im, current_scale)
                _, _, current_height, current_width = im_resized.shape

                if boxes.size == 0:
                    continue
                keep = py_nms(boxes[:, :5], 0.5, 'Union')
                boxes = boxes[keep]
                all_boxes.append(boxes)

            if len(all_boxes) == 0:
                return None, None

            all_boxes = np.vstack(all_boxes)

            # merge the detection from first stage
            keep = py_nms(all_boxes[:, 0:5], 0.7, 'Union')
            all_boxes = all_boxes[keep]
            boxes = all_boxes[:, :5]

            bbw = all_boxes[:, 2] - all_boxes[:, 0] + 1
            bbh = all_boxes[:, 3] - all_boxes[:, 1] + 1

            # refine the boxes
            boxes_c = np.vstack([all_boxes[:, 0] + all_boxes[:, 5] * bbw,
                                 all_boxes[:, 1] + all_boxes[:, 6] * bbh,
                                 all_boxes[:, 2] + all_boxes[:, 7] * bbw,
                                 all_boxes[:, 3] + all_boxes[:, 8] * bbh,
                                 all_boxes[:, 4]])
            boxes_c = boxes_c.T

        return boxes, boxes_c