Changeset 1636
- Timestamp:
- 06/13/07 10:20:37 (18 months ago)
- Location:
- branches/3.0-Beta2/components/rendering/src/omeis/providers/re
- Files:
-
- 3 modified
-
GreyScaleStrategy.java (modified) (5 diffs)
-
data/Plane2D.java (modified) (2 diffs)
-
metadata/StatsFactory.java (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/3.0-Beta2/components/rendering/src/omeis/providers/re/GreyScaleStrategy.java
r1608 r1636 16 16 17 17 // Application-internal dependencies 18 import ome.conditions.ResourceError;19 18 import ome.io.nio.PixelBuffer; 20 19 import ome.model.core.Pixels; 21 20 import ome.model.display.ChannelBinding; 22 import ome.model.display.Color;23 21 import omeis.providers.re.codomain.CodomainChain; 24 22 import omeis.providers.re.data.PlaneFactory; … … 44 42 /** The logger for this particular class */ 45 43 private static Log log = LogFactory.getLog(Renderer.class); 46 44 45 /** The channel we're operating on */ 46 private int channel; 47 48 /** The channel binding we're using */ 49 private ChannelBinding channelBinding; 50 47 51 /** 48 52 * Initializes the <code>sizeX1</code> and <code>sizeX2</code> fields … … 76 80 77 81 /** 78 * Renders the specified wavelength (channel).79 *80 * @param dataBuf81 * The buffer to hold the output image's data.82 * @param plane83 * Defines the plane to render.84 * @param qs85 * Knows how to quantize a pixel intensity value.86 * @param color87 * The color components used when mapping a quantized value onto88 * the color space.89 * @throws QuantizationException90 * If an error occurs while quantizing a pixels intensity value.91 */92 private void renderWave(RGBBuffer dataBuf, Plane2D plane, Color color,93 QuantumStrategy qs) throws QuantizationException {94 CodomainChain cc = renderer.getCodomainChain();95 int x1, x2, discreteValue, pixelIndex;96 97 // Perform optimised pixel settings for integer arrays98 if (dataBuf instanceof RGBIntBuffer) {99 int alpha = color.getAlpha();100 int[] buf = ((RGBIntBuffer) dataBuf).getDataBuffer();101 for (x2 = 0; x2 < sizeX2; ++x2) {102 int index = sizeX1 * x2;103 for (x1 = 0; x1 < sizeX1; ++x1) {104 discreteValue = qs.quantize(plane.getPixelValue(x1, x2));105 discreteValue = cc.transform(discreteValue);106 buf[index + x1] = alpha << 24 | discreteValue << 16107 | discreteValue << 8 | discreteValue;108 }109 }110 } else // We have just a plain RGBBuffer111 {112 byte value;113 float alpha = color.getAlpha().floatValue() / 255;114 byte[] r = dataBuf.getRedBand();115 byte[] g = dataBuf.getBlueBand();116 byte[] b = dataBuf.getGreenBand();117 for (x2 = 0; x2 < sizeX2; ++x2) {118 for (x1 = 0; x1 < sizeX1; ++x1) {119 pixelIndex = sizeX1 * x2 + x1;120 discreteValue = qs.quantize(plane.getPixelValue(x1, x2));121 discreteValue = cc.transform(discreteValue);122 value = (byte) (discreteValue * alpha);123 r[pixelIndex] = value;124 g[pixelIndex] = value;125 b[pixelIndex] = value;126 }127 }128 }129 }130 131 /**132 82 * Implemented as specified by the superclass. 133 83 * … … 139 89 // Set the context and retrieve objects we're gonna use. 140 90 renderer = ctx; 91 findFirstActiveChannelBinding(); 92 PixelBuffer pixels = renderer.getPixels(); 141 93 Pixels metadata = renderer.getMetadata(); 94 RenderingStats performanceStats = renderer.getStats(); 95 QuantumStrategy qs = 96 renderer.getQuantumManager().getStrategyFor(channel); 97 CodomainChain cc = renderer.getCodomainChain(); 98 99 // Retrieve the planar data to render 100 performanceStats.startIO(channel); 101 Plane2D plane = 102 PlaneFactory.createPlane(planeDef, channel, metadata, pixels); 103 performanceStats.endIO(channel); 142 104 143 105 // Initialize sizeX1 and sizeX2 according to the plane definition and … … 145 107 initAxesSize(planeDef, metadata); 146 108 RGBBuffer buf = getRgbBuffer(); 147 148 render(buf, planeDef); 109 110 byte value; 111 float alpha = channelBinding.getColor().getAlpha().floatValue() / 255; 112 113 int x1, x2, discreteValue, pixelIndex; 114 byte[] r = buf.getRedBand(); 115 byte[] g = buf.getBlueBand(); 116 byte[] b = buf.getGreenBand(); 117 if (plane.isXYPlanar()) 118 { 119 int planeSize = sizeX1 * sizeX2; 120 for (int i = 0; i < planeSize; i++) 121 { 122 for (x1 = 0; x1 < sizeX1; ++x1) 123 { 124 discreteValue = qs.quantize(plane.getPixelValue(i)); 125 discreteValue = cc.transform(discreteValue); 126 value = (byte) (discreteValue * alpha); 127 r[i] = value; 128 g[i] = value; 129 b[i] = value; 130 } 131 } 132 } 133 else 134 { 135 for (x2 = 0; x2 < sizeX2; ++x2) { 136 for (x1 = 0; x1 < sizeX1; ++x1) { 137 pixelIndex = sizeX1 * x2 + x1; 138 discreteValue = qs.quantize(plane.getPixelValue(x1, x2)); 139 discreteValue = cc.transform(discreteValue); 140 value = (byte) (discreteValue * alpha); 141 r[pixelIndex] = value; 142 g[pixelIndex] = value; 143 b[pixelIndex] = value; 144 } 145 } 146 } 149 147 return buf; 150 148 } 151 152 /** 153 * Implemented as specified by the superclass.154 *155 * @see RenderingStrategy#render(Renderer ctx, PlaneDef planeDef)156 */157 @Override158 RGBIntBuffer renderAsPackedInt(Renderer ctx, PlaneDef planeDef)159 throws IOException, QuantizationException {149 150 /** 151 * Implemented as specified by the superclass. 152 * 153 * @see RenderingStrategy#render(Renderer ctx, PlaneDef planeDef) 154 */ 155 @Override 156 RGBIntBuffer renderAsPackedInt(Renderer ctx, PlaneDef planeDef) 157 throws IOException, QuantizationException { 160 158 // Set the context and retrieve objects we're gonna use. 161 159 renderer = ctx; 162 Pixels metadata = renderer.getMetadata(); 163 164 // Initialize sizeX1 and sizeX2 according to the plane definition and 165 // create the RGB buffer. 166 initAxesSize(planeDef, metadata); 167 RGBIntBuffer buf = getIntBuffer(); 168 169 render(buf, planeDef); 170 return buf; 171 } 172 173 /** 174 * Implemented as specified by the superclass. 175 * 176 * @see RenderingStrategy#render(Renderer ctx, PlaneDef planeDef) 177 */ 178 private void render(RGBBuffer buf, PlaneDef planeDef) throws IOException, 179 QuantizationException { 180 QuantumManager qManager = renderer.getQuantumManager(); 160 findFirstActiveChannelBinding(); 181 161 PixelBuffer pixels = renderer.getPixels(); 182 162 Pixels metadata = renderer.getMetadata(); 183 ChannelBinding[] cBindings = renderer.getChannelBindings();184 163 RenderingStats performanceStats = renderer.getStats(); 185 186 // Process the first active wavelength. 187 Plane2D wData; 188 for (int i = 0; i < cBindings.length; i++) { 189 if (cBindings[i].getActive().booleanValue()) { 190 // Get the raw data. 191 performanceStats.startIO(i); 192 wData = PlaneFactory.createPlane(planeDef, i, metadata, pixels); 193 performanceStats.endIO(i); 194 195 try { // Transform it into an RGB image. 196 performanceStats.startRendering(); 197 renderWave(buf, wData, cBindings[i].getColor(), qManager 198 .getStrategyFor(i)); 199 performanceStats.endRendering(); 200 } catch (QuantizationException e) { 201 e.setWavelength(i); 202 throw e; 203 } 204 break; 205 } 206 } 207 // Make sure that the pixel buffer is cleansed properly. 208 try { 209 pixels.close(); 210 } catch (IOException e) { 211 log.error("IOException caught, throwing ResourceError", e.getCause()); 212 throw new ResourceError( 213 e.getMessage() + " Please check server log."); 214 } 215 } 164 QuantumStrategy qs = 165 renderer.getQuantumManager().getStrategyFor(channel); 166 CodomainChain cc = renderer.getCodomainChain(); 167 168 // Retrieve the planar data to render 169 performanceStats.startIO(channel); 170 Plane2D plane = 171 PlaneFactory.createPlane(planeDef, channel, metadata, pixels); 172 performanceStats.endIO(channel); 173 174 // Initialize sizeX1 and sizeX2 according to the plane definition and 175 // create the RGB buffer. 176 initAxesSize(planeDef, metadata); 177 RGBIntBuffer dataBuf = getIntBuffer(); 178 179 int alpha = channelBinding.getColor().getAlpha(); 180 int[] buf = ((RGBIntBuffer) dataBuf).getDataBuffer(); 181 int x1, x2, discreteValue, pixelIndex; 182 if (plane.isXYPlanar()) 183 { 184 int planeSize = sizeX1 * sizeX2; 185 for (int i = 0; i < planeSize; i++) 186 { 187 discreteValue = qs.quantize(plane.getPixelValue(i)); 188 discreteValue = cc.transform(discreteValue); 189 buf[i] = alpha << 24 | discreteValue << 16 190 | discreteValue << 8 | discreteValue; 191 } 192 } 193 else 194 { 195 for (x2 = 0; x2 < sizeX2; ++x2) { 196 pixelIndex = sizeX1 * x2; 197 for (x1 = 0; x1 < sizeX1; ++x1) { 198 discreteValue = qs.quantize(plane.getPixelValue(x1, x2)); 199 discreteValue = cc.transform(discreteValue); 200 buf[pixelIndex + x1] = alpha << 24 | discreteValue << 16 201 | discreteValue << 8 | discreteValue; 202 } 203 } 204 } 205 return dataBuf; 206 } 207 208 /** 209 * Initializes the first active channel binding for the current rendering 210 * context. 211 */ 212 private void findFirstActiveChannelBinding() 213 { 214 ChannelBinding[] channelBindings = renderer.getChannelBindings(); 215 for (int i = 0; i < channelBindings.length; i++) 216 { 217 if (channelBindings[i].getActive()) 218 { 219 channel = i; 220 channelBinding = channelBindings[i]; 221 return; 222 } 223 } 224 throw new IllegalArgumentException("No active channel bindings found."); 225 } 216 226 217 227 /** -
branches/3.0-Beta2/components/rendering/src/omeis/providers/re/data/Plane2D.java
r1348 r1636 132 132 */ 133 133 public double getPixelValue(int x1, int x2) { 134 int offset = calculateOffset(x1, x2); 135 134 return getPixelValueDirect(calculateOffset(x1, x2)); 135 } 136 137 138 /** 139 * Returns the pixel intensity value of the pixel at a given offset within 140 * the backing buffer. This method takes into account bytes per pixel. So 141 * the number of offsets is equal to the buffer size / 142 * <code>bytesPerPixel</code>. 143 * 144 * @param offset The relative offset (taking into account the number of 145 * bytes per pixel) within the backing buffer. 146 * @return The intensity value. 147 */ 148 public double getPixelValue(int offset) 149 { 150 return getPixelValueDirect(offset * bytesPerPixel); 151 } 152 153 /** 154 * Returns the pixel intensity value of the pixel at a given offset within 155 * the backing buffer. This method does not take into account bytes per 156 * pixel. 157 * 158 * @param offset The absolute offset within the backing buffer. 159 * @return The intensity value. 160 */ 161 private double getPixelValueDirect(int offset) 162 { 136 163 if (signed) { 137 164 switch (javaType) { … … 160 187 } 161 188 189 /** 190 * Returns <code>true</code> if the plane is an <code>XY-plane</code>, 191 * <code>false</code> otherwise. 192 * 193 * @return See above. 194 */ 195 public boolean isXYPlanar() 196 { 197 return (planeDef.getSlice() == PlaneDef.XY); 198 } 162 199 } -
branches/3.0-Beta2/components/rendering/src/omeis/providers/re/metadata/StatsFactory.java
r1582 r1636 82 82 int[] totals = new int[NB_BIN]; 83 83 locationStats = new double[NB_BIN]; 84 /* 84 85 Segment[] segments = new Segment[NB_BIN]; 85 86 for (int i = 0; i < NB_BIN; i++) { … … 88 89 gMin + (i + 1) * sizeBin, 0); 89 90 } 90 91 // check segment [o,e] 92 double pointX1; 93 double pointX2 = 0; 94 for (int x2 = 0; x2 < sizeX2; ++x2) { 95 for (int x1 = 0; x1 < sizeX1; ++x1) { 96 for (int i = 0; i < segments.length; i++) { 97 pointX1 = p2D.getPixelValue(x1, x2); 98 if (!segments[i].equals(1, pointX1, pointX2) 99 && segments[i].lies(pointX1, pointX2)) 100 { 101 totals[i]++; 91 */ 92 BasicSegment[] segments = new BasicSegment[NB_BIN]; 93 for (int i = 0; i < NB_BIN; i++) { 94 segments[i] = new BasicSegment( 95 gMin + i * sizeBin, gMin + (i + 1) * sizeBin); 96 } 97 98 // check segment [o,e[ 99 double v; 100 BasicSegment segment; 101 if (p2D.isXYPlanar()) { 102 //modified code 103 int size = sizeX1*sizeX2; 104 for (int j = 0; j < size; j++) { 105 v = p2D.getPixelValue(j); 106 for (int i = 0; i < segments.length; i++) { 107 segment = segments[i]; 108 if (v >= segment.x1 && v < segment.x2) { 109 totals[i]++; 102 110 break; 103 }111 } 104 112 } // end i 105 } // end x1 106 }// end x2 113 } 114 } else { 115 for (int x2 = 0; x2 < sizeX2; ++x2) { 116 for (int x1 = 0; x1 < sizeX1; ++x1) { 117 v = p2D.getPixelValue(x1, x2); 118 for (int i = 0; i < segments.length; i++) { 119 segment = segments[i]; 120 if (v >= segment.x1 && v < segment.x2) { 121 totals[i]++; 122 break; 123 } 124 /* 125 if (!segments[i].equals(1, pointX1, pointX2) 126 && segments[i].lies(pointX1, pointX2)) 127 { 128 totals[i]++; 129 break; 130 } 131 */ 132 } // end i 133 } // end x1 134 }// end x2 135 } 136 137 107 138 108 139 double total = sizeX2 * sizeX1; … … 111 142 } 112 143 // Default, we assume that we have at least 3 sub-intervals. 113 inputStart = segments[0]. getPoint(1).x1;114 inputEnd = segments[NB_BIN - 1]. getPoint(1).x1;144 inputStart = segments[0].x2;//segments[0].getPoint(1).x1; 145 inputEnd = segments[NB_BIN - 1].x2;//segments[NB_BIN - 1].getPoint(1).x1; 115 146 total = total - totals[0] - totals[NB_BIN - 1]; 116 147 if (totals[0] >= totals[NB_BIN - 1]) { … … 144 175 * closed to the min. 145 176 */ 146 private double accumulateCloseToMin(int[] totals, Segment[] segments,177 private double accumulateCloseToMin(int[] totals, BasicSegment[] segments, 147 178 double total, double epsilon) { 148 double e = segments[NB_BIN - 1]. getPoint(1).x1, sum = 0;179 double e = segments[NB_BIN - 1].x2, sum = 0; 149 180 for (int i = 1; i < totals.length - 1; i++) { 150 181 sum += totals[i]; 151 182 if (sum / total > THRESHOLD) { 152 e = segments[i]. getPoint(1).x1 + epsilon;183 e = segments[i].x1 + epsilon; 153 184 break; 154 185 } … … 161 192 * closed to the max. 162 193 */ 163 private double accumulateCloseToMax(int[] totals, Segment[] segments,194 private double accumulateCloseToMax(int[] totals, BasicSegment[] segments, 164 195 double total, double epsilon) { 165 double s = segments[0]. getPoint(1).x1, sum = 0;196 double s = segments[0].x2, sum = 0; 166 197 for (int i = totals.length - 2; i > 0; i--) { 167 198 sum += totals[i]; 168 199 if (sum / total > THRESHOLD) { 169 s = segments[i]. getPoint(1).x1- epsilon;200 s = segments[i].x2 - epsilon; 170 201 break; 171 202 } … … 216 247 return inputEnd; 217 248 } 218 249 250 //inner class 251 class BasicSegment { 252 253 /** Left bound of the segment. */ 254 double x1; 255 256 /** Right bound of the segment. */ 257 double x2; 258 259 /** 260 * Creates a new instance. 261 * 262 * @param x1 The left bound of the segment. 263 * @param x2 The right bound of the segment. 264 */ 265 BasicSegment(double x1, double x2) 266 { 267 if (x2 < x1) 268 throw new IllegalArgumentException("Segment not valid."); 269 this.x2 = x2; 270 this.x1 = x1; 271 } 272 273 } 274 219 275 }
