def transform_wb(
    x: "torch.Tensor",
    x_adv: "torch.Tensor",
    mask: "torch.Tensor",
    xform: tuple[float, float, float, int, float, float, float, float, float],
    net_size: tuple[int, int],
    clip_min: float,
    clip_max: float,
    pts: np.ndarray | None,
) -> "torch.Tensor":
    """
    Get transformed image, white-box setting.

    :param x: Original input image.
    :param x_adv: Input image to transform, possibly attacked.
    :param mask: Mask image.
    :param xform: Transformation parameters.
    :param net_size: Size of the image for the network.
    :param clip_min: Minimum value of an example.
    :param clip_max: Maximum value of an example.
    :param pts: A set of points that will set the crop size in the perspective transform.
    :return: Transformed image.
    """
    import torch
    import cv2
    from kornia.enhance import adjust_gamma

    angle, dist, gamma, blur, crop_percent, crop_off_x, crop_off_y, obj_width, focal = xform
    x_adv = torch.clamp(x_adv, 0.0, 1.0)

    if blur != 0:
        kernel = np.zeros((blur * 2 - 1, blur * 2 - 1))
        kernel[blur - 1, blur - 1] = 1
        kernel = cv2.GaussianBlur(kernel, (blur, blur), 0).astype(float)
        kernel = kernel[blur // 2 : blur // 2 + blur, blur // 2 : blur // 2 + blur]
        kernel = kernel[np.newaxis, :, :]
        kernel = np.repeat(kernel[np.newaxis, :, :, :], x_adv.size()[1], axis=0)
        kernel_torch = torch.from_numpy(kernel)
        blur_torch = torch.nn.Conv2d(
            in_channels=x_adv.size()[1],
            out_channels=x_adv.size()[1],
            kernel_size=blur,
            groups=x_adv.size()[1],
            bias=False,
            padding=blur // 2,
        )
        blur_torch.weight.data = kernel_torch.to(x_adv.dtype)
        blur_torch.weight.requires_grad = False
        blur_torch = blur_torch.to(x_adv.device)
        # the below is done this way to match the black box implementation
        pert = torch.where(mask > 0.5, x_adv, torch.zeros(x_adv.size()).to(mask.device))
        x_adv = torch.where(mask > 0.5, blur_torch(pert), x)
    else:
        x_adv = torch.where(mask > 0.5, x_adv, x)

    x_adv = torch.clamp(x_adv, 0.0, 1.0)
    dist = dist2pixels(dist, x_adv.size()[2], obj_width)
    focal = dist2pixels(focal, x_adv.size()[2], obj_width)
    x_adv = get_perspective_transform_wb(
        x_adv, angle, x_adv.size()[3], x_adv.size()[2], focal, dist, crop_percent, crop_off_x, crop_off_y, pts
    )

    # Gamma
    x_adv = adjust_gamma(x_adv, gamma)

    return convert_to_network_wb(x_adv, net_size, clip_min, clip_max)

    Get transformed image, white-box setting.

    :param x: Original input image.
    :param x_adv: Input image to transform, possibly attacked.
    :param mask: Mask image.
    :param xform: Transformation parameters.
    :param net_size: Size of the image for the network.
    :param clip_min: Minimum value of an example.
    :param clip_max: Maximum value of an example.
    :param pts: A set of points that will set the crop size in the perspective transform.
    :return: Transformed image.
    
art/attacks/evasion/graphite/utils.py