Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
ShortProcessor.java
1 package ij.process;
2 
3 import java.util.*;
4 import java.awt.*;
5 import java.awt.image.*;
6 import ij.gui.*;
7 
10 public class ShortProcessor extends ImageProcessor {
11 
12  private int min, max, snapshotMin, snapshotMax;
13  private short[] pixels;
14  private short[] snapshotPixels;
15  private byte[] pixels8;
16  private byte[] LUT;
17  private boolean fixedScale;
18 
21  public ShortProcessor(int width, int height, short[] pixels, ColorModel cm) {
22  if (pixels!=null && width*height!=pixels.length)
23  throw new IllegalArgumentException(WRONG_LENGTH);
24  this.width = width;
25  this.height = height;
26  this.pixels = pixels;
27  this.cm = cm;
28  resetRoi();
29  if (pixels!=null)
30  findMinAndMax();
31  fgColor = max;
32  }
33 
36  public ShortProcessor(int width, int height) {
37  this(width, height, new short[width*height], null);
38  }
39 
42  public ShortProcessor(int width, int height, short[] pixels, ColorModel cm, boolean unsigned) {
43  this(width, height, pixels, cm);
44  }
45 
48  public ShortProcessor(int width, int height, boolean unsigned) {
49  this(width, height);
50  }
51 
52  public void findMinAndMax() {
53  if (fixedScale)
54  return;
55  int size = width*height;
56  int value;
57  min = 65535;
58  max = 0;
59  for (int i=0; i<size; i++) {
60  value = pixels[i]&0xffff;
61  if (value<min)
62  min = value;
63  if (value>max)
64  max = value;
65  }
66  hideProgress();
67  }
68 
70  public Image createImage() {
71  //ij.IJ.log("createImage: "+min+" "+max);
72  boolean firstTime = pixels8==null;
73  if (firstTime || !lutAnimation) {
74  // scale from 16-bits to 8-bits
75  int size = width*height;
76  if (pixels8==null)
77  pixels8 = new byte[size];
78 
79  int value;
80  double scale = 256.0/(max-min+1);
81  for (int i=0; i<size; i++) {
82  value = (pixels[i]&0xffff)-min;
83  if (value<0) value = 0;
84  value = (int)(value*scale);
85  if (value>255) value = 255;
86  pixels8[i] = (byte)value;
87  }
88  }
89  if (cm==null)
90  makeDefaultColorModel();
91  if (source==null || (ij.IJ.isMacintosh()&&(!ij.IJ.isJava2()||lutAnimation))) {
92  source = new MemoryImageSource(width, height, cm, pixels8, 0, width);
93  source.setAnimated(true);
94  source.setFullBufferUpdates(true);
95  img = Toolkit.getDefaultToolkit().createImage(source);
96  } else if (newPixels) {
97  source.newPixels(pixels8, cm, 0, width);
98  newPixels = false;
99  } else
100  source.newPixels();
101  lutAnimation = false;
102  return img;
103  }
104 
106  public ImageProcessor createProcessor(int width, int height) {
107  ImageProcessor ip2 = new ShortProcessor(width, height, new short[width*height], getColorModel());
108  ip2.setMinAndMax(getMin(), getMax());
109  return ip2;
110  }
111 
112  public void snapshot() {
113  snapshotWidth=width;
114  snapshotHeight=height;
115  snapshotMin=min;
116  snapshotMax=max;
117  if (snapshotPixels==null || (snapshotPixels!=null && snapshotPixels.length!=pixels.length))
118  snapshotPixels = new short[width * height];
119  System.arraycopy(pixels, 0, snapshotPixels, 0, width*height);
120  newSnapshot = true;
121  }
122 
123  public void reset() {
124  if (snapshotPixels==null)
125  return;
126  min=snapshotMin;
127  max=snapshotMax;
128  System.arraycopy(snapshotPixels, 0, pixels, 0, width*height);
129  newSnapshot = true;
130  }
131 
132  public void reset(ImageProcessor mask) {
133  if (mask==null || snapshotPixels==null)
134  return;
135  if (mask.getWidth()!=roiWidth||mask.getHeight()!=roiHeight)
136  throw new IllegalArgumentException(maskSizeError(mask));
137  byte[] mpixels = (byte[])mask.getPixels();
138  for (int y=roiY, my=0; y<(roiY+roiHeight); y++, my++) {
139  int i = y * width + roiX;
140  int mi = my * roiWidth;
141  for (int x=roiX; x<(roiX+roiWidth); x++) {
142  if (mpixels[mi++]==0)
143  pixels[i] = snapshotPixels[i];
144  i++;
145  }
146  }
147  }
148 
149  /* Obsolete. */
150  //public boolean isUnsigned() {
151  // return true;
152  //}
153 
155  public double getMin() {
156  return min;
157  }
158 
160  public double getMax() {
161  return max;
162  }
163 
170  public void setMinAndMax(double min, double max) {
171  if (min==0.0 && max==0.0)
172  {resetMinAndMax(); return;}
173  if (min<0.0)
174  min = 0.0;
175  if (max>65535.0)
176  max = 65535.0;
177  this.min = (int)min;
178  this.max = (int)max;
179  fixedScale = true;
180  resetThreshold();
181  }
182 
186  public void resetMinAndMax() {
187  fixedScale = false;
188  findMinAndMax();
189  resetThreshold();
190  }
191 
192  public int getPixel(int x, int y) {
193  if (x>=0 && x<width && y>=0 && y<height)
194  return pixels[y*width+x]&0xffff;
195  else
196  return 0;
197  }
198 
200  public double getInterpolatedPixel(double x, double y) {
201  if (x<0.0) x = 0.0;
202  if (x>=width-1.0) x = width-1.001;
203  if (y<0.0) y = 0.0;
204  if (y>=height-1.0) y = height-1.001;
205  return getInterpolatedPixel(x, y, pixels);
206  }
207 
210  public double getInterpolatedValue(double x, double y) {
211  double value = getInterpolatedPixel(x, y);
212  if (cTable==null)
213  return value;
214  else
215  return cTable[(int)(value+0.5)];
216  }
217 
222  public void putPixel(int x, int y, int value) {
223  if (x>=0 && x<width && y>=0 && y<height) {
224  if (value>65535) value = 65535;
225  if (value<0) value = 0;
226  pixels[y*width + x] = (short)value;
227  }
228  }
229 
234  public void putPixelValue(int x, int y, double value) {
235  if (x>=0 && x<width && y>=0 && y<height) {
236  if (value>65535.0)
237  value = 65535.0;
238  else if (value<0.0)
239  value = 0.0;
240  pixels[y*width + x] = (short)(value+0.5);
241  }
242  }
243 
245  public void drawPixel(int x, int y) {
246  if (x>=clipXMin && x<=clipXMax && y>=clipYMin && y<=clipYMax)
247  putPixel(x, y, fgColor);
248  }
249 
250  public float getPixelValue(int x, int y) {
251  if (x>=0 && x<width && y>=0 && y<height) {
252  if (cTable==null)
253  return pixels[y*width + x]&0xffff;
254  else
255  return cTable[pixels[y*width + x]&0xffff];
256  } else
257  return 0f;
258  }
259 
263  public Object getPixels() {
264  return (Object)pixels;
265  }
266 
269  public Object getPixelsCopy() {
270  if (newSnapshot)
271  return snapshotPixels;
272  else {
273  short[] pixels2 = new short[width*height];
274  System.arraycopy(pixels, 0, pixels2, 0, width*height);
275  return pixels2;
276  }
277  }
278 
279  public void setPixels(Object pixels) {
280  this.pixels = (short[])pixels;
281  resetPixels(pixels);
282  snapshotPixels = null;
283  if (pixels==null)
284  pixels8 = null;
285  }
286 
287  void getRow2(int x, int y, int[] data, int length) {
288  int value;
289  for (int i=0; i<length; i++)
290  data[i] = pixels[y*width+x+i]&0xffff;
291  }
292 
293  void putColumn2(int x, int y, int[] data, int length) {
294  int value;
295  for (int i=0; i<length; i++)
296  pixels[(y+i)*width+x] = (short)data[i];
297  }
298 
301  public void copyBits(ImageProcessor ip, int xloc, int yloc, int mode) {
302  if (!(ip instanceof ShortProcessor))
303  throw new IllegalArgumentException("16-bit image required");
304  new ShortBlitter(this).copyBits(ip, xloc, yloc, mode);
305  }
306 
308  public void applyTable(int[] lut) {
309  if (lut.length!=65536)
310  throw new IllegalArgumentException("lut.length!=65536");
311  int lineStart, lineEnd, v;
312  for (int y=roiY; y<(roiY+roiHeight); y++) {
313  lineStart = y * width + roiX;
314  lineEnd = lineStart + roiWidth;
315  for (int i=lineEnd; --i>=lineStart;) {
316  v = lut[pixels[i]&0xffff];
317  pixels[i] = (short)v;
318  }
319  }
320  findMinAndMax();
321  }
322 
323  private void process(int op, double value) {
324  int v1, v2;
325  double range = max-min;
326  boolean resetMinMax = roiWidth==width && roiHeight==height && !(op==FILL);
327 
328  for (int y=roiY; y<(roiY+roiHeight); y++) {
329  int i = y * width + roiX;
330  for (int x=roiX; x<(roiX+roiWidth); x++) {
331  v1 = pixels[i]&0xffff;
332  switch(op) {
333  case INVERT:
334  v2 = max - (v1 - min);
335  break;
336  case FILL:
337  v2 = fgColor;
338  break;
339  case ADD:
340  v2 = v1 + (int)value;
341  break;
342  case MULT:
343  v2 = (int)Math.round(v1 * value);
344  break;
345  case AND:
346  v2 = v1 & (int)value;
347  break;
348  case OR:
349  v2 = v1 | (int)value;
350  break;
351  case XOR:
352  v2 = v1 ^ (int)value;
353  break;
354  case GAMMA:
355  if (range<=0.0 || v1==min)
356  v2 = v1;
357  else
358  v2 = (int)(Math.exp(value*Math.log((v1-min)/range))*range+min);
359  break;
360  case LOG:
361  if (v1<=0)
362  v2 = 0;
363  else
364  v2 = (int)(Math.log(v1)*(max/Math.log(max)));
365  break;
366  case SQR:
367  v2 = v1*v1;
368  break;
369  case SQRT:
370  v2 = (int)Math.sqrt(v1);
371  break;
372  case MINIMUM:
373  if (v1<value)
374  v2 = (int)value;
375  else
376  v2 = v1;
377  break;
378  case MAXIMUM:
379  if (v1>value)
380  v2 = (int)value;
381  else
382  v2 = v1;
383  break;
384  default:
385  v2 = v1;
386  }
387  if (v2 < 0)
388  v2 = 0;
389  if (v2 > 65535)
390  v2 = 65535;
391  pixels[i++] = (short)v2;
392  }
393  if (y%20==0)
394  showProgress((double)(y-roiY)/roiHeight);
395  }
396  if (resetMinMax)
397  findMinAndMax();
398  showProgress(1.0);
399  }
400 
401  public void invert() {
402  resetMinAndMax();
403  process(INVERT, 0.0);
404  }
405 
406  public void add(int value) {process(ADD, value);}
407  public void add(double value) {process(ADD, value);}
408  public void multiply(double value) {process(MULT, value);}
409  public void and(int value) {process(AND, value);}
410  public void or(int value) {process(OR, value);}
411  public void xor(int value) {process(XOR, value);}
412  public void gamma(double value) {process(GAMMA, value);}
413  public void log() {process(LOG, 0.0);}
414  public void sqr() {process(SQR, 0.0);}
415  public void sqrt() {process(SQRT, 0.0);}
416  public void min(double value) {process(MINIMUM, value);}
417  public void max(double value) {process(MAXIMUM, value);}
418 
420  public void fill() {
421  process(FILL, 0.0);
422  }
423 
427  public void fill(ImageProcessor mask) {
428  if (mask==null)
429  {fill(); return;}
430  if (mask.getWidth()!=roiWidth||mask.getHeight()!=roiHeight)
431  throw new IllegalArgumentException(maskSizeError(mask));
432  byte[] mpixels = (byte[])mask.getPixels();
433  for (int y=roiY, my=0; y<(roiY+roiHeight); y++, my++) {
434  int i = y * width + roiX;
435  int mi = my * roiWidth;
436  for (int x=roiX; x<(roiX+roiWidth); x++) {
437  if (mpixels[mi++]!=0)
438  pixels[i] = (short)fgColor;
439  i++;
440  }
441  }
442  }
443 
445  public void convolve3x3(int[] kernel) {
446  int p1, p2, p3,
447  p4, p5, p6,
448  p7, p8, p9;
449  int k1=kernel[0], k2=kernel[1], k3=kernel[2],
450  k4=kernel[3], k5=kernel[4], k6=kernel[5],
451  k7=kernel[6], k8=kernel[7], k9=kernel[8];
452 
453  int scale = 0;
454  for (int i=0; i<kernel.length; i++)
455  scale += kernel[i];
456  if (scale==0) scale = 1;
457  int inc = roiHeight/25;
458  if (inc<1) inc = 1;
459 
460  short[] pixels2 = (short[])getPixelsCopy();
461  int offset, sum;
462  int rowOffset = width;
463  for (int y=yMin; y<=yMax; y++) {
464  offset = xMin + y * width;
465  p1 = 0;
466  p2 = pixels2[offset-rowOffset-1]&0xffff;
467  p3 = pixels2[offset-rowOffset]&0xffff;
468  p4 = 0;
469  p5 = pixels2[offset-1]&0xffff;
470  p6 = pixels2[offset]&0xffff;
471  p7 = 0;
472  p8 = pixels2[offset+rowOffset-1]&0xffff;
473  p9 = pixels2[offset+rowOffset]&0xffff;
474 
475  for (int x=xMin; x<=xMax; x++) {
476  p1 = p2; p2 = p3;
477  p3 = pixels2[offset-rowOffset+1]&0xffff;
478  p4 = p5; p5 = p6;
479  p6 = pixels2[offset+1]&0xffff;
480  p7 = p8; p8 = p9;
481  p9 = pixels2[offset+rowOffset+1]&0xffff;
482  sum = k1*p1 + k2*p2 + k3*p3
483  + k4*p4 + k5*p5 + k6*p6
484  + k7*p7 + k8*p8 + k9*p9;
485  sum /= scale;
486  if(sum>65535) sum = 65535;
487  if(sum<0) sum= 0;
488  pixels[offset++] = (short)sum;
489  }
490  if (y%inc==0)
491  showProgress((double)(y-roiY)/roiHeight);
492  }
493  hideProgress();
494  }
495 
497  public void filter(int type) {
498  int p1, p2, p3, p4, p5, p6, p7, p8, p9;
499  int inc = roiHeight/25;
500  if (inc<1) inc = 1;
501 
502  short[] pixels2 = (short[])getPixelsCopy();
503  int offset, sum1, sum2, sum=0;
504  int rowOffset = width;
505  for (int y=yMin; y<=yMax; y++) {
506  offset = xMin + y * width;
507  p1 = 0;
508  p2 = pixels2[offset-rowOffset-1]&0xffff;
509  p3 = pixels2[offset-rowOffset]&0xffff;
510  p4 = 0;
511  p5 = pixels2[offset-1]&0xffff;
512  p6 = pixels2[offset]&0xffff;
513  p7 = 0;
514  p8 = pixels2[offset+rowOffset-1]&0xffff;
515  p9 = pixels2[offset+rowOffset]&0xffff;
516 
517  for (int x=xMin; x<=xMax; x++) {
518  p1 = p2; p2 = p3;
519  p3 = pixels2[offset-rowOffset+1]&0xffff;
520  p4 = p5; p5 = p6;
521  p6 = pixels2[offset+1]&0xffff;
522  p7 = p8; p8 = p9;
523  p9 = pixels2[offset+rowOffset+1]&0xffff;
524 
525  switch (type) {
526  case BLUR_MORE:
527  sum = (p1+p2+p3+p4+p5+p6+p7+p8+p9)/9;
528  break;
529  case FIND_EDGES:
530  sum1 = p1 + 2*p2 + p3 - p7 - 2*p8 - p9;
531  sum2 = p1 + 2*p4 + p7 - p3 - 2*p6 - p9;
532  sum = (int)Math.sqrt(sum1*sum1 + sum2*sum2);
533  break;
534  }
535 
536  pixels[offset++] = (short)sum;
537  }
538  if (y%inc==0)
539  showProgress((double)(y-roiY)/roiHeight);
540  }
541  if (type==BLUR_MORE)
542  hideProgress();
543  else
544  findMinAndMax();
545  }
546 
550  public void rotate(double angle) {
551  short[] pixels2 = (short[])getPixelsCopy();
552  double centerX = roiX + (roiWidth-1)/2.0;
553  double centerY = roiY + (roiHeight-1)/2.0;
554  int xMax = roiX + this.roiWidth - 1;
555 
556  double angleRadians = -angle/(180.0/Math.PI);
557  double ca = Math.cos(angleRadians);
558  double sa = Math.sin(angleRadians);
559  double tmp1 = centerY*sa-centerX*ca;
560  double tmp2 = -centerX*sa-centerY*ca;
561  double tmp3, tmp4, xs, ys;
562  int index, ixs, iys;
563  double dwidth=width,dheight=height;
564  double xlimit = width-1.0, xlimit2 = width-1.001;
565  double ylimit = height-1.0, ylimit2 = height-1.001;
566  // zero is 32768 for signed images
567  int background = cTable!=null && cTable[0]==-32768?32768:0;
568 
569  for (int y=roiY; y<(roiY + roiHeight); y++) {
570  index = y*width + roiX;
571  tmp3 = tmp1 - y*sa + centerX;
572  tmp4 = tmp2 + y*ca + centerY;
573  for (int x=roiX; x<=xMax; x++) {
574  xs = x*ca + tmp3;
575  ys = x*sa + tmp4;
576  if ((xs>=-0.01) && (xs<dwidth) && (ys>=-0.01) && (ys<dheight)) {
577  if (interpolate) {
578  if (xs<0.0) xs = 0.0;
579  if (xs>=xlimit) xs = xlimit2;
580  if (ys<0.0) ys = 0.0;
581  if (ys>=ylimit) ys = ylimit2;
582  pixels[index++] = (short)(getInterpolatedPixel(xs, ys, pixels2)+0.5);
583  } else {
584  ixs = (int)(xs+0.5);
585  iys = (int)(ys+0.5);
586  if (ixs>=width) ixs = width - 1;
587  if (iys>=height) iys = height -1;
588  pixels[index++] = pixels2[width*iys+ixs];
589  }
590  } else
591  pixels[index++] = (short)background;
592  }
593  if (y%30==0)
594  showProgress((double)(y-roiY)/roiHeight);
595  }
596  hideProgress();
597  }
598 
599  public void flipVertical() {
600  int index1,index2;
601  short tmp;
602  for (int y=0; y<roiHeight/2; y++) {
603  index1 = (roiY+y)*width+roiX;
604  index2 = (roiY+roiHeight-1-y)*width+roiX;
605  for (int i=0; i<roiWidth; i++) {
606  tmp = pixels[index1];
607  pixels[index1++] = pixels[index2];
608  pixels[index2++] = tmp;
609  }
610  }
611  newSnapshot = false;
612  }
613 
617  public void scale(double xScale, double yScale) {
618  double xCenter = roiX + roiWidth/2.0;
619  double yCenter = roiY + roiHeight/2.0;
620  int xmin, xmax, ymin, ymax;
621 
622  if ((xScale>1.0) && (yScale>1.0)) {
623  //expand roi
624  xmin = (int)(xCenter-(xCenter-roiX)*xScale);
625  if (xmin<0) xmin = 0;
626  xmax = xmin + (int)(roiWidth*xScale) - 1;
627  if (xmax>=width) xmax = width - 1;
628  ymin = (int)(yCenter-(yCenter-roiY)*yScale);
629  if (ymin<0) ymin = 0;
630  ymax = ymin + (int)(roiHeight*yScale) - 1;
631  if (ymax>=height) ymax = height - 1;
632  } else {
633  xmin = roiX;
634  xmax = roiX + roiWidth - 1;
635  ymin = roiY;
636  ymax = roiY + roiHeight - 1;
637  }
638  short[] pixels2 = (short[])getPixelsCopy();
639  boolean checkCoordinates = (xScale < 1.0) || (yScale < 1.0);
640  int index1, index2, xsi, ysi;
641  double ys, xs;
642  double xlimit = width-1.0, xlimit2 = width-1.001;
643  double ylimit = height-1.0, ylimit2 = height-1.001;
644  for (int y=ymin; y<=ymax; y++) {
645  ys = (y-yCenter)/yScale + yCenter;
646  ysi = (int)ys;
647  if (ys<0.0) ys = 0.0;
648  if (ys>=ylimit) ys = ylimit2;
649  index1 = y*width + xmin;
650  index2 = width*(int)ys;
651  for (int x=xmin; x<=xmax; x++) {
652  xs = (x-xCenter)/xScale + xCenter;
653  xsi = (int)xs;
654  if (checkCoordinates && ((xsi<xmin) || (xsi>xmax) || (ysi<ymin) || (ysi>ymax)))
655  pixels[index1++] = (short)min;
656  else {
657  if (interpolate) {
658  if (xs<0.0) xs = 0.0;
659  if (xs>=xlimit) xs = xlimit2;
660  pixels[index1++] = (short)(getInterpolatedPixel(xs, ys, pixels2)+0.5);
661  } else
662  pixels[index1++] = pixels2[index2+xsi];
663  }
664  }
665  if (y%20==0)
666  showProgress((double)(y-ymin)/height);
667  }
668  hideProgress();
669  }
670 
672  private final double getInterpolatedPixel(double x, double y, short[] pixels) {
673  int xbase = (int)x;
674  int ybase = (int)y;
675  double xFraction = x - xbase;
676  double yFraction = y - ybase;
677  int offset = ybase * width + xbase;
678  int lowerLeft = pixels[offset]&0xffff;
679  int lowerRight = pixels[offset + 1]&0xffff;
680  int upperRight = pixels[offset + width + 1]&0xffff;
681  int upperLeft = pixels[offset + width]&0xffff;
682  double upperAverage = upperLeft + xFraction * (upperRight - upperLeft);
683  double lowerAverage = lowerLeft + xFraction * (lowerRight - lowerLeft);
684  return lowerAverage + yFraction * (upperAverage - lowerAverage);
685  }
686 
688  public ImageProcessor resize(int dstWidth, int dstHeight) {
689  double srcCenterX = roiX + roiWidth/2.0;
690  double srcCenterY = roiY + roiHeight/2.0;
691  double dstCenterX = dstWidth/2.0;
692  double dstCenterY = dstHeight/2.0;
693  double xScale = (double)dstWidth/roiWidth;
694  double yScale = (double)dstHeight/roiHeight;
695  if (interpolate) {
696  dstCenterX += xScale/2.0;
697  dstCenterY += yScale/2.0;
698  }
699  ImageProcessor ip2 = createProcessor(dstWidth, dstHeight);
700  short[] pixels2 = (short[])ip2.getPixels();
701  double xs, ys;
702  double xlimit = width-1.0, xlimit2 = width-1.001;
703  double ylimit = height-1.0, ylimit2 = height-1.001;
704  int index1, index2;
705  for (int y=0; y<=dstHeight-1; y++) {
706  ys = (y-dstCenterY)/yScale + srcCenterY;
707  if (interpolate) {
708  if (ys<0.0) ys = 0.0;
709  if (ys>=ylimit) ys = ylimit2;
710  }
711  index1 = width*(int)ys;
712  index2 = y*dstWidth;
713  for (int x=0; x<=dstWidth-1; x++) {
714  xs = (x-dstCenterX)/xScale + srcCenterX;
715  if (interpolate) {
716  if (xs<0.0) xs = 0.0;
717  if (xs>=xlimit) xs = xlimit2;
718  pixels2[index2++] = (short)(getInterpolatedPixel(xs, ys, pixels)+0.5);
719  } else
720  pixels2[index2++] = pixels[index1+(int)xs];
721  }
722  if (y%20==0)
723  showProgress((double)y/dstHeight);
724  }
725  hideProgress();
726  return ip2;
727  }
728 
729  public ImageProcessor crop() {
730  ImageProcessor ip2 = createProcessor(roiWidth, roiHeight);
731  short[] pixels2 = (short[])ip2.getPixels();
732  for (int ys=roiY; ys<roiY+roiHeight; ys++) {
733  int offset1 = (ys-roiY)*roiWidth;
734  int offset2 = ys*width+roiX;
735  for (int xs=0; xs<roiWidth; xs++)
736  pixels2[offset1++] = pixels[offset2++];
737  }
738  return ip2;
739  }
740 
742  public void setColor(Color color) {
743  int bestIndex = getBestIndex(color);
744  if (bestIndex>0 && getMin()==0.0 && getMax()==0.0) {
745  setValue(bestIndex);
746  setMinAndMax(0.0,255.0);
747  } else if (bestIndex==0 && getMin()>0.0 && (color.getRGB()&0xffffff)==0)
748  setValue(0.0);
749  else
750  fgColor = (int)(getMin() + (getMax()-getMin())*(bestIndex/255.0));
751 
752  }
753 
755  public void setValue(double value) {
756  fgColor = (int)value;
757  if (fgColor<0) fgColor = 0;
758  if (fgColor>65535) fgColor = 65535;
759  }
760 
763  public int[] getHistogram() {
764  if (mask!=null)
765  return getHistogram(mask);
766  int[] histogram = new int[65536];
767  for (int y=roiY; y<(roiY+roiHeight); y++) {
768  int i = y*width + roiX;
769  for (int x=roiX; x<(roiX+roiWidth); x++)
770  histogram[pixels[i++]&0xffff]++;
771  }
772  return histogram;
773  }
774 
775  int[] getHistogram(ImageProcessor mask) {
776  if (mask.getWidth()!=roiWidth||mask.getHeight()!=roiHeight)
777  throw new IllegalArgumentException(maskSizeError(mask));
778  byte[] mpixels = (byte[])mask.getPixels();
779  int[] histogram = new int[65536];
780  for (int y=roiY, my=0; y<(roiY+roiHeight); y++, my++) {
781  int i = y * width + roiX;
782  int mi = my * roiWidth;
783  for (int x=roiX; x<(roiX+roiWidth); x++) {
784  if (mpixels[mi++]!=0)
785  histogram[pixels[i]&0xffff]++;
786  i++;
787  }
788  }
789  return histogram;
790  }
791 
792  public void setThreshold(double minThreshold, double maxThreshold, int lutUpdate) {
793  if (minThreshold!=NO_THRESHOLD && max>min) {
794  double minT = Math.round(((minThreshold-min)/(max-min))*255.0);
795  double maxT = Math.round(((maxThreshold-min)/(max-min))*255.0);
796  super.setThreshold(minT, maxT, lutUpdate);
797  this.minThreshold = Math.round(minThreshold);
798  this.maxThreshold = Math.round(maxThreshold);
799  } else
800  super.resetThreshold();
801  }
802 
804  public void convolve(float[] kernel, int kernelWidth, int kernelHeight) {
806  ip2.setRoi(getRoi());
807  new ij.plugin.filter.Convolver().convolve(ip2, kernel, kernelWidth, kernelHeight);
808  ip2 = ip2.convertToShort(false);
809  short[] pixels2 = (short[])ip2.getPixels();
810  System.arraycopy(pixels2, 0, pixels, 0, pixels.length);
811  }
812 
813  public void noise(double range) {
814  Random rnd=new Random();
815  int v;
816  for (int y=roiY; y<(roiY+roiHeight); y++) {
817  int i = y * width + roiX;
818  for (int x=roiX; x<(roiX+roiWidth); x++) {
819  int RandomBrightness = (int)Math.round(rnd.nextGaussian()*range);
820  v = (pixels[i] & 0xffff) + RandomBrightness;
821  if (v < 0) v = 0;
822  if (v > 65535) v = 65535;
823  pixels[i] = (short)v;
824  i++;
825  }
826  }
827  findMinAndMax();
828  }
829 
830  public void threshold(int level) {
831  for (int i=0; i<width*height; i++) {
832  if ((pixels[i]&0xffff)<=level)
833  pixels[i] = 0;
834  else
835  pixels[i] = (short)255;
836  }
837  newSnapshot = false;
838  findMinAndMax();
839  }
840 
842  public void medianFilter() {}
844  public void erode() {}
846  public void dilate() {}
847 
848 }
849