code: def run(self, workspace):
      names = ["Branches", "Endpoints"]
  
      input_image_name = self.skeleton_name.value
  
      image_set = workspace.image_set
  
      input_image = image_set.get_image(
          input_image_name, must_be_grayscale=True
      )
  
      dimensions = input_image.dimensions
  
      pixels = input_image.pixel_data
  
      pixels = pixels > 0
  
      branch_nodes = branches(pixels)
  
      endpoint_nodes = endpoints(pixels)
  
      statistics = self.measure(input_image, workspace)
  
      if self.show_window:
          workspace.display_data.skeleton = pixels
  
          a = numpy.copy(branch_nodes).astype(numpy.uint16)
          b = numpy.copy(endpoint_nodes).astype(numpy.uint16)
  
          a[a == 1] = 1
          b[b == 1] = 2
  
          nodes = skimage.segmentation.join_segmentations(a, b)
  
          workspace.display_data.nodes = nodes
  
          workspace.display_data.dimensions = dimensions
  
          workspace.display_data.names = names
  
          workspace.display_data.statistics = statistics
  
imports: import numpy
  import scipy.ndimage
  import skimage.segmentation
  import skimage.util
  from cellprofiler_core.module import Module
  from cellprofiler_core.setting.subscriber import ImageSubscriber
label_desc: Use image node_id 3 for calling the MeasureImageSkeleton obj's underlying member method code with example usage: obj.run(workspace) without return types