code: def rectangle(nrows, ncols, dtype=np.uint8, *, decomposition=None):
      """Generates a flat, rectangular-shaped footprint.
  
      Every pixel in the rectangle generated for a given width and given height
      belongs to the neighborhood.
  
      Parameters
      ----------
      nrows : int
          The number of rows of the rectangle.
      ncols : int
          The number of columns of the rectangle.
  
      Other Parameters
      ----------------
      dtype : data-type, optional
          The data type of the footprint.
      decomposition : {None, 'separable', 'sequence'}, optional
          If None, a single array is returned. For 'sequence', a tuple of smaller
          footprints is returned. Applying this series of smaller footprints will
          given an identical result to a single, larger footprint, but often with
          better computational performance. See Notes for more details.
          With 'separable', this function uses separable 1D footprints for each
          axis. Whether 'sequence' or 'separable' is computationally faster may
          be architecture-dependent.
  
      Returns
      -------
      footprint : ndarray or tuple
          A footprint consisting only of ones, i.e. every pixel belongs to the
          neighborhood. When `decomposition` is None, this is just a
          numpy.ndarray. Otherwise, this will be a tuple whose length is equal to
          the number of unique structuring elements to apply (see Notes for more
          detail)
  
      Notes
      -----
      When `decomposition` is not None, each element of the `footprint`
      tuple is a 2-tuple of the form ``(ndarray, num_iter)`` that specifies a
      footprint array and the number of iterations it is to be applied.
  
      For binary morphology, using ``decomposition='sequence'``
      was observed to give better performance, with the magnitude of the
      performance increase rapidly increasing with footprint size. For grayscale
      morphology with rectangular footprints, it is recommended to use
      ``decomposition=None`` since the internal SciPy functions that are called
      already have a fast implementation based on separable 1D sliding windows.
  
      The `sequence` decomposition mode only supports odd valued `nrows` and
      `ncols`. If either `nrows` or `ncols` is even, the sequence used will be
      identical to ``decomposition='separable'``.
  
      - The use of ``width`` and ``height`` has been deprecated in
        version 0.18.0. Use ``nrows`` and ``ncols`` instead.
      """
      if (
          decomposition is None
      ):  # TODO: check optimal width setting here
          return np.ones((nrows, ncols), dtype=dtype)
  
      even_rows = nrows % 2 == 0
      even_cols = ncols % 2 == 0
      if decomposition == "separable" or even_rows or even_cols:
          sequence = [
              (np.ones((nrows, 1), dtype=dtype), 1),
              (np.ones((1, ncols), dtype=dtype), 1),
          ]
      elif decomposition == "sequence":
          # this branch only support odd nrows, ncols
          sq_size = 3
          sq_reps = _decompose_size(min(nrows, ncols), sq_size)
          sequence = [(np.ones((3, 3), dtype=dtype), sq_reps)]
          if nrows > ncols:
              nextra = nrows - ncols
              sequence.append(
                  (np.ones((nextra + 1, 1), dtype=dtype), 1)
              )
          elif ncols > nrows:
              nextra = ncols - nrows
              sequence.append(
                  (np.ones((1, nextra + 1), dtype=dtype), 1)
              )
      else:
          raise ValueError(
              f"Unrecognized decomposition: {decomposition}"
          )
      return tuple(sequence)
  
imports: import os
  from collections.abc import Sequence
  from numbers import Integral
  import numpy
  from ..None import draw
  from skimage import morphology
label_desc: Use image node_id 6 for calling a global function with example usage: rectangle(nrows, ncols, dtype) and returns: tuple, np