code: def extract_patches_2d(
      image, patch_size, max_patches=None, random_state=None
  ):
      """Reshape a 2D image into a collection of patches
  
      The resulting patches are allocated in a dedicated array.
  
      Read more in the :ref:`User Guide <image_feature_extraction>`.
  
      Parameters
      ----------
      image : array, shape = (image_height, image_width) or
          (image_height, image_width, n_channels)
          The original image data. For color images, the last dimension specifies
          the channel: a RGB image would have `n_channels=3`.
  
      patch_size : tuple of ints (patch_height, patch_width)
          the dimensions of one patch
  
      max_patches : integer or float, optional default is None
          The maximum number of patches to extract. If max_patches is a float
          between 0 and 1, it is taken to be a proportion of the total number
          of patches.
  
      random_state : int or RandomState
          Pseudo number generator state used for random sampling to use if
          `max_patches` is not None.
  
      Returns
      -------
      patches : array, shape = (n_patches, patch_height, patch_width) or
           (n_patches, patch_height, patch_width, n_channels)
           The collection of patches extracted from the image, where `n_patches`
           is either `max_patches` or the total number of patches that can be
           extracted.
  
      Examples
      --------
  
      >>> from sklearn.feature_extraction import image
      >>> one_image = np.arange(16).reshape((4, 4))
      >>> one_image
      array([[ 0,  1,  2,  3],
             [ 4,  5,  6,  7],
             [ 8,  9, 10, 11],
             [12, 13, 14, 15]])
      >>> patches = image.extract_patches_2d(one_image, (2, 2))
      >>> print(patches.shape)
      (9, 2, 2)
      >>> patches[0]
      array([[0, 1],
             [4, 5]])
      >>> patches[1]
      array([[1, 2],
             [5, 6]])
      >>> patches[8]
      array([[10, 11],
             [14, 15]])
      """
      i_h, i_w = image.shape[:2]
      p_h, p_w = patch_size
  
      if p_h > i_h:
          raise ValueError(
              "Height of the patch should be less than the height"
              " of the image."
          )
  
      if p_w > i_w:
          raise ValueError(
              "Width of the patch should be less than the width"
              " of the image."
          )
  
      image = check_array(image, allow_nd=True)
      image = image.reshape((i_h, i_w, -1))
      n_colors = image.shape[-1]
  
      extracted_patches = extract_patches(
          image, patch_shape=(p_h, p_w, n_colors), extraction_step=1
      )
  
      n_patches = _compute_n_patches(i_h, i_w, p_h, p_w, max_patches)
      if max_patches:
          rng = check_random_state(random_state)
          i_s = rng.randint(i_h - p_h + 1, size=n_patches)
          j_s = rng.randint(i_w - p_w + 1, size=n_patches)
          patches = extracted_patches[i_s, j_s, 0]
      else:
          patches = extracted_patches
  
      patches = patches.reshape(-1, p_h, p_w, n_colors)
      # remove the color dimension if useless
      if patches.shape[-1] == 1:
          return patches.reshape((n_patches, p_h, p_w))
      else:
          return patches
  
imports: from itertools import product
  import numbers
  import numpy
  from scipy import sparse
  from numpy.lib.stride_tricks import as_strided
  from ..utils import check_array, check_random_state
  from ..utils.fixes import astype
  from ..base import BaseEstimator
label_desc: Use image node_id 9 for calling a global function with example usage: extract_patches_2d(image, patch_size, max_patches, random_state) and returns: patches, patches