code: def preprocess_image(
      image,
      target_size: Tuple[int, int] = None,
      grayscale: bool = False,
  ) -> np.ndarray:
      """
      Take as input an image as numpy array or Pillow format. Returns an array version of optionally resized and grayed
      image.
  
      Args:
          image: numpy array or a pillow image.
          target_size: Size to resize the input image to.
          grayscale: A boolean indicating whether to grayscale the image.
  
      Returns:
          A numpy array of the processed image.
      """
      if isinstance(image, np.ndarray):
          image = image.astype("uint8")
          image_pil = Image.fromarray(image)
  
      elif isinstance(image, Image.Image):
          image_pil = image
      else:
          raise ValueError(
              "Input is expected to be a numpy array or a pillow object!"
          )
  
      if target_size:
          image_pil = image_pil.resize(target_size, Image.LANCZOS)
  
      if grayscale:
          image_pil = image_pil.convert("L")
  
      return np.array(image_pil).astype("uint8")
  
file_path: imagededup/imagededup/utils/image_utils.py
imports: from pathlib import PurePath
  from typing import List, Union, Tuple
  import numpy
  from PIL import Image
  from imagededup.utils.logger import return_logger
label_desc: Use image node_id 6 for calling a global function with example usage: preprocess_image(image, target_size, grayscale) and returns: np