code: def _palette_is_grayscale(pil_image):
      if pil_image.mode != "P":
          return False
      elif pil_image.info.get("transparency", None):  # see issue #475
          return False
      # get palette as an array with R, G, B columns
      # Note: starting in pillow 9.1 palettes may have less than 256 entries
      palette = np.asarray(pil_image.getpalette()).reshape((-1, 3))
      # Not all palette colors are used; unused colors have junk values.
      start, stop = pil_image.getextrema()
      valid_palette = palette[start : stop + 1]
      # Image is grayscale if channel differences (R - G and G - B)
      # are all zero.
      return np.allclose(np.diff(valid_palette), 0)
  
imports: import logging
  import threading
  import numpy
  from ..core import Format, image_as_uint
  from ..core.request import URI_FILE, URI_BYTES
  from .pillowmulti import GIFFormat, TIFFFormat
label_desc: Use image node_id 3 for calling a global function with example usage: _palette_is_grayscale(pil_image) and returns: np, False, False