docstr: Separate objects based on local maxima or distance transform
  
  workspace - get the image from here
  
  labeled_image - image labeled by scipy.ndimage.label
  
  object_count  - # of objects in image
  
  returns revised labeled_image, object count, maxima_suppression_size,
  LoG threshold and filter diameter
code: def separate_neighboring_objects(
      self, workspace, labeled_image, object_count
  ):
      """Separate objects based on local maxima or distance transform
  
      workspace - get the image from here
  
      labeled_image - image labeled by scipy.ndimage.label
  
      object_count  - # of objects in image
  
      returns revised labeled_image, object count, maxima_suppression_size,
      LoG threshold and filter diameter
      """
      if self.advanced and (
          self.unclump_method == UN_NONE
          or self.watershed_method == WA_NONE
      ):
          return labeled_image, object_count, 7
  
      cpimage = workspace.image_set.get_image(
          self.x_name.value, must_be_grayscale=True
      )
      image = cpimage.pixel_data
      mask = cpimage.mask
  
      blurred_image = self.smooth_image(image, mask)
      if self.size_range.min > 10 and (
          self.basic or self.low_res_maxima.value
      ):
          image_resize_factor = 10.0 / float(self.size_range.min)
          if self.basic or self.automatic_suppression.value:
              maxima_suppression_size = 7
          else:
              maxima_suppression_size = (
                  self.maxima_suppression_size.value
                  * image_resize_factor
                  + 0.5
              )
          reported_maxima_suppression_size = (
              maxima_suppression_size / image_resize_factor
          )
      else:
          image_resize_factor = 1.0
          if self.basic or self.automatic_suppression.value:
              maxima_suppression_size = self.size_range.min / 1.5
          else:
              maxima_suppression_size = (
                  self.maxima_suppression_size.value
              )
          reported_maxima_suppression_size = maxima_suppression_size
      maxima_mask = centrosome.cpmorphology.strel_disk(
          max(1, maxima_suppression_size - 0.5)
      )
      distance_transformed_image = None
      if self.basic or self.unclump_method == UN_INTENSITY:
          # Remove dim maxima
          maxima_image = self.get_maxima(
              blurred_image,
              labeled_image,
              maxima_mask,
              image_resize_factor,
          )
      elif self.unclump_method == UN_SHAPE:
          if self.fill_holes == FH_NEVER:
              # For shape, even if the user doesn't want to fill holes,
              # a point far away from the edge might be near a hole.
              # So we fill just for this part.
              foreground = (
                  centrosome.cpmorphology.fill_labeled_holes(
                      labeled_image
                  )
                  > 0
              )
          else:
              foreground = labeled_image > 0
          distance_transformed_image = (
              scipy.ndimage.distance_transform_edt(foreground)
          )
          # randomize the distance slightly to get unique maxima
          numpy.random.seed(0)
          distance_transformed_image += numpy.random.uniform(
              0, 0.001, distance_transformed_image.shape
          )
          maxima_image = self.get_maxima(
              distance_transformed_image,
              labeled_image,
              maxima_mask,
              image_resize_factor,
          )
      else:
          raise ValueError(
              "Unsupported local maxima method: %s"
              % self.unclump_method.value
          )
  
      # Create the image for watershed
      if self.basic or self.watershed_method == WA_INTENSITY:
          # use the reverse of the image to get valleys at peaks
          watershed_image = 1 - image
      elif self.watershed_method == WA_SHAPE:
          if distance_transformed_image is None:
              distance_transformed_image = (
                  scipy.ndimage.distance_transform_edt(
                      labeled_image > 0
                  )
              )
          watershed_image = -distance_transformed_image
          watershed_image = watershed_image - numpy.min(watershed_image)
      elif self.watershed_method == WA_PROPAGATE:
          # No image used
          pass
      else:
          raise NotImplementedError(
              "Watershed method %s is not implemented"
              % self.watershed_method.value
          )
      #
      # Create a marker array where the unlabeled image has a label of
      # -(nobjects+1)
      # and every local maximum has a unique label which will become
      # the object's label. The labels are negative because that
      # makes the watershed algorithm use FIFO for the pixels which
      # yields fair boundaries when markers compete for pixels.
      #
      self.labeled_maxima, object_count = scipy.ndimage.label(
          maxima_image, numpy.ones((3, 3), bool)
      )
      if self.advanced and self.watershed_method == WA_PROPAGATE:
          (
              watershed_boundaries,
              distance,
          ) = centrosome.propagate.propagate(
              numpy.zeros(self.labeled_maxima.shape),
              self.labeled_maxima,
              labeled_image != 0,
              1.0,
          )
      else:
          markers_dtype = (
              numpy.int16
              if object_count < numpy.iinfo(numpy.int16).max
              else numpy.int32
          )
          markers = numpy.zeros(watershed_image.shape, markers_dtype)
          markers[self.labeled_maxima > 0] = -self.labeled_maxima[
              self.labeled_maxima > 0
          ]
  
          #
          # Some labels have only one maker in them, some have multiple and
          # will be split up.
          #
  
          watershed_boundaries = skimage.segmentation.watershed(
              connectivity=numpy.ones((3, 3), bool),
              image=watershed_image,
              markers=markers,
              mask=labeled_image != 0,
          )
  
          watershed_boundaries = -watershed_boundaries
  
      return (
          watershed_boundaries,
          object_count,
          reported_maxima_suppression_size,
      )
  
imports: import math
  import cellprofiler_core.module.image_segmentation
  import cellprofiler_core.object
  import centrosome.cpmorphology
  import centrosome.outline
  import centrosome.propagate
  import centrosome.threshold
  import numpy
  import scipy.ndimage
  import scipy.sparse
  import skimage.morphology
  import skimage.segmentation
  from cellprofiler_core.setting import Binary, Color
  from cellprofiler_core.setting.choice import Choice
  from cellprofiler_core.setting.range import IntegerRange
  from cellprofiler_core.setting.text import Integer, Float
  import cellprofiler.gui.help
  import cellprofiler.gui.help.content
  from cellprofiler.modules import _help, threshold
label_desc: Use image node_id 12 for calling the IdentifyPrimaryObjects obj's underlying member method code with example usage: obj.separate_neighboring_objects(workspace, labeled_image, object_count) and returns: watershed_boundaries,  object_count,  reported_maxima_suppression_size, labeled_image,  object_count,  int