001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2023 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit https://imagingbook.com for additional details. 008 ******************************************************************************/ 009package imagingbook.common.ij; 010 011import ij.gui.OvalRoi; 012import ij.gui.PointRoi; 013import ij.gui.PolygonRoi; 014import ij.gui.Roi; 015import ij.process.FloatPolygon; 016import imagingbook.common.geometry.basic.Pnt2d; 017 018import java.awt.Polygon; 019 020/** 021 * This class defines static ROI-related utility methods to interface with ImageJ. 022 * 023 * @author WB 024 * @version 2022/09/22 025 */ 026public class RoiUtils { 027 028 private RoiUtils() {} 029 030 /** 031 * Retrieves the outline of the specified ROI as an array of {@link Pnt2d} points with {@code int} coordinates. Note 032 * that unless the ROI is of type {@link PolygonRoi} or {@link PointRoi} only the corner points of the bounding box 033 * are returned. Interpolated contour points are returned for a instance of {@link OvalRoi}. 034 * 035 * @param roi the ROI 036 * @return the ROI's polygon coordinates 037 */ 038 public static Pnt2d[] getOutlinePointsInt(Roi roi) { 039 Polygon pgn = roi.getPolygon(); 040 Pnt2d[] pts = new Pnt2d[pgn.npoints]; 041 for (int i = 0; i < pgn.npoints; i++) { 042 pts[i] = Pnt2d.PntInt.from(pgn.xpoints[i], pgn.ypoints[i]); 043 } 044 return pts; 045 } 046 047 /** 048 * Retrieves the outline of the specified ROI as an array of {@link Pnt2d} points with {@code double} coordinates. 049 * Returned coordinates are measured relative to the pixel center, e.g., (5.0, 3.0) is assumed to be in the middle 050 * of pixel (5, 3). This method retrieves ROI points with {@link Roi#getFloatPolygon()} but applies type-dependent 051 * correction for consistent point rendering. 052 * 053 * @param roi the {@link Roi} 054 * @return the ROI's outline coordinates 055 */ 056 public static Pnt2d[] getOutlinePointsFloat(Roi roi) { 057// final double offset = (isAreaRoi(roi)) ? -0.5 : 0.0; // replaced by Roi#isLineOrPoint() with IJ 1.53v 058 final double offset = (roi.isLineOrPoint()) ? 0.0 : -0.5; // shift area rois to pixel centers 059 FloatPolygon poly = roi.getFloatPolygon(); 060 return getPoints(poly, offset); 061 } 062 063 /** 064 * Extracts the points of an ImageJ {@link FloatPolygon}. 065 * 066 * @param poly the original polygon 067 * @param offset x/y offset to add to coordinates (typically -0.5 for "area ROIs") 068 * @return the polygon's vertex points 069 */ 070 public static Pnt2d[] getPoints(FloatPolygon poly, double offset) { 071 Pnt2d[] pts = new Pnt2d[poly.npoints]; 072 for (int i = 0; i < poly.npoints; i++) { 073 pts[i] = Pnt2d.from(poly.xpoints[i] + offset, poly.ypoints[i] + offset); 074 } 075 return pts; 076 } 077 078 /** 079 * Extracts the points of an ImageJ {@link FloatPolygon}. Calls {@link #getPoints(FloatPolygon, double)} with zero 080 * offset. 081 * 082 * @param poly the original polygon 083 * @return the polygon's vertex points 084 */ 085 public static Pnt2d[] getPoints(FloatPolygon poly) { 086 return getPoints(poly, 0.0); 087 } 088 089 /** 090 * Converts an array of 2D points (of type {@link Pnt2d}) to a {@link PointRoi} instance. 091 * 092 * @param points v 093 * @return a {@link PointRoi} instance 094 */ 095 public static PointRoi toPointRoi(Pnt2d[] points) { 096 PointRoi roi = new PointRoi(); 097 for (Pnt2d p : points) { 098 roi.addPoint(p.getX(), p.getY()); 099 } 100 return roi; 101 } 102 103}