code: def setup(self, shape, footprint, radius, decomposition):
      rng = np.random.default_rng(123)
      # Make an image that is mostly True, with random isolated False areas
      # (so it will not become fully False for any of the footprints).
      self.image = rng.standard_normal(shape) < 3.5
      fp_func = getattr(morphology, footprint)
      allow_sequence = (
          "rectangle",
          "square",
          "diamond",
          "octagon",
          "disk",
      )
      allow_separable = ("rectangle", "square")
      allow_crosses = ("disk", "ellipse")
      allow_decomp = tuple(
          set(allow_sequence)
          | set(allow_separable)
          | set(allow_crosses)
      )
      footprint_kwargs = {}
      if (
          decomposition == "sequence"
          and footprint not in allow_sequence
      ):
          raise NotImplementedError("decomposition unimplemented")
      elif (
          decomposition == "separable"
          and footprint not in allow_separable
      ):
          raise NotImplementedError(
              "separable decomposition unavailable"
          )
      elif (
          decomposition == "crosses" and footprint not in allow_crosses
      ):
          raise NotImplementedError(
              "separable decomposition unavailable"
          )
      if footprint in allow_decomp:
          footprint_kwargs["decomposition"] = decomposition
      if footprint in ["rectangle", "square"]:
          size = 2 * radius + 1
          self.footprint = fp_func(size, **footprint_kwargs)
      elif footprint in ["diamond", "disk"]:
          self.footprint = fp_func(radius, **footprint_kwargs)
      elif footprint == "star":
          # set a so bounding box size is approximately 2*radius + 1
          # size will be 2*a + 1 + 2*floor(a / 2)
          a = max((2 * radius) // 3, 1)
          self.footprint = fp_func(a, **footprint_kwargs)
      elif footprint == "octagon":
          # overall size is m + 2 * n
          # so choose m = n so that overall size is ~ 2*radius + 1
          m = n = max((2 * radius) // 3, 1)
          self.footprint = fp_func(m, n, **footprint_kwargs)
      elif footprint == "ellipse":
          if radius > 1:
              # make somewhat elliptical
              self.footprint = fp_func(
                  radius - 1, radius + 1, **footprint_kwargs
              )
          else:
              self.footprint = fp_func(
                  radius, radius, **footprint_kwargs
              )
  
imports: import numpy
  from numpy.lib import NumpyVersion
  import skimage
  from skimage import data, morphology, util
label_desc: Use image node_id 1 for calling the BinaryMorphology2D obj's underlying member method code with example usage: obj.setup(shape, footprint, radius, decomposition) without return types