View Javadoc
1   package com.github.celldynamics.quimp.geom;
2   
3   import java.awt.Shape;
4   import java.util.List;
5   
6   import org.scijava.vecmath.Point2d;
7   
8   import com.github.celldynamics.quimp.plugin.utils.QuimpDataConverter;
9   
10  import ij.gui.PolygonRoi;
11  import ij.gui.Roi;
12  import ij.gui.ShapeRoi;
13  import ij.process.FloatPolygon;
14  
15  /**
16   * Add some fields indicating that this Shape has been included already in any Snake chain.
17   * 
18   * <p>Shapes among one chain have the same id. Chain id is set when following shape overlap current
19   * one
20   * 
21   * @author p.baniukiewicz
22   * @see com.github.celldynamics.quimp.geom.TrackOutline
23   * @see com.github.celldynamics.quimp.plugin.binaryseg.BinarySegmentation
24   *
25   */
26  public class SegmentedShapeRoi extends ShapeRoi {
27  
28    /**
29     * The Constant NOT_COUNTED.
30     * 
31     * <p>Code for not counted yet shape.
32     */
33    public static final int NOT_COUNTED = -1;
34  
35    /**
36     * The id of the shape.
37     * 
38     * <p>positive if has any id assigned (thus it has been counted already)
39     */
40    protected int id = NOT_COUNTED;
41  
42    /**
43     * Frame number where this outline was found.
44     */
45    protected int frame = 0;
46    /**
47     * Step during conversion outline to points. For 1 every point from outline is included in
48     * output list
49     */
50    protected double step = 1;
51    /**
52     * true for using spline smoothing during interpolation.
53     */
54    protected boolean splineSmooth = false;
55    /**
56     * true for using running average for smoothing. Will apply before {@link #splineSmooth}
57     */
58    protected boolean runningAverageSmooth = false;
59    /**
60     * serialVersionUID.
61     */
62    private static final long serialVersionUID = 1L;
63  
64    /**
65     * Construct object from ij.gui.Roi.
66     * 
67     * @param r Roi
68     */
69    public SegmentedShapeRoi(Roi r) {
70      super(r);
71    }
72  
73    /**
74     * Construct object from java.awt.Shape.
75     * 
76     * @param s Shape
77     */
78    public SegmentedShapeRoi(Shape s) {
79      super(s);
80    }
81  
82    /**
83     * Construct object from array.
84     * 
85     * @param shapeArray shapeArray
86     * @see ij.gui.ShapeRoi#ShapeRoi(float[])
87     */
88    public SegmentedShapeRoi(float[] shapeArray) {
89      super(shapeArray);
90    }
91  
92    /**
93     * Constructs a ShapeRoi from a Shape.
94     * 
95     * @param x x
96     * @param y y
97     * @param s s
98     * @see ij.gui.ShapeRoi#ShapeRoi(int x, int y, Shape s)
99     */
100   public SegmentedShapeRoi(int x, int y, Shape s) {
101     super(x, y, s);
102   }
103 
104   /**
105    * Get id.
106    * 
107    * @return the id
108    */
109   public int getId() {
110     return id;
111   }
112 
113   /**
114    * Set Roi id.
115    * 
116    * @param id the id to set
117    */
118   public void setId(int id) {
119     this.id = id;
120   }
121 
122   /**
123    * Get Roi frame.
124    * 
125    * @return the frame
126    */
127   public int getFrame() {
128     return frame;
129   }
130 
131   /**
132    * Set Roi frame.
133    * 
134    * @param frame the frame to set
135    */
136   public void setFrame(int frame) {
137     this.frame = frame;
138   }
139 
140   /**
141    * Convert this ROI to list of points using smoothing and step.
142    * 
143    * <p>First this method converts shape to {@link PolygonRoi} using step and running average
144    * smoothing set up by
145    * {@link SegmentedShapeRoi#setInterpolationParameters(double, boolean, boolean)}. Then if
146    * {@link #splineSmooth} was set, spline is fitted to ROI and result is converted to list. By
147    * default step is set to 1 and without smoothing.
148    * 
149    * <p>Step of 1 does not mean one point resolution. Still interpolation can apply. Use
150    * {@link #getOutlineasRawPoints()} for obtaining pure coordinates without smoothing nor
151    * interpolation. Depending on interpolation step, last point in list can overlap with first.
152    * 
153    * @return List of List of ROIs
154    * @see #getOutlineasRawPoints()
155    * @see #setInterpolationParameters(double, boolean, boolean)
156    */
157   public List<Point2d> getOutlineasPoints() {
158     List<Point2d> ret;
159     FloatPolygon fp;
160     PolygonRoi pr;
161     // convert to PolygonRoi as it supports spline fitting
162     pr = new PolygonRoi(getInterpolatedPolygon(step, runningAverageSmooth), Roi.FREEROI);
163     if (splineSmooth == true) { // fit spline
164       pr.fitSpline();
165       fp = pr.getFloatPolygon(); // get FloatPolygon to have access to x[],y[]
166       ret = new QuimpDataConverter(fp.xpoints, fp.ypoints).getList(); // x[],y[] are fitted
167     } else {
168       fp = pr.getFloatPolygon();
169       ret = new QuimpDataConverter(fp.xpoints, fp.ypoints).getList(); // x[],y[] not fitted
170     }
171     return ret;
172   }
173 
174   /**
175    * Convert this ROI to list of points without any interpolation.
176    * 
177    * @return List of List of ROIs
178    * @see #getOutlineasPoints()
179    */
180   public List<Point2d> getOutlineasRawPoints() {
181     FloatPolygon fp = this.getFloatPolygon();
182     if (fp.xpoints != null && fp.ypoints != null) {
183       return new QuimpDataConverter(fp.xpoints, fp.ypoints).getList();
184     } else {
185       return null;
186     }
187   }
188 
189   /**
190    * Allow to set non-standard parameters used during conversion from outline (ROI) to list of
191    * points. Do not use runing average smoothing.
192    * 
193    * <pre>
194    * <code>
195    * for (ArrayList&lt;SegmentedShapeRoi&gt; asS : ret) {
196    *  for (SegmentedShapeRoi ss : asS) {
197    *    ss.setInterpolationParameters(1, false);
198    *  }
199    * }
200    * </code>
201    * </pre>
202    * 
203    * @param step interpolation step. Step = 1 does not stand for no interpolation. Use
204    *        {@link #getOutlineasRawPoints()} instead.
205    * @param splineSmooth true to use Spline smoothing
206    * 
207    * @see #getOutlineasPoints()
208    * @see #getOutlineasRawPoints()
209    */
210   public void setInterpolationParameters(double step, boolean splineSmooth) {
211     this.step = step;
212     this.splineSmooth = splineSmooth;
213     this.runningAverageSmooth = false;
214   }
215 
216   /**
217    * Allow to set non-standard parameters used during conversion from outline (ROI) to list of
218    * points.
219    * 
220    * <pre>
221    * <code>
222    * for (ArrayList&lt;SegmentedShapeRoi&gt; asS : ret) {
223    *  for (SegmentedShapeRoi ss : asS) {
224    *    ss.setInterpolationParameters(1, false,true);
225    *  }
226    * }
227    * </code>
228    * </pre>
229    * 
230    * @param step interpolation step. Step = 1 does not stand for no interpolation. Use
231    *        {@link #getOutlineasRawPoints()} instead.
232    * @param splineSmooth true to use Spline smoothing
233    * @param runningAverageSmooth true for using 3 point running average smoothing. This will apply
234    *        before spline smoothing.
235    * 
236    * @see #getOutlineasPoints()
237    * @see #getOutlineasRawPoints()
238    */
239   public void setInterpolationParameters(double step, boolean splineSmooth,
240           boolean runningAverageSmooth) {
241     this.step = step;
242     this.splineSmooth = splineSmooth;
243     this.runningAverageSmooth = runningAverageSmooth;
244   }
245 
246 }