code: def __distinct_binary_object_correspondences(
      reference, result, connectivity=1
  ):
      """
      Determines all distinct (where connectivity is defined by the connectivity parameter
      passed to scipy's `generate_binary_structure`) binary objects in both of the input
      parameters and returns a 1to1 mapping from the labelled objects in reference to the
      corresponding (whereas a one-voxel overlap suffices for correspondence) objects in
      result.
  
      All stems from the problem, that the relationship is non-surjective many-to-many.
  
      @return (labelmap1, labelmap2, n_lables1, n_labels2, labelmapping2to1)
      """
      result = numpy.atleast_1d(result.astype(numpy.bool_))
      reference = numpy.atleast_1d(reference.astype(numpy.bool_))
  
      # binary structure
      footprint = generate_binary_structure(result.ndim, connectivity)
  
      # label distinct binary objects
      labelmap1, n_obj_result = label(result, footprint)
      labelmap2, n_obj_reference = label(reference, footprint)
  
      # find all overlaps from labelmap2 to labelmap1; collect one-to-one relationships and store all one-two-many for later processing
      slicers = find_objects(
          labelmap2
      )  # get windows of labelled objects
      mapping = (
          dict()
      )  # mappings from labels in labelmap2 to corresponding object labels in labelmap1
      used_labels = (
          set()
      )  # set to collect all already used labels from labelmap2
      one_to_many = list()  # list to collect all one-to-many mappings
      for l1id, slicer in enumerate(
          slicers
      ):  # iterate over object in labelmap2 and their windows
          l1id += 1  # labelled objects have ids sarting from 1
          bobj = (l1id) == labelmap2[
              slicer
          ]  # find binary object corresponding to the label1 id in the segmentation
          l2ids = numpy.unique(
              labelmap1[slicer][bobj]
          )  # extract all unique object identifiers at the corresponding positions in the reference (i.e. the mapping)
          l2ids = l2ids[
              0 != l2ids
          ]  # remove background identifiers (=0)
          if 1 == len(
              l2ids
          ):  # one-to-one mapping: if target label not already used, add to final list of object-to-object mappings and mark target label as used
              l2id = l2ids[0]
              if not l2id in used_labels:
                  mapping[l1id] = l2id
                  used_labels.add(l2id)
          elif 1 < len(
              l2ids
          ):  # one-to-many mapping: store relationship for later processing
              one_to_many.append((l1id, set(l2ids)))
  
      # process one-to-many mappings, always choosing the one with the least labelmap2 correspondences first
      while True:
          one_to_many = [
              (l1id, l2ids - used_labels) for l1id, l2ids in one_to_many
          ]  # remove already used ids from all sets
          one_to_many = [
              x for x in one_to_many if x[1]
          ]  # remove empty sets
          one_to_many = sorted(
              one_to_many, key=lambda x: len(x[1])
          )  # sort by set length
          if 0 == len(one_to_many):
              break
          l2id = one_to_many[0][
              1
          ].pop()  # select an arbitrary target label id from the shortest set
          mapping[
              one_to_many[0][0]
          ] = l2id  # add to one-to-one mappings
          used_labels.add(l2id)  # mark target label as used
          one_to_many = one_to_many[
              1:
          ]  # delete the processed set from all sets
  
      return (
          labelmap1,
          labelmap2,
          n_obj_result,
          n_obj_reference,
          mapping,
      )
  
imports: import numpy
  from scipy.ndimage import _ni_support
  from scipy.ndimage import distance_transform_edt, binary_erosion, generate_binary_structure
  from scipy.ndimage import label, find_objects
  from scipy.stats import pearsonr
label_desc: Use image node_id 21 for calling a global function with example usage: __distinct_binary_object_correspondences(reference, result, connectivity) and returns: labelmap1,  labelmap2,  n_obj_result,  n_obj_reference,  mapping