コード例 #1
0
ファイル: losses.py プロジェクト: sudarsanGyrus/3D_Pose_VIBE
def body_fitting_loss(body_pose,
                      betas,
                      model_joints,
                      camera_t,
                      camera_center,
                      joints_2d,
                      joints_conf,
                      pose_prior,
                      focal_length=5000,
                      sigma=100,
                      pose_prior_weight=4.78,
                      shape_prior_weight=5,
                      angle_prior_weight=15.2,
                      output='sum'):
    """
    Loss function for body fitting
    """
    # pose_prior_weight = 1.
    # shape_prior_weight = 1.
    # angle_prior_weight = 1.
    # sigma = 10.

    batch_size = body_pose.shape[0]
    rotation = torch.eye(3, device=body_pose.device).unsqueeze(0).expand(
        batch_size, -1, -1)
    projected_joints = perspective_projection(model_joints, rotation, camera_t,
                                              focal_length, camera_center)

    # Weighted robust reprojection error
    reprojection_error = gmof(projected_joints - joints_2d, sigma)
    reprojection_loss = (joints_conf**2) * reprojection_error.sum(dim=-1)

    # Pose prior loss
    pose_prior_loss = (pose_prior_weight**2) * pose_prior(body_pose, betas)

    # Angle prior for knees and elbows
    angle_prior_loss = (angle_prior_weight**
                        2) * angle_prior(body_pose).sum(dim=-1)

    # Regularizer to prevent betas from taking large values
    shape_prior_loss = (shape_prior_weight**2) * (betas**2).sum(dim=-1)

    total_loss = reprojection_loss.sum(
        dim=-1) + pose_prior_loss + angle_prior_loss + shape_prior_loss
    print(f'joints: {reprojection_loss[0].sum().item():.2f}, '
          f'pose_prior: {pose_prior_loss[0].item():.2f}, '
          f'angle_prior: {angle_prior_loss[0].item():.2f}, '
          f'shape_prior: {shape_prior_loss[0].item():.2f}')

    if output == 'sum':
        return total_loss.sum()
    elif output == 'reprojection':
        return reprojection_loss
コード例 #2
0
ファイル: losses.py プロジェクト: sudarsanGyrus/3D_Pose_VIBE
def camera_fitting_loss(model_joints,
                        camera_t,
                        camera_t_est,
                        camera_center,
                        joints_2d,
                        joints_conf,
                        focal_length=5000,
                        depth_loss_weight=100):
    """
    Loss function for camera optimization.
    """

    # Project model joints
    batch_size = model_joints.shape[0]
    rotation = torch.eye(3, device=model_joints.device).unsqueeze(0).expand(
        batch_size, -1, -1)
    projected_joints = perspective_projection(model_joints, rotation, camera_t,
                                              focal_length, camera_center)

    op_joints = ['OP RHip', 'OP LHip', 'OP RShoulder', 'OP LShoulder']
    op_joints_ind = [JOINT_IDS[joint] for joint in op_joints]
    gt_joints = ['Right Hip', 'Left Hip', 'Right Shoulder', 'Left Shoulder']
    gt_joints_ind = [JOINT_IDS[joint] for joint in gt_joints]
    reprojection_error_op = (joints_2d[:, op_joints_ind] -
                             projected_joints[:, op_joints_ind])**2
    reprojection_error_gt = (joints_2d[:, gt_joints_ind] -
                             projected_joints[:, gt_joints_ind])**2

    # Check if for each example in the batch all 4 OpenPose detections are valid, otherwise use the GT detections
    # OpenPose joints are more reliable for this task, so we prefer to use them if possible
    is_valid = (joints_conf[:, op_joints_ind].min(dim=-1)[0][:, None, None] >
                0).float()
    reprojection_loss = (is_valid * reprojection_error_op +
                         (1 - is_valid) * reprojection_error_gt).sum(dim=(1,
                                                                          2))

    # Loss that penalizes deviation from depth estimate
    depth_loss = (depth_loss_weight**
                  2) * (camera_t[:, 2] - camera_t_est[:, 2])**2

    total_loss = reprojection_loss + depth_loss
    return total_loss.sum()
コード例 #3
0
def project_3d_to_2d(joints_3d, bbox, pred_cam):
    joints_3d_tensor = torch.from_numpy(joints_3d).unsqueeze(0)
    focal_length = 5000
    camera_center = torch.zeros(2).unsqueeze(0)
    rotation = torch.eye(3).unsqueeze(0)
    pred_camera = torch.from_numpy(pred_cam).unsqueeze(0)  # shape: (1, 3)
    pred_cam_t = torch.stack([
        pred_camera[:, 1], pred_camera[:, 2], 2 * 5000. /
        (224. * pred_camera[:, 0] + 1e-9)
    ],
                             dim=-1)

    joints_2d = perspective_projection(joints_3d_tensor, rotation, pred_cam_t,
                                       focal_length,
                                       camera_center).squeeze().numpy()

    # scale back to the original image
    scaled_joints_2d = joints_2d * bbox[2:] / 224 + bbox[:2]
    scaled_joints_2d = scaled_joints_2d.astype(int)
    return scaled_joints_2d
コード例 #4
0
    joints_3d_body_center = (joints_3d_shoulder_left + joints_3d_shoulder_right
                             + joints_3d_hip_middle) / 3

    body_orientation_starting_point = joints_3d_body_center
    joints_3d_body_direction = body_orientation_starting_point - np.cross(
        (joints_3d_shoulder_left - joints_3d_hip_middle),
        (joints_3d_shoulder_right - joints_3d_hip_middle)).reshape(1, 3)
    joints_3d = np.vstack(
        (joints_3d, body_orientation_starting_point.reshape(1, 3),
         joints_3d_body_direction))

    joints_3d_tensor = torch.from_numpy(joints_3d).unsqueeze(0)

    joints_2d = perspective_projection(joints_3d_tensor, rotation, pred_cam_t,
                                       focal_length,
                                       camera_center).squeeze().numpy()

    # extraction of head orientation
    mid_front = (joints_2d[15:16] + joints_2d[16:17]) / 2  # (Leye + Reye) / 2
    mid_back = (joints_2d[42:43] + joints_2d[43:44]) / 2  # (Jaw + Head) / 2

    joints_2d = np.vstack((joints_2d, mid_front, mid_back))

    # scale back to the original image
    scaled_joints_2d = joints_2d * bbox[2:] / 224 + bbox[:2]
    scaled_joints_2d = scaled_joints_2d.astype(int)

    for i in range(len(scaled_joints_2d)):
        img = cv2.circle(img, (scaled_joints_2d[i, 0], scaled_joints_2d[i, 1]),
                         2, (0, 0, 255), -1)
コード例 #5
0
ファイル: losses.py プロジェクト: sudarsanGyrus/3D_Pose_VIBE
def temporal_body_fitting_loss(body_pose,
                               betas,
                               model_joints,
                               camera_t,
                               camera_center,
                               joints_2d,
                               joints_conf,
                               pose_prior,
                               focal_length=5000,
                               sigma=100,
                               pose_prior_weight=4.78,
                               shape_prior_weight=5,
                               angle_prior_weight=15.2,
                               smooth_2d_weight=0.01,
                               smooth_3d_weight=1.0,
                               output='sum'):
    """
    Loss function for body fitting
    """
    # pose_prior_weight = 1.
    # shape_prior_weight = 1.
    # angle_prior_weight = 1.
    # sigma = 10.

    batch_size = body_pose.shape[0]
    rotation = torch.eye(3, device=body_pose.device).unsqueeze(0).expand(
        batch_size, -1, -1)
    projected_joints = perspective_projection(model_joints, rotation, camera_t,
                                              focal_length, camera_center)

    # Weighted robust reprojection error
    reprojection_error = gmof(projected_joints - joints_2d, sigma)
    reprojection_loss = (joints_conf**2) * reprojection_error.sum(dim=-1)

    # Pose prior loss
    pose_prior_loss = (pose_prior_weight**2) * pose_prior(body_pose, betas)

    # Angle prior for knees and elbows
    angle_prior_loss = (angle_prior_weight**
                        2) * angle_prior(body_pose).sum(dim=-1)

    # Regularizer to prevent betas from taking large values
    shape_prior_loss = (shape_prior_weight**2) * (betas**2).sum(dim=-1)

    total_loss = reprojection_loss.sum(
        dim=-1) + pose_prior_loss + angle_prior_loss + shape_prior_loss

    # Smooth 2d joint loss
    joint_conf_diff = joints_conf[1:]
    joints_2d_diff = projected_joints[1:] - projected_joints[:-1]
    smooth_j2d_loss = (joint_conf_diff**2) * joints_2d_diff.abs().sum(dim=-1)
    smooth_j2d_loss = torch.cat([
        torch.zeros(1, smooth_j2d_loss.shape[1], device=body_pose.device),
        smooth_j2d_loss
    ]).sum(dim=-1)
    smooth_j2d_loss = (smooth_2d_weight**2) * smooth_j2d_loss

    # Smooth 3d joint loss
    joints_3d_diff = model_joints[1:] - model_joints[:-1]
    # joints_3d_diff = joints_3d_diff * 100.
    smooth_j3d_loss = (joint_conf_diff**2) * joints_3d_diff.abs().sum(dim=-1)
    smooth_j3d_loss = torch.cat([
        torch.zeros(1, smooth_j3d_loss.shape[1], device=body_pose.device),
        smooth_j3d_loss
    ]).sum(dim=-1)
    smooth_j3d_loss = (smooth_3d_weight**2) * smooth_j3d_loss

    total_loss += smooth_j2d_loss + smooth_j3d_loss

    # print(f'joints: {reprojection_loss[0].sum().item():.2f}, '
    #       f'pose_prior: {pose_prior_loss[0].item():.2f}, '
    #       f'angle_prior: {angle_prior_loss[0].item():.2f}, '
    #       f'shape_prior: {shape_prior_loss[0].item():.2f}, '
    #       f'smooth_j2d: {smooth_j2d_loss.sum().item()}, '
    #       f'smooth_j3d: {smooth_j3d_loss.sum().item()}')

    if output == 'sum':
        return total_loss.sum()
    elif output == 'reprojection':
        return reprojection_loss