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.processed_image(im, current_scale) current_height, current_width, _ = im_resized.shape # for fcn all_boxes = list() while min(current_height, current_width) > net_size: #return the result predicted by pnet #cls_cls_map : H*w*2 #reg: H*w*4 cls_cls_map, reg = self.pnet_detector.predict(im_resized) #boxes: num*9(x1,y1,x2,y2,score,x1_offset,y1_offset,x2_offset,y2_offset) boxes = self.generate_bbox(cls_cls_map[:, :, 1], reg, current_scale, self.thresh[0]) current_scale *= self.scale_factor im_resized = self.processed_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, 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, None
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 """ 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] cropped_ims = np.zeros((num_boxes, 48, 48, 3), 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, :, :, :] = (cv2.resize(tmp, (48, 48)) - 127.5) / 128 cls_scores, reg, landmark = self.onet_detector.predict(cropped_ims) # prob belongs to face cls_scores = cls_scores[:, 1] keep_inds = np.where(cls_scores > self.thresh[2])[0] if len(keep_inds) > 0: # pickout filtered box boxes = dets[keep_inds] boxes[:, 4] = cls_scores[keep_inds] reg = reg[keep_inds] landmark = landmark[keep_inds] else: return None, None, None # width w = boxes[:, 2] - boxes[:, 0] + 1 # height h = boxes[:, 3] - boxes[:, 1] + 1 landmark[:, 0::2] = (np.tile(w, (5, 1)) * landmark[:, 0::2].T + np.tile(boxes[:, 0], (5, 1)) - 1).T landmark[:, 1::2] = (np.tile(h, (5, 1)) * landmark[:, 1::2].T + np.tile(boxes[:, 1], (5, 1)) - 1).T boxes_c = self.calibrate_box(boxes, reg) boxes = boxes[py_nms(boxes, 0.6, "Minimum")] keep = py_nms(boxes_c, 0.6, "Minimum") boxes_c = boxes_c[keep] landmark = landmark[keep] return boxes, boxes_c, landmark
def detect_rnet(self, im, dets): """Get face candidates using rnet Parameters: ---------- im: numpy array input image array dets: numpy array detection results of pnet 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]) # 对PNet送进来的图像进行处理,填充+resize [dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph] = self.pad(dets, w, h) num_boxes = dets.shape[0] cropped_ims = np.zeros((num_boxes, 24, 24, 3), 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, :, :, :] = (cv2.resize(tmp, (24, 24)) - 127.5) / 128 # cls_scores : num_data*2 # reg: num_data*4 # landmark: num_data*10 cls_scores, reg, _ = self.rnet_detector.predict( cropped_ims) # 获得概率值、偏移系数值 cls_scores = cls_scores[:, 1] keep_inds = np.where(cls_scores > self.thresh[1])[0] if len(keep_inds) > 0: boxes = dets[keep_inds] # PNet输出的区域赋值给boxes boxes[:, 4] = cls_scores[keep_inds] reg = reg[keep_inds] # landmark = landmark[keep_inds] else: return None, None, None keep = py_nms(boxes, 0.6) boxes = boxes[keep] boxes_c = self.calibrate_box(boxes, reg[keep]) # 计算微调之后的边框 return boxes, boxes_c, None