示例#1
0
def main(args):
    det = hdface_detector(use_cuda=False)
    checkpoint = torch.load(args.model_path)
    plfd_backbone = PFLDInference().cuda()
    plfd_backbone.load_state_dict(checkpoint)
    plfd_backbone.eval()
    plfd_backbone = plfd_backbone.cuda()
    transform = transforms.Compose([transforms.ToTensor()])
    root = args.images_path

    path_list = glob.glob(os.path.join(root, "*.jpg"))
    # cap = cv2.VideoCapture("")
    for img_path in path_list:
        img = cv2.imread(img_path)

        height, width = img.shape[:2]
        img_det = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        result = det.detect_face(img_det)
        for i in range(len(result)):
            box = result[i]['box']
            cls = result[i]['cls']
            pts = result[i]['pts']
            x1, y1, x2, y2 = box
            cv2.rectangle(img, (x1, y1), (x2, y2), (255, 255, 25))
            w = x2 - x1 + 1
            h = y2 - y1 + 1

            size_w = int(max([w, h]) * 0.9)
            size_h = int(max([w, h]) * 0.9)
            cx = x1 + w // 2
            cy = y1 + h // 2
            x1 = cx - size_w // 2
            x2 = x1 + size_w
            y1 = cy - int(size_h * 0.4)
            y2 = y1 + size_h

            left = 0
            top = 0
            bottom = 0
            right = 0
            if x1 < 0:
                left = -x1
            if y1 < 0:
                top = -y1
            if x2 >= width:
                right = x2 - width
            if y2 >= height:
                bottom = y2 - height

            x1 = max(0, x1)
            y1 = max(0, y1)

            x2 = min(width, x2)
            y2 = min(height, y2)

            cropped = img[y1:y2, x1:x2]
            print(top, bottom, left, right)
            cropped = cv2.copyMakeBorder(cropped, top, bottom, left, right,
                                         cv2.BORDER_CONSTANT, 0)

            cropped = cv2.resize(cropped, (112, 112))

            input = cv2.resize(cropped, (112, 112))
            input = cv2.cvtColor(input, cv2.COLOR_BGR2RGB)
            input = transform(input).unsqueeze(0).cuda()
            pose, landmarks = plfd_backbone(input)
            poses = pose.cpu().detach().numpy()[0] * 180 / np.pi
            pre_landmark = landmarks[0]
            pre_landmark = pre_landmark.cpu().detach().numpy().reshape(
                -1, 2) * [size_w, size_h]
            cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0))
            for (x, y) in pre_landmark.astype(np.int32):
                cv2.circle(img, (x1 - left + x, y1 - bottom + y), 1,
                           (255, 255, 0), 1)
            plot_pose_cube(img,
                           poses[0],
                           poses[1],
                           poses[2],
                           tdx=pts['nose'][0],
                           tdy=pts['nose'][1],
                           size=(x2 - x1) // 2)
        cv2.imshow('0', img)
        cv2.waitKey(0)
示例#2
0
def validate(wlfw_val_dataloader, plfd_backbone, args):
    plfd_backbone.eval()

    with torch.no_grad():
        losses_NME = []
        losses_ION = []

        for img, landmark_gt, attribute_gt, euler_angle_gt, type_flag in wlfw_val_dataloader:
            img.requires_grad = False
            img = img.cuda(non_blocking=True)

            attribute_gt.requires_grad = False
            attribute_gt = attribute_gt.cuda(non_blocking=True)

            landmark_gt.requires_grad = False
            landmark_gt = landmark_gt.cuda(non_blocking=True)

            euler_angle_gt.requires_grad = False
            euler_angle_gt = euler_angle_gt.cuda(non_blocking=True)

            type_flag.requires_grad = False
            type_flag = type_flag.cuda()

            plfd_backbone = plfd_backbone.cuda()
            pose, landmarks = plfd_backbone(img)

            if args.is_show:
                landms_tmp = landmarks.cpu().numpy()
                landms_tmp = landms_tmp.reshape(landms_tmp.shape[0], -1, 2)
                for i in range(landms_tmp.shape[0]):
                    # show result
                    show_img = np.array(
                        np.transpose(img[i].cpu().numpy(), (1, 2, 0)))
                    show_img = (show_img * 255).astype(np.uint8)
                    np.clip(show_img, 0, 255)
                    draw = show_img.copy()
                    yaw = pose[i][0] * 180 / np.pi
                    pitch = pose[i][1] * 180 / np.pi
                    roll = pose[i][2] * 180 / np.pi
                    pre_landmark = landms_tmp[i] * [112, 112]
                    for (x, y) in pre_landmark.astype(np.int8):
                        cv2.circle(draw, (int(x), int(y)), 1, (0, 255, 0), 1)
                    draw = plot_pose_cube(draw,
                                          yaw,
                                          pitch,
                                          roll,
                                          size=draw.shape[0] // 2)

                    cv2.imshow("check", draw)
                    cv2.waitKey(0)

            landms_const = torch.tensor(-2).cuda()
            pose_const = torch.tensor(-1).cuda()

            pos1 = type_flag == landms_const

            landmarks = landmarks[pos1]
            landmark_gt = landmark_gt[pos1]
            if landmarks.shape[0] > 0:
                loss = torch.mean(
                    torch.sqrt(torch.sum((landmark_gt - landmarks)**2, dim=1)))

                landmarks = landmarks.cpu().numpy()
                landmarks = landmarks.reshape(landmarks.shape[0], -1, 2)
                landmark_gt = landmark_gt.reshape(landmark_gt.shape[0], -1,
                                                  2).cpu().numpy()

                error_diff = np.sum(np.sqrt(
                    np.sum((landmark_gt - landmarks)**2, axis=2)),
                                    axis=1)
                interocular_distance = np.sqrt(
                    np.sum((landmarks[:, 60, :] - landmarks[:, 72, :])**2,
                           axis=1))
                # interpupil_distance = np.sqrt(np.sum((landmarks[:, 60, :] - landmarks[:, 72, :]) ** 2, axis=1))
                error_norm = np.mean(error_diff / interocular_distance)

                losses_NME.append(loss.cpu().numpy())
                losses_ION.append(error_norm)
        print("NME", np.mean(losses_NME))
        print("ION", np.mean(losses_ION))
示例#3
0
def main():
    args = get_args()
    img_size = args.img_size
    pts_68_index = pts_68_index_table()

    output_db_root = os.path.join(args.output, args.db)
    if not os.path.exists(output_db_root):
        os.makedirs(output_db_root)

    onlyfiles_mat = [
        f for f in listdir(join(args.root, args.db))
        if isfile(join(args.root, args.db, f))
        and join(args.root, args.db, f).endswith('.mat')
    ]
    onlyfiles_jpg = [
        f for f in listdir(join(args.root, args.db))
        if isfile(join(args.root, args.db, f))
        and join(args.root, args.db, f).endswith('.jpg')
    ]
    # AFW_134212_1_0_pts
    onlyfiles_mat.sort()
    onlyfiles_jpg.sort()
    print(len(onlyfiles_jpg))
    print(len(onlyfiles_mat))
    out_imgs = []
    out_poses = []
    with open(os.path.join(args.output, args.db + '_label.txt'), 'w') as fw:
        for i in tqdm(range(len(onlyfiles_jpg))):

            img_name = onlyfiles_jpg[i]
            mat_name = onlyfiles_mat[i]

            save_path = args.db + '/' + img_name

            # print(img_name)
            # print(lds_name)
            # print(mat_name)
            img_name_split = img_name.split('.')
            mat_name_split = mat_name.split('.')

            if img_name_split[0] != mat_name_split[0]:
                print('Mismatched!')
                sys.exit()

            mat_contents = sio.loadmat(
                os.path.join(args.root, args.db, mat_name))
            img = cv2.imread(os.path.join(args.root, args.db, img_name))
            pose_para = mat_contents['Pose_Para'][0]
            pt2d = mat_contents['pt2d']
            pt2d_x = pt2d[0, :]
            pt2d_y = pt2d[1, :]
            # I found negative value in AFLW2000. It need to be removed.
            pt2d_idx = pt2d_x > 0.0
            pt2d_idy = pt2d_y > 0.0

            pt2d_id = pt2d_idx
            if sum(pt2d_idx) > sum(pt2d_idy):
                pt2d_id = pt2d_idy

            pt2d_x = pt2d_x[pt2d_id]
            pt2d_y = pt2d_y[pt2d_id]

            img_h = img.shape[0]
            img_w = img.shape[1]

            # Crop the face loosely
            x_min = int(min(pt2d_x))
            x_max = int(max(pt2d_x))
            y_min = int(min(pt2d_y))
            y_max = int(max(pt2d_y))

            h = y_max - y_min
            w = x_max - x_min

            # ad = 0.4
            ad = random.uniform(0.12, 0.3)
            x_min = max(int(x_min - ad * w), 0)
            x_max = min(int(x_max + ad * w), img_w - 1)
            y_min = max(int(y_min - ad * h), 0)
            y_max = min(int(y_max + ad * h), img_h - 1)

            img = img[y_min:y_max, x_min:x_max]

            # Checking the cropped image

            w_factor = img_size / float(img.shape[1])
            h_factor = img_size / float(img.shape[0])
            img = cv2.resize(img, (img_size, img_size))
            save_img = img.copy()
            landmarks98 = np.array([-256.0 for i in range(98 * 2)])
            for k in range(pt2d_x.shape[0]):
                center = (int((pt2d_x[k] - x_min) * w_factor),
                          int((pt2d_y[k] - y_min) * h_factor))
                cv2.circle(img, center, 1, (255, 255, 0), 1)

            pitch = pose_para[0] * 180 / np.pi
            yaw = pose_para[1] * 180 / np.pi
            roll = pose_para[2] * 180 / np.pi

            euler_angles = np.array([yaw, pitch, roll])
            plot_pose_cube(img, yaw, pitch, roll, tdx=50, tdy=50, size=50)

            landmark_str = ' '.join(
                list(map(str,
                         landmarks98.reshape(-1).tolist())))
            euler_angles_str = ' '.join(
                list(map(str,
                         euler_angles.reshape(-1).tolist())))
            label = '{} {} 0 0 0 0 0 0 {}\n'.format(save_path, landmark_str,
                                                    euler_angles_str)
            fw.write(label)
            cv2.imwrite(os.path.join(output_db_root, img_name), save_img)
            if args.is_show:
                cv2.imshow('check', img)
                cv2.waitKey(0)
示例#4
0
def validate(wlfw_val_dataloader, plfd_backbone):
    plfd_backbone.eval()

    with torch.no_grad():
        losses = []
        losses_ION = []

        for img, landmark_gt, attribute_gt, euler_angle_gt in wlfw_val_dataloader:
            img.requires_grad = False
            img = img.cuda(non_blocking=True)

            attribute_gt.requires_grad = False
            attribute_gt = attribute_gt.cuda(non_blocking=True)

            landmark_gt.requires_grad = False
            landmark_gt = landmark_gt.cuda(non_blocking=True)

            euler_angle_gt.requires_grad = False
            euler_angle_gt = euler_angle_gt.cuda(non_blocking=True)

            plfd_backbone = plfd_backbone.cuda()

            pose, landmarks = plfd_backbone(img)

            loss = torch.mean(
                torch.sqrt(torch.sum((landmark_gt - landmarks)**2, dim=1))
                )

            landmarks = landmarks.cpu().numpy()
            landmarks = landmarks.reshape(landmarks.shape[0], -1, 2)
            landmark_gt = landmark_gt.reshape(landmark_gt.shape[0], -1, 2).cpu().numpy()
            error_diff = np.sum(np.sqrt(np.sum((landmark_gt - landmarks) ** 2, axis=2)), axis=1)
            interocular_distance = np.sqrt(np.sum((landmarks[:, 60, :] - landmarks[:,72, :]) ** 2, axis=1))
            # interpupil_distance = np.sqrt(np.sum((landmarks[:, 60, :] - landmarks[:, 72, :]) ** 2, axis=1))
            error_norm = np.mean(error_diff / interocular_distance)

            # show result 
            show_img = np.array(np.transpose(img[0].cpu().numpy(), (1, 2, 0)))
            show_img = (show_img * 255).astype(np.uint8)
            np.clip(show_img, 0, 255)

            pre_landmark = landmarks[0] * [112, 112]

            # cv2.imwrite("xxx.jpg", show_img)
            # img_clone = cv2.imread("xxx.jpg")
            draw  = show_img.copy()
            yaw = pose[0][0] * 180 / np.pi
            pitch = pose[0][1] * 180 / np.pi
            roll = pose[0][2] * 180 / np.pi
            for (x, y) in pre_landmark.astype(np.int8):
                # print("x:{0:}, y:{1:}".format(x, y))
                cv2.circle(draw, (int(x), int(y)), 1, (0,255,0), 1)
            draw = plot_pose_cube(draw, yaw, pitch, roll, size=draw.shape[0] // 2)

            # cv2.imshow("xx.jpg", draw)
            # cv2.waitKey(0)

        losses.append(loss.cpu().numpy())
        losses_ION.append(error_norm)

        print("NME", np.mean(losses))
        print("ION", np.mean(losses_ION))
示例#5
0
def main():
    args = get_args()
    img_size = args.img_size
    pts_68_index = pts_68_index_table()

    output_db_root = os.path.join(args.output, args.db)
    if not os.path.exists(output_db_root):
        os.makedirs(output_db_root)

    onlyfiles_mat = [
        f for f in listdir(join(args.root, args.db))
        if isfile(join(args.root, args.db, f))
        and join(args.root, args.db, f).endswith('.mat')
    ]
    onlyfiles_jpg = [
        f for f in listdir(join(args.root, args.db))
        if isfile(join(args.root, args.db, f))
        and join(args.root, args.db, f).endswith('.jpg')
    ]
    # AFW_134212_1_0_pts
    onlyfiles_mat.sort()
    onlyfiles_jpg.sort()
    print(len(onlyfiles_jpg))
    print(len(onlyfiles_mat))
    out_imgs = []
    out_poses = []
    with open(os.path.join(args.output, args.db + '_label.txt'), 'w') as fw:
        for i in tqdm(range(len(onlyfiles_jpg))):

            img_name = onlyfiles_jpg[i]
            lds_name = img_name.split('/')[-1].replace(".jpg", "_pts.mat")
            mat_name = onlyfiles_mat[i]

            # print(img_name)
            # print(lds_name)
            # print(mat_name)
            img_name_split = img_name.split('.')
            mat_name_split = mat_name.split('.')

            if img_name_split[0] != mat_name_split[0]:
                print('Mismatched!')
                sys.exit()

            mat_contents = sio.loadmat(
                os.path.join(args.root, args.db, mat_name))
            lds_contents = sio.loadmat(
                os.path.join(args.root, 'landmarks', args.db, lds_name))
            img = cv2.imread(os.path.join(args.root, args.db, img_name))
            pose_para = mat_contents['Pose_Para'][0]
            pt2d = mat_contents['pt2d']
            pt2d_real = lds_contents['pts_2d']
            pt2d_x = pt2d_real[:, 0]
            pt2d_y = pt2d_real[:, 1]

            img_h = img.shape[0]
            img_w = img.shape[1]

            # Crop the face loosely
            x_min = int(min(pt2d_x))
            x_max = int(max(pt2d_x))
            y_min = int(min(pt2d_y))
            y_max = int(max(pt2d_y))

            h = y_max - y_min
            w = x_max - x_min

            # ad = 0.4
            ad = random.uniform(0.05, 0.2)
            x_min = max(int(x_min - ad * w), 0)
            x_max = min(int(x_max + ad * w), img_w - 1)
            y_min = max(int(y_min - ad * h), 0)
            y_max = min(int(y_max + ad * h), img_h - 1)

            img = img[y_min:y_max, x_min:x_max]

            # Checking the cropped image

            w_factor = img_size / float(img.shape[1])
            h_factor = img_size / float(img.shape[0])
            img = cv2.resize(img, (img_size, img_size))
            save_img = img.copy()
            landmarks98 = np.array([-256.0 for i in range(98 * 2)])
            for k in range(pt2d_x.shape[0]):
                center = (int((pt2d_x[k] - x_min) * w_factor),
                          int((pt2d_y[k] - y_min) * h_factor))
                cv2.circle(img, center, 1, (255, 255, 0), 1)
                points = (center[0] / 112.0, center[1] / 112.0)
                landmarks98[pts_68_index[str(k)] * 2 + 0] = points[0]
                landmarks98[pts_68_index[str(k)] * 2 + 1] = points[1]
                # cv2.putText(img, str(pts_68_index[str(k)]), center, cv2.FONT_HERSHEY_COMPLEX_SMALL, 0.8, (0,255,0), 1)
            pitch = pose_para[0] * 180 / np.pi
            yaw = pose_para[1] * 180 / np.pi
            roll = pose_para[2] * 180 / np.pi

            euler_angles = np.array([yaw, pitch, roll])
            plot_pose_cube(img, yaw, pitch, roll, tdx=100, tdy=100, size=50)

            landmark_str = ' '.join(
                list(map(str,
                         landmarks98.reshape(-1).tolist())))
            euler_angles_str = ' '.join(
                list(map(str,
                         euler_angles.reshape(-1).tolist())))

            img_name = img_name.replace(' ', '')
            save_path = args.db + '/' + img_name
            label = '{} {} 0 0 0 0 0 0 {}\n'.format(save_path, landmark_str,
                                                    euler_angles_str)
            fw.write(label)
            cv2.imwrite(os.path.join(output_db_root, img_name), save_img)
            if args.is_show:
                cv2.imshow('check', img)
                cv2.waitKey(0)