def d_perspective_camera_d_shape_parameters(shape_pc_uv, warped_uv, camera):
    """
    Calculates the derivative of the perspective projection with respect to the
    shape parameters.

    Parameters
    ----------
    shape_pc_uv : ``(n_points, 3, n_parameters)`` `ndarray`
        The (sampled) basis of the shape model.
    warped_uv : ``(n_points, 3)`` `ndarray`
        The shape instance with the view transform (rotation and translation)
        applied on it.
    camera : `menpo3d.camera.PerspectiveCamera`
        The camera object that is responsible of projecting the model to the
        image plane.

    Returns
    -------
    dw_da : ``(2, n_shape_parameters, n_points)`` `ndarray`
        The derivative of the perspective camera transform with respect to
        the shape parameters.
    """
    n_points, n_dims, n_parameters = shape_pc_uv.shape
    assert n_dims == 3
    z = warped_uv[:, (2)]
    dw_da = camera.rotation_transform.apply(shape_pc_uv.transpose(0, 2, 1)).T
    dw_da[:2] -= warped_uv[:, :2].T[:, (None)] * dw_da[2] / z
    return camera.projection_transform.focal_length * dw_da[:2] / z
