code: def random_shadow(
      img: torch.Tensor, opacity_range: Tuple[float, float], **kwargs
  ) -> torch.Tensor:
      """Crop and image and associated bboxes
  
      Args:
      ----
          img: image to modify
          opacity_range: the minimum and maximum desired opacity of the shadow
          **kwargs: additional arguments to pass to `create_shadow_mask`
  
      Returns:
      -------
          shaded image
      """
      shadow_mask = create_shadow_mask(img.shape[1:], **kwargs)
  
      opacity = np.random.uniform(*opacity_range)
      shadow_tensor = 1 - torch.from_numpy(shadow_mask[None, ...])
  
      # Add some blur to make it believable
      k = 7 + 2 * int(4 * np.random.rand(1))
      sigma = np.random.uniform(0.5, 5.0)
      shadow_tensor = F.gaussian_blur(
          shadow_tensor, k, sigma=[sigma, sigma]
      )
  
      return opacity * shadow_tensor * img + (1 - opacity) * img
  
file_path: doctr/doctr/transforms/functional/pytorch.py
imports: from copy import deepcopy
  from typing import Tuple
  import numpy
  import torch
  from torchvision.transforms import functional
  from doctr.utils.geometry import rotate_abs_geoms
  from .base import create_shadow_mask, crop_boxes
label_desc: Use image node_id 4 for calling a global function with example usage: random_shadow(img, opacity_range) and returns: unknown