001package plugins.kernel.roi.descriptor.measure; 002 003import icy.plugin.abstract_.Plugin; 004import icy.plugin.interface_.PluginROIDescriptor; 005import icy.roi.ROI; 006import icy.roi.ROIDescriptor; 007import icy.sequence.Sequence; 008import icy.type.rectangle.Rectangle5D; 009 010import java.util.ArrayList; 011import java.util.HashMap; 012import java.util.List; 013import java.util.Map; 014 015/** 016 * This {@link PluginROIDescriptor} implements the following basic measures ROI descriptors:<br/> 017 * <li>Contour (in pixel)</li><br/> 018 * <li>Interior (in pixel)</li><br/> 019 * <li>Perimeter (pixel size unit - 2D ROI only)</li><br/> 020 * <li>Surface Area (pixel size unit - 3D ROI only)</li><br/> 021 * <li>Area (pixel size unit - 2D ROI only)</li><br/> 022 * <li>Volume (pixel size unit - 3D ROI only)</li><br/> 023 * 024 * @author Stephane 025 */ 026public class ROIBasicMeasureDescriptorsPlugin extends Plugin implements PluginROIDescriptor 027{ 028 public static final String ID_CONTOUR = ROIContourDescriptor.ID; 029 public static final String ID_INTERIOR = ROIInteriorDescriptor.ID; 030 public static final String ID_PERIMETER = ROIPerimeterDescriptor.ID; 031 public static final String ID_AREA = ROIAreaDescriptor.ID; 032 public static final String ID_SURFACE_AREA = ROISurfaceAreaDescriptor.ID; 033 public static final String ID_VOLUME = ROIVolumeDescriptor.ID; 034 035 public static final ROIContourDescriptor contourDescriptor = new ROIContourDescriptor(); 036 public static final ROIInteriorDescriptor interiorDescriptor = new ROIInteriorDescriptor(); 037 public static final ROIPerimeterDescriptor perimeterDescriptor = new ROIPerimeterDescriptor(); 038 public static final ROIAreaDescriptor areaDescriptor = new ROIAreaDescriptor(); 039 public static final ROISurfaceAreaDescriptor surfaceAreaDescriptor = new ROISurfaceAreaDescriptor(); 040 public static final ROIVolumeDescriptor volumeDescriptor = new ROIVolumeDescriptor(); 041 042 /** 043 * Calculate the multiplier factor depending the wanted dimension information. 044 */ 045 public static double getMultiplierFactor(Sequence sequence, ROI roi, int dim) 046 { 047 final int dimRoi = roi.getDimension(); 048 049 // cannot give this information for this roi 050 if (dimRoi > dim) 051 return 0d; 052 053 final Rectangle5D boundsRoi = roi.getBounds5D(); 054 double mul = 1d; 055 056 switch (dim) 057 { 058 case 5: 059 if (dimRoi == 4) 060 { 061 final int sizeC = sequence.getSizeC(); 062 063 if ((boundsRoi.getSizeC() == Double.POSITIVE_INFINITY) && (sizeC > 1)) 064 mul *= sizeC; 065 // cannot give this information for this roi 066 else 067 mul = 0d; 068 } 069 case 4: 070 if (dimRoi == 3) 071 { 072 final int sizeT = sequence.getSizeT(); 073 074 if ((boundsRoi.getSizeT() == Double.POSITIVE_INFINITY) && (sizeT > 1)) 075 mul *= sizeT; 076 // cannot give this information for this roi 077 else 078 mul = 0d; 079 } 080 case 3: 081 if (dimRoi == 2) 082 { 083 final int sizeZ = sequence.getSizeZ(); 084 085 if ((boundsRoi.getSizeZ() == Double.POSITIVE_INFINITY) && (sizeZ > 1)) 086 mul *= sizeZ; 087 // cannot give this information for this roi 088 else 089 mul = 0d; 090 } 091 case 2: 092 if (dimRoi == 1) 093 { 094 final int sizeY = sequence.getSizeY(); 095 096 if ((boundsRoi.getSizeY() == Double.POSITIVE_INFINITY) && (sizeY > 1)) 097 mul *= sizeY; 098 // cannot give this information for this roi 099 else 100 mul = 0d; 101 } 102 } 103 104 return mul; 105 } 106 107 @Override 108 public List<ROIDescriptor> getDescriptors() 109 { 110 final List<ROIDescriptor> result = new ArrayList<ROIDescriptor>(); 111 112 result.add(contourDescriptor); 113 result.add(interiorDescriptor); 114 result.add(perimeterDescriptor); 115 result.add(areaDescriptor); 116 result.add(surfaceAreaDescriptor); 117 result.add(volumeDescriptor); 118 119 return result; 120 } 121 122 @Override 123 public Map<ROIDescriptor, Object> compute(ROI roi, Sequence sequence) throws UnsupportedOperationException 124 { 125 final Map<ROIDescriptor, Object> result = new HashMap<ROIDescriptor, Object>(); 126 127 // use the contour and interior to compute others descriptors 128 final double contour = ROIContourDescriptor.computeContour(roi); 129 final double interior = ROIInteriorDescriptor.computeInterior(roi); 130 131 result.put(contourDescriptor, Double.valueOf(contour)); 132 result.put(interiorDescriptor, Double.valueOf(interior)); 133 134 int notComputed = 0; 135 136 try 137 { 138 result.put(perimeterDescriptor, Double.valueOf(ROIPerimeterDescriptor.computePerimeter(roi, sequence))); 139 } 140 catch (UnsupportedOperationException e) 141 { 142 result.put(perimeterDescriptor, null); 143 notComputed++; 144 } 145 try 146 { 147 result.put(areaDescriptor, Double.valueOf(ROIAreaDescriptor.computeArea(interior, roi, sequence))); 148 } 149 catch (UnsupportedOperationException e) 150 { 151 result.put(areaDescriptor, null); 152 notComputed++; 153 } 154 try 155 { 156 result.put(surfaceAreaDescriptor, 157 Double.valueOf(ROISurfaceAreaDescriptor.computeSurfaceArea(roi, sequence))); 158 } 159 catch (UnsupportedOperationException e) 160 { 161 result.put(surfaceAreaDescriptor, null); 162 notComputed++; 163 } 164 try 165 { 166 result.put(volumeDescriptor, Double.valueOf(ROIVolumeDescriptor.computeVolume(interior, roi, sequence))); 167 } 168 catch (UnsupportedOperationException e) 169 { 170 result.put(volumeDescriptor, null); 171 notComputed++; 172 } 173 174 if (notComputed == 4) 175 { 176 throw new UnsupportedOperationException(getClass().getSimpleName() 177 + ": cannot compute any of the descriptors for '" + roi.getName() + "'"); 178 } 179 180 return result; 181 } 182}