def rnet_boxes(img, rnet, bounding_boxes, thresholds=THRESHOLDS, nms_thresholds=NMS_THRESHOLDS, show_boxes=True): rnet.eval() img_boxes = get_image_boxes(bounding_boxes, img, size=24) img_boxes = torch.FloatTensor(img_boxes) img_boxes = img_boxes.to( torch.device('cuda' if torch.cuda.is_available() else 'cpu')) output = rnet(img_boxes) probs = output[0].data.cpu().numpy() # shape [n_boxes, 1] offsets = output[1].data.cpu().numpy() # shape [n_boxes, 4] keep = np.where(probs[:, 0] > thresholds[1])[0] bounding_boxes = bounding_boxes[keep] bounding_boxes[:, 4] = probs[keep, 0].reshape((-1, )) offsets = offsets[keep] keep = nms(bounding_boxes, nms_thresholds[1]) bounding_boxes = bounding_boxes[keep] bounding_boxes = calibrate_box(bounding_boxes, offsets[keep]) bounding_boxes = convert_to_square(bounding_boxes) bounding_boxes[:, 0:4] = np.round(bounding_boxes[:, 0:4]) if show_boxes: show_bboxes(img, bounding_boxes, []).show() return bounding_boxes
def onet_test(args, img_path): img = load_img(img_path) net = load_net(args, 'pnet') output = net((transforms.ToTensor()(img.resize( (12, 12), Image.BILINEAR))).unsqueeze(0)) print('prob:', output[0]) show_bboxes(img, [[(250 * t.item() + 250 * (i > 1)) for i, t in enumerate(output[1][0])]]).show()
def pnet_boxes(img, pnet, min_face_size=MIN_FACE_SIZE, thresholds=THRESHOLDS, nms_thresholds=NMS_THRESHOLDS, show_boxes=True): pnet.eval() width, height = img.size min_length = min(height, width) # print('img min_length is {}'.format(min_length)) min_detection_size = 12 factor = 0.707 # sqrt(0.5) scales = [] # min_face_size 哪来的? m = min_detection_size / min_face_size # 缩放原图使得最小脸尺寸为12pix min_length *= m # 将图片从最小脸为12pix到整张图为12pix,保存对应的缩放比例,都为小于1的数? factor_count = 0 while min_length > min_detection_size: scales.append(m * factor ** factor_count) min_length *= factor factor_count += 1 # STAGE 1 bounding_boxes = [] for s in scales: # run P-Net on different scales boxes = run_first_stage(img, pnet, scale=s, threshold=thresholds[0]) bounding_boxes.append(boxes) # bounding_boxes shape:[scales,boxes_num_each_sale,5] # 把每个scale找到的框框全部打开堆在一起 # [total_boxes_num, 5] 是list bounding_boxes = [i for i in bounding_boxes if i is not None] # print(bounding_boxes) # bounding_boxes = np.array(bounding_boxes) # print(bounding_boxes.shape, img.size) try: _ = bounding_boxes[0] # print('bounding_boxes:{}'.format(len(bounding_boxes))) # print('bounding_boxes[0]:{}'.format(len(bounding_boxes[0]))) except Exception: print(bounding_boxes) img.show() if len(bounding_boxes) == 0: return None bounding_boxes = np.vstack(bounding_boxes) # print(bounding_boxes.shape) keep = nms(bounding_boxes[:, 0:5], nms_thresholds[0]) bounding_boxes = bounding_boxes[keep] # print('bounding_boxes:{}'.format(bounding_boxes[:, 4] > 0.5)) # 根据 w、h 对 x1,y1,x2,y2 的位置进行微调 bounding_boxes = calibrate_box(bounding_boxes[:, 0:5], bounding_boxes[:, 5:]) # 将检测出的框转化成矩形 bounding_boxes = convert_to_square(bounding_boxes) bounding_boxes[:, 0:4] = np.round(bounding_boxes[:, 0:4]) # print('bounding_boxes:{}'.format(bounding_boxes[:, 4] > 0.5)) # print('bounding_boxes:', len(bounding_boxes), bounding_boxes) if show_boxes: show_bboxes(img, bounding_boxes, []).show() return bounding_boxes
def onet_boxes(img, onet, bounding_boxes, thresholds=THRESHOLDS, nms_thresholds=NMS_THRESHOLDS, show_boxes=True): onet.eval() img_boxes = get_image_boxes(bounding_boxes, img, size=48) if len(img_boxes) == 0: return [], [] img_boxes = torch.FloatTensor(img_boxes) img_boxes = img_boxes.to( torch.device('cuda' if torch.cuda.is_available() else 'cpu')) output = onet(img_boxes) probs = output[0].data.cpu().numpy() # shape [n_boxes, 1] offsets = output[1].data.cpu().numpy() # shape [n_boxes, 4] landmarks = output[2].data.cpu().numpy() # shape [n_boxes, 10] keep = np.where(probs[:, 0] > thresholds[2])[0] bounding_boxes = bounding_boxes[keep] # 用更大模型的置信度对原置信度进行更新 bounding_boxes[:, 4] = probs[keep, 0].reshape((-1, )) offsets = offsets[keep] landmarks = landmarks[keep] # compute landmark points width = bounding_boxes[:, 2] - bounding_boxes[:, 0] + 1.0 height = bounding_boxes[:, 3] - bounding_boxes[:, 1] + 1.0 xmin, ymin = bounding_boxes[:, 0], bounding_boxes[:, 1] # print('width:{},\nheight:{},\nxmin:{},\nymin:{}\n'.format(width, height, xmin, ymin)) # landmark[,前5个为x,后5个为y] # 在左上角坐标的基础上,通过 w,h 确定脸各关键点的坐标。 landmarks_pixel = np.zeros(landmarks.shape) landmarks_pixel[:, 0:5] = ( np.expand_dims(xmin, 1) + np.expand_dims(width, 1) * landmarks[:, 0::2]).copy() landmarks_pixel[:, 5:10] = ( np.expand_dims(ymin, 1) + np.expand_dims(height, 1) * landmarks[:, 1::2]).copy() # for i in landmarks:print(i) bounding_boxes = calibrate_box(bounding_boxes, offsets) keep = nms(bounding_boxes, nms_thresholds[2], mode='min') bounding_boxes = bounding_boxes[keep] landmarks_pixel = landmarks_pixel[keep] if show_boxes: show_bboxes(img, bounding_boxes, landmarks_pixel).show() return bounding_boxes, landmarks_pixel