Class ObjectMerger

java.lang.Object
qupath.lib.objects.utils.ObjectMerger
All Implemented Interfaces:
ObjectProcessor

public class ObjectMerger extends Object implements ObjectProcessor
Helper class for merging objects using different criteria.

This is designed to be used for post-processing a segmentation, to help resolve tile boundaries.

Since:
v0.5.0
  • Method Details

    • merge

      @Deprecated public List<PathObject> merge(Collection<? extends PathObject> pathObjects)
      Deprecated.
      Merge the input objects using the merging strategy.
      Parameters:
      pathObjects - the input objects for which merges should be calculated
      Returns:
      a list of objects, with the same number or fewer than the input
    • process

      public List<PathObject> process(Collection<? extends PathObject> pathObjects)
      Calculate the result of applying the merging strategy to the input objects.

      The output list will contain the same number of objects or fewer. Objects that are not merged will be returned unchanged, while objects that are merged will be replaced by a new objects with a new ROI.

      New objects will be assigned new IDs. Classifications will be preserved, but other measurements and properties will not be.

      No guarantees are made about the mutability or ordering of the returned list.

      Specified by:
      process in interface ObjectProcessor
      Parameters:
      pathObjects - the input objects for which merges should be calculated
      Returns:
      a list of objects, with the same number or fewer than the input
    • createSharedTileBoundaryMerger

      public static ObjectMerger createSharedTileBoundaryMerger(double sharedBoundaryThreshold, MeasurementStrategy measurementStrategy)
      Create an object merger that uses a shared boundary IoU criterion and default overlap tolerance.

      Objects will be merged if they share a common boundary and have the same classification. A small overlap tolerance is used to compensate for sub-pixel misalignment of tiles.

      This is intended for post-processing a tile-based segmentation, where the tiling has been strictly enforced (i.e. any objects have been clipped to non-overlapping tile boundaries).

      Parameters:
      sharedBoundaryThreshold - minimum intersection-over-union (IoU) proportion of the possibly-clipped boundary for merging
      measurementStrategy - strategy for merging measurements from merged objects.
      Returns:
      an object merger that uses a shared boundary criterion
      See Also:
    • createSharedTileBoundaryMerger

      public static ObjectMerger createSharedTileBoundaryMerger(double sharedBoundaryThreshold)
      See Also:
    • createSharedTileBoundaryMerger

      public static ObjectMerger createSharedTileBoundaryMerger(double sharedBoundaryThreshold, double overlapTolerance, MeasurementStrategy measurementStrategy)
      Create an object merger that uses a shared boundary IoU criterion and overlap tolerance.

      Objects will be merged if they share a common boundary and have the same classification. A small overlap tolerance can be used to compensate for slight misalignment of tiles.

      After identifying a common boundary line between ROIs, the ROI boundaries are intersected with the line, and the two intersections are subsequently intersected with each other to determine the shared intersection. The length of the shared intersection is then used to compute the intersection over union.

      This is intended for post-processing a tile-based segmentation, where the tiling has been strictly enforced (i.e. any objects have been clipped to non-overlapping tile boundaries).

      Parameters:
      sharedBoundaryThreshold - minimum intersection-over-union (IoU) proportion of the possibly-clipped boundary * for merging
      overlapTolerance - amount of overlap allowed between objects, in pixels. If zero, the boundary must be shared exactly. A typical value is 0.125, which allows for a small, sub-pixel overlap.
      measurementStrategy - strategy for merging measurements from merged objects.
      Returns:
      an object merger that uses a shared boundary criterion and overlap tolerance
    • createSharedTileBoundaryMerger

      public static ObjectMerger createSharedTileBoundaryMerger(double sharedBoundaryThreshold, double overlapTolerance)
      See Also:
    • createSharedClassificationMerger

      public static ObjectMerger createSharedClassificationMerger(MeasurementStrategy measurementStrategy)
      Create an object merger that can merge together any objects with similar ROIs (e.g. points, areas), the same classification, and are on the same image plane.

      The ROIs do not need to be touching; the resulting merged objects can have discontinuous ROIs.

      Parameters:
      measurementStrategy - strategy for merging measurements from merged objects.
      Returns:
      an object merger that can merge together any objects with similar ROIs and the same classification
    • createSharedClassificationMerger

      public static ObjectMerger createSharedClassificationMerger()
      See Also:
    • createTouchingMerger

      public static ObjectMerger createTouchingMerger(MeasurementStrategy measurementStrategy)
      Create an object merger that can merge together any objects with similar ROIs (e.g. points, areas) that also touch one another.

      Objects must also have the same classification and be on the same image plane to be mergeable.

      Note that this is a strict criterion following the Java Topology Suite definition of touching, which requires that the boundaries of the geometries intersect, but the interiors do not intersect.

      This strictness can cause unexpected results due to floating point precision issues, unless it is certain that the ROIs are perfectly aligned (e.g they are generated using integer coordinates on a pixel grid).

      If this is not the case, createSharedTileBoundaryMerger(double, double) is usually preferable, since it can include a small overlap tolerance.

      Parameters:
      measurementStrategy - strategy for merging measurements from merged objects.
      Returns:
      an object merger that can merge together any objects with similar ROIs and the same classification
      See Also:
    • createTouchingMerger

      public static ObjectMerger createTouchingMerger()
      See Also:
    • createIoUMerger

      public static ObjectMerger createIoUMerger(double iouThreshold, MeasurementStrategy measurementStrategy)
      Create an object merger that can merge together any objects with sufficiently large intersection over union.

      Objects must also have the same classification and be on the same image plane to be mergeable.

      IoU is calculated using Java Topology Suite intersection, union, and getArea calls.

      This merger assumes that you are using an OutputHandler that doesn't clip to tile boundaries (only to region requests) and that you are using sufficient padding to ensure that objects are being detected in more than on tile/region request. You should probably also remove any objects that touch the regionRequest boundaries, as these will probably be clipped, and merging them will result in weirdly shaped detections.

      Parameters:
      iouThreshold - Intersection over union threshold; any pairs with values greater than or equal to this are merged.
      measurementStrategy - strategy for merging measurements from merged objects.
      Returns:
      an object merger that can merge together any objects with sufficiently high IoU and the same classification
    • createIoUMerger

      public static ObjectMerger createIoUMerger(double iouThreshold)
      See Also:
    • createIoMinMerger

      public static ObjectMerger createIoMinMerger(double iomThreshold, MeasurementStrategy measurementStrategy)
      Create an object merger that can merge together any objects with sufficiently large intersection over minimum area (IoMin). This is similar to IoU, but uses the minimum area of the two objects as the denominator.

      This is useful in the (common) case where we are happy for small objects falling within larger objects to be swallowed up by the larger object.

      Objects must also have the same classification and be on the same image plane to be mergeable.

      IoM is calculated using Java Topology Suite intersection, union, and getArea calls.

      This merger assumes that you are using an OutputHandler that doesn't clip to tile boundaries (only to region requests) and that you are using sufficient padding to ensure that objects are being detected in more than on tile/region request. You should probably also remove any objects that touch the regionRequest boundaries, as these will probably be clipped, and merging them will result in weirdly shaped detections.

      Parameters:
      iomThreshold - Intersection over minimum threshold; any pairs with values greater than or equal to this are merged.
      measurementStrategy - strategy for merging measurements from merged objects.
      Returns:
      an object merger that can merge together any objects with sufficiently high IoM and the same classification
      Implementation Note
      This method does not currently merge objects with zero area. It is assumed that they will be handled separately.
    • createIoMinMerger

      public static ObjectMerger createIoMinMerger(double iomThreshold)
      See Also: