code: def degradation_bsrgan_variant(image, sf=4, isp_model=None):
      """
      This is the degradation model of BSRGAN from the paper
      "Designing a Practical Degradation Model for Deep Blind Image Super-Resolution"
      ----------
      sf: scale factor
      isp_model: camera ISP model
      Returns
      -------
      img: low-quality patch, size: lq_patchsizeXlq_patchsizeXC, range: [0, 1]
      hq: corresponding high-quality patch, size: (lq_patchsizexsf)X(lq_patchsizexsf)XC, range: [0, 1]
      """
      image = util.uint2single(image)
      isp_prob, jpeg_prob, scale2_prob = 0.25, 0.9, 0.25
      sf_ori = sf
  
      h1, w1 = image.shape[:2]
      image = image.copy()[
          : w1 - w1 % sf, : h1 - h1 % sf, ...
      ]  # mod crop
      h, w = image.shape[:2]
  
      hq = image.copy()
  
      if sf == 4 and random.random() < scale2_prob:  # downsample1
          if np.random.rand() < 0.5:
              image = cv2.resize(
                  image,
                  (
                      int(1 / 2 * image.shape[1]),
                      int(1 / 2 * image.shape[0]),
                  ),
                  interpolation=random.choice([1, 2, 3]),
              )
          else:
              image = util.imresize_np(image, 1 / 2, True)
          image = np.clip(image, 0.0, 1.0)
          sf = 2
  
      shuffle_order = random.sample(range(7), 7)
      idx1, idx2 = shuffle_order.index(2), shuffle_order.index(3)
      if idx1 > idx2:  # keep downsample3 last
          shuffle_order[idx1], shuffle_order[idx2] = (
              shuffle_order[idx2],
              shuffle_order[idx1],
          )
  
      for i in shuffle_order:
          if i == 0:
              image = add_blur(image, sf=sf)
  
          # elif i == 1:
          #     image = add_blur(image, sf=sf)
  
          if i == 0:
              pass
  
          elif i == 2:
              a, b = image.shape[1], image.shape[0]
              # downsample2
              if random.random() < 0.8:
                  sf1 = random.uniform(1, 2 * sf)
                  image = cv2.resize(
                      image,
                      (
                          int(1 / sf1 * image.shape[1]),
                          int(1 / sf1 * image.shape[0]),
                      ),
                      interpolation=random.choice([1, 2, 3]),
                  )
              else:
                  k = fspecial(
                      "gaussian", 25, random.uniform(0.1, 0.6 * sf)
                  )
                  k_shifted = shift_pixel(k, sf)
                  k_shifted = (
                      k_shifted / k_shifted.sum()
                  )  # blur with shifted kernel
                  image = ndimage.filters.convolve(
                      image,
                      np.expand_dims(k_shifted, axis=2),
                      mode="mirror",
                  )
                  image = image[
                      0::sf, 0::sf, ...
                  ]  # nearest downsampling
  
              image = np.clip(image, 0.0, 1.0)
  
          elif i == 3:
              # downsample3
              image = cv2.resize(
                  image,
                  (int(1 / sf * a), int(1 / sf * b)),
                  interpolation=random.choice([1, 2, 3]),
              )
              image = np.clip(image, 0.0, 1.0)
  
          elif i == 4:
              # add Gaussian noise
              image = add_Gaussian_noise(
                  image, noise_level1=1, noise_level2=2
              )
  
          elif i == 5:
              # add JPEG noise
              if random.random() < jpeg_prob:
                  image = add_JPEG_noise(image)
          #
          # elif i == 6:
          #     # add processed camera sensor noise
          #     if random.random() < isp_prob and isp_model is not None:
          #         with torch.no_grad():
          #             img, hq = isp_model.forward(img.copy(), hq)
  
      # add final JPEG compression noise
      image = add_JPEG_noise(image)
      image = util.single2uint(image)
      example = {"image": image}
      return example
  
imports: import numpy
  import cv2
  import torch
  from functools import partial
  import random
  from scipy import ndimage
  import scipy
  import scipy.stats
  from scipy.interpolate import interp2d
  from scipy.linalg import orth
  import albumentations
  import ldm.modules.image_degradation.utils_image
label_desc: Use image node_id 24 for calling a global function with example usage: degradation_bsrgan_variant(image, sf, isp_model) and returns: example