def get_perspective_transform_wb(
    img: "torch.Tensor",
    angle: float,
    width: int,
    height: int,
    focal: float,
    dist: float,
    crop_percent: float,
    crop_off_x: float,
    crop_off_y: float,
    pts: np.ndarray | None = None,
) -> "torch.Tensor":
    """
    Computes perspective transform for whitebox attack.

    :param img: Input image.
    :param angle: Angle to rotate.
    :param width: Width of image.
    :param height: Height of image.
    :param focal: Focal length.
    :param dist: Distance for transform.
    :param crop_percent: Percentage for cropping.
    :param crop_off_x: Cropping x offset.
    :param crop_off_y: Cropping y offset.
    :param pts: pts to include in the crop.
    :return: Transformed image.
    """
    import torch
    from kornia.geometry.transform import warp_perspective

    perspective_mat, crop_x, crop_y = _get_perspective_transform(
        angle, width, height, focal, dist, crop_percent, crop_off_x, crop_off_y, pts
    )
    dst = warp_perspective(
        img,
        torch.from_numpy(perspective_mat).float().to(img.device).unsqueeze(0),
        (crop_y, crop_x),
        align_corners=True,
        padding_mode="border",
    )
    return dst

    Computes perspective transform for whitebox attack.

    :param img: Input image.
    :param angle: Angle to rotate.
    :param width: Width of image.
    :param height: Height of image.
    :param focal: Focal length.
    :param dist: Distance for transform.
    :param crop_percent: Percentage for cropping.
    :param crop_off_x: Cropping x offset.
    :param crop_off_y: Cropping y offset.
    :param pts: pts to include in the crop.
    :return: Transformed image.
    
art/attacks/evasion/graphite/utils.py