public static List<PathObject> getConvexHullDetections(final PathObjectHierarchy hierarchy, final PathObject parent, final int nIterations) { Map<Point2, PathObject> pointsMap = new HashMap<>(); List<PathObject> convexDetections = new ArrayList<>(); List<PathObject> pathObjects = hierarchy.getDescendantObjects(parent, null, PathDetectionObject.class); if (pathObjects.isEmpty()) return Collections.emptyList(); // Populate the points map pointsMap.clear(); for (PathObject child : pathObjects) { if (!child.hasROI()) continue; pointsMap.put(new Point2(child.getROI().getCentroidX(), child.getROI().getCentroidY()), child); } // Determine what to remove List<Point2> points = new ArrayList<>(pointsMap.keySet()); for (int i = 0; i < nIterations; i++) { List<Point2> convexPoints = ConvexHull.getConvexHull(points); if (convexPoints != null) { for (Point2 p : convexPoints) convexDetections.add(pointsMap.get(p)); points.removeAll(convexPoints); } } return convexDetections; }
public synchronized boolean addPathObject(PathObject pathObject, boolean avoidDuplicates, boolean fireUpdate) { if (pathObject == getRootObject() || !pathObject.hasROI()) return false; return addPathObjectToList(getRootObject(), pathObject, avoidDuplicates, fireUpdate); }
/** * Add a PathObject to the cache, optionally including children. * * The lock is not acquired here! * * @param pathObject * @param includeChildren */ private void addToCache(PathObject pathObject, boolean includeChildren) { // If the cache isn't active, we can ignore this... it will be constructed when it is needed if (!isActive()) return; if (pathObject.hasROI()) { Class<? extends PathObject> cls = pathObject.getClass(); PathObjectTileMap mapObjects = map.get(cls); if (mapObjects == null) { mapObjects = new PathObjectTileMap(tileSize); map.put(cls, mapObjects); } mapObjects.put(pathObject); } // Add the children if (includeChildren && !(pathObject instanceof TemporaryObject) && pathObject.hasChildren()) { for (PathObject child : pathObject.getChildObjects().toArray(new PathObject[0])) addToCache(child, includeChildren); } }
/** * Add a pathObject to the map. * If it does not have a ROI, it will be ignored. * Otherwise it is added to the map for as many tiles as its ROI's bounding box intersects. * * @param pathObject */ public void put(PathObject pathObject) { if (!pathObject.hasROI()) return; // if (pathObject.isPoint()) { // PathPointsROI points = (PathPointsROI)pathObject.getROI(); // } // Compute the tiles & add as required ROI pathROI = pathObject.getROI(); int tx1 = (int)(pathROI.getBoundsX() / tileSize); int ty1 = (int)(pathROI.getBoundsY() / tileSize); int tx2 = (int)((pathROI.getBoundsX() + pathROI.getBoundsWidth()) / tileSize); int ty2 = (int)((pathROI.getBoundsY() + pathROI.getBoundsHeight()) / tileSize); int z = pathROI.getZ(); int t = pathROI.getT(); for (int y = ty1; y <= ty2; y++) { for (int x = tx1; x <= tx2; x++) { putInMap(getKey(x, y, z, t), pathObject); } } }