text: import functools
  
  import numpy as np
  
  from .. import color
  from ..util.dtype import _convert
  
  
  __all__ = ['adapt_rgb', 'hsv_value', 'each_channel']
  
  
  def is_rgb_like(image, channel_axis=-1):
      """Return True if the image *looks* like it's RGB.
  
      This function should not be public because it is only intended to be used
      for functions that don't accept volumes as input, since checking an image's
      shape is fragile.
      """
      return (image.ndim == 3) and (image.shape[channel_axis] in (3, 4))
  
  
  def adapt_rgb(apply_to_rgb):
      """Return decorator that adapts to RGB images to a gray-scale filter.
  
      This function is only intended to be used for functions that don't accept
      volumes as input, since checking an image's shape is fragile.
  
      Parameters
      ----------
      apply_to_rgb : function
          Function that returns a filtered image from an image-filter and RGB
          image. This will only be called if the image is RGB-like.
      """
      def decorator(image_filter):
          @functools.wraps(image_filter)
          def image_filter_adapted(image, *args, **kwargs):
              if is_rgb_like(image):
                  return apply_to_rgb(image_filter, image, *args, **kwargs)
              else:
                  return image_filter(image, *args, **kwargs)
          return image_filter_adapted
      return decorator
  
  
  def hsv_value(image_filter, image, *args, **kwargs):
      """Return color image by applying `image_filter` on HSV-value of `image`.
  
      Note that this function is intended for use with `adapt_rgb`.
  
      Parameters
      ----------
      image_filter : function
          Function that filters a gray-scale image.
      image : array
          Input image. Note that RGBA images are treated as RGB.
      """
      # Slice the first three channels so that we remove any alpha channels.
      hsv = color.rgb2hsv(image[:, :, :3])
      value = hsv[:, :, 2].copy()
      value = image_filter(value, *args, **kwargs)
      hsv[:, :, 2] = _convert(value, hsv.dtype)
      return color.hsv2rgb(hsv)
  
  
  def each_channel(image_filter, image, *args, **kwargs):
      """Return color image by applying `image_filter` on channels of `image`.
  
      Note that this function is intended for use with `adapt_rgb`.
  
      Parameters
      ----------
      image_filter : function
          Function that filters a gray-scale image.
      image : array
          Input image.
      """
      c_new = [image_filter(c, *args, **kwargs)
               for c in np.moveaxis(image, -1, 0)]
      return np.stack(c_new, axis=-1)
  