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
Beispiel #2
0
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