code: def compute_earth_movers_distance(
      ground_truth_image,
      test_image,
      mask=None,
      decimation_method: mio.DM = mio.DM.KMEANS,
      max_distance: int = 250,
      max_points: int = 250,
      penalize_missing: bool = False,
  ):
      """Compute the earthmovers distance between two sets of objects
  
      src_objects - move pixels from these objects
  
      dest_objects - move pixels to these objects
  
      returns the earth mover's distance
      """
  
      # Check that the inputs are binary
      if not np.array_equal(
          ground_truth_image, ground_truth_image.astype(bool)
      ):
          raise ValueError("ground_truth_image is not a binary image")
  
      if not np.array_equal(test_image, test_image.astype(bool)):
          raise ValueError("test_image is not a binary image")
  
      if mask is None:
          mask = np.ones_like(ground_truth_image, bool)
  
      # Covert 3D image to 2D long
      if ground_truth_image.ndim > 2:
          ground_truth_image = ground_truth_image.reshape(
              -1, ground_truth_image.shape[-1]
          )
  
          test_image = test_image.reshape(-1, test_image.shape[-1])
  
          mask = mask.reshape(-1, mask.shape[-1])
  
      # ground truth labels
      dest_labels = scipy.ndimage.label(
          ground_truth_image & mask, np.ones((3, 3), bool)
      )[0]
      dest_labelset = cast_labels_to_label_set(dest_labels)
      dest_ijv = convert_labels_to_ijv(dest_labels, validate=False)
      dest_ijv_indices = indices_from_ijv(dest_ijv, validate=False)
      dest_count = count_from_ijv(
          dest_ijv, indices=dest_ijv_indices, validate=False
      )
      dest_areas = areas_from_ijv(
          dest_ijv, indices=dest_ijv_indices, validate=False
      )
  
      # test labels
      src_labels = scipy.ndimage.label(
          test_image & mask, np.ones((3, 3), bool)
      )[0]
      src_labelset = cast_labels_to_label_set(src_labels)
      src_ijv = convert_labels_to_ijv(src_labels, validate=False)
      src_ijv_indices = indices_from_ijv(src_ijv, validate=False)
      src_count = count_from_ijv(
          src_ijv, indices=src_ijv_indices, validate=False
      )
      src_areas = areas_from_ijv(
          src_ijv, indices=src_ijv_indices, validate=False
      )
  
      #
      # if either foreground set is empty, the emd is the penalty.
      #
      for lef_count, right_areas in (
          (src_count, dest_areas),
          (dest_count, src_areas),
      ):
          if lef_count == 0:
              if penalize_missing:
                  return np.sum(right_areas) * max_distance
              else:
                  return 0
      if decimation_method == mio.DM.KMEANS:
          isrc, jsrc = get_kmeans_points(src_ijv, dest_ijv, max_points)
          idest, jdest = isrc, jsrc
      elif decimation_method == mio.DM.SKELETON:
          isrc, jsrc = get_skeleton_points(
              src_labelset, src_labels.shape, max_points
          )
          idest, jdest = get_skeleton_points(
              dest_labelset, dest_labels.shape, max_points
          )
      else:
          raise TypeError(
              "Unknown type for decimation method: %s"
              % decimation_method
          )
      src_weights, dest_weights = [
          get_weights(i, j, get_labels_mask(labelset, shape))
          for i, j, labelset, shape in (
              (isrc, jsrc, src_labelset, src_labels.shape),
              (idest, jdest, dest_labelset, dest_labels.shape),
          )
      ]
      ioff, joff = [
          src[:, np.newaxis] - dest[np.newaxis, :]
          for src, dest in ((isrc, idest), (jsrc, jdest))
      ]
      c = np.sqrt(ioff * ioff + joff * joff).astype(np.int32)
      c[c > max_distance] = max_distance
      extra_mass_penalty = max_distance if penalize_missing else 0
  
      emd = centrosome.fastemd.emd_hat_int32(
          src_weights.astype(np.int32),
          dest_weights.astype(np.int32),
          c,
          extra_mass_penalty=extra_mass_penalty,
      )
      return emd
  
imports: import numpy
  import scipy
  import centrosome
  import centrosome.cpmorphology
  import centrosome.filter
  import centrosome.propagate
  import centrosome.fastemd
  from sklearn.cluster import KMeans
  from cellprofiler_library.opts import measureimageoverlap
  from cellprofiler_library.functions.segmentation import convert_labels_to_ijv
  from cellprofiler_library.functions.segmentation import indices_from_ijv
  from cellprofiler_library.functions.segmentation import count_from_ijv
  from cellprofiler_library.functions.segmentation import areas_from_ijv
  from cellprofiler_library.functions.segmentation import cast_labels_to_label_set
label_desc: Use image node_id 3 for calling a global function with example usage: compute_earth_movers_distance(ground_truth_image, test_image, mask, decimation_method, max_distance, max_points, penalize_missing) and returns: emd, unknown, int