Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
BoxFilter.java
1 package ij.plugin.filter;
2 import ij.*;
3 import ij.process.*;
4 import ij.gui.*;
5 import java.awt.*;
6 import java.util.*;
7 
12 public class BoxFilter implements PlugInFilter {
13 
14  static final int BYTE=0, SHORT=1, FLOAT=2, RGB=3;
15 
16  ImagePlus imp;
17  int slice;
18  boolean canceled;
19  boolean isLineRoi;
20 
21  static double radius = 2.0;
22  static int boxWidth = 5;
23  static int boxHeight = 5;
24 
25 
26  public int setup(String arg, ImagePlus imp) {
27  IJ.register(BoxFilter.class);
28  this.imp = imp;
29  slice = 0;
30  canceled = false;
31  if (imp!=null) {
32  Roi roi = imp.getRoi();
33  isLineRoi= roi!=null && roi.getType()>=Roi.LINE;
34  }
35  if (imp!=null && !showDialog())
36  return DONE;
37  else
38  return IJ.setupDialog(imp, DOES_ALL);
39  }
40 
41  public void run(ImageProcessor ip) {
42  if (canceled)
43  return;
44  slice++;
45 
46  if (isLineRoi)
47  ip.resetRoi();
48  int type = getType(ip);
49  if (type==RGB)
50  blurRGB(ip, boxWidth, boxHeight);
51  else {
52  ImageProcessor ip2 = blur(ip, boxWidth, boxHeight);
53  convertBack(ip2, ip, type);
54  //new ImagePlus("ip2", ip2).show();
55  }
56  if (slice>1)
57  IJ.showStatus("Mean: "+": "+slice+"/"+imp.getStackSize());
58  if (imp!=null && slice==imp.getStackSize())
59  ip.resetMinAndMax();
60  }
61 
62  int getType(ImageProcessor ip) {
63  int type;
64  if (ip instanceof ByteProcessor)
65  type = BYTE;
66  else if (ip instanceof ShortProcessor)
67  type = SHORT;
68  else if (ip instanceof FloatProcessor)
69  type = FLOAT;
70  else
71  type = RGB;
72  return type;
73  }
74 
75  public void convertBack(ImageProcessor ip2, ImageProcessor ip, int type) {
76  switch (type) {
77  case BYTE:
78  ip2 = ip2.convertToByte(false);
79  byte[] pixels = (byte[])ip.getPixels();
80  byte[] pixels2 = (byte[])ip2.getPixels();
81  System.arraycopy(pixels2, 0, pixels, 0, pixels.length);
82  break;
83  case SHORT:
84  ip2 = ip2.convertToShort(false);
85  short[] pixels16 = (short[])ip.getPixels();
86  short[] pixels16b = (short[])ip2.getPixels();
87  System.arraycopy(pixels16b, 0, pixels16, 0, pixels16.length);
88  break;
89  case FLOAT:
90  break;
91  }
92  }
93 
94  boolean showDialog() {
95  GenericDialog gd = new GenericDialog("Blur...");
96  gd.addNumericField("Kernel Size:", boxWidth, 0);
97  gd.showDialog();
98  if (gd.wasCanceled()) {
99  canceled = true;
100  return false;
101  }
102  boxWidth = (int)gd.getNextNumber();
103  if (boxWidth<1) boxWidth = 1;
104  boxHeight = boxWidth;
105  imp.startTiming();
106  return true;
107  }
108 
109  ImageProcessor blur(ImageProcessor ip1, int boxw, int boxh) {
110  ip1 = preCalculateSums(ip1);
111  //new ImagePlus("sum", ip1).show();
112  int width = ip1.getWidth();
113  int height = ip1.getHeight();
114  float[] pixels1 = (float[])ip1.getPixels();
115  float[] pixels2 = new float[width*height];
116  double scale = 1.0/((boxw*2.0)*(boxh*2.0));
117  double sum;
118  for (int y=0; y<height; y++) {
119  for (int x=0; x<width; x++) {
120  sum = getPixel(pixels1, width, height, x+boxw, y+boxh)
121  + getPixel(pixels1, width, height, x-boxw, y-boxh)
122  - getPixel(pixels1, width, height, x-boxw, y+boxh)
123  - getPixel(pixels1, width, height, x+boxw, y-boxh);
124  pixels2[x+y*width] = (float)(sum*scale);
125  }
126  }
127  return new FloatProcessor(width, height, pixels2, null);
128  }
129 
132  ImageProcessor preCalculateSums(ImageProcessor ip1) {
133  int width = ip1.getWidth();
134  int height = ip1.getHeight();
135  ip1 = ip1.convertToFloat();
136  ImageProcessor ip2 = ip1.duplicate();
137  float[] pixels1 = (float[])ip1.getPixels();
138  float[] pixels2 = (float[])ip2.getPixels();
139  float sum;
140  int offset;
141  for (int y=0; y<height; y++) {
142  offset = y*width;
143  for (int x=0; x<width; x++) {
144  sum = pixels1[offset];
145  if (x>0) sum += pixels2[offset-1];
146  if (y>0) sum += pixels2[offset-width];
147  if (x>0 && y>0) sum -= pixels2[offset-width-1];
148  pixels2[offset] = sum;
149  offset++;
150  }
151  }
152  return ip2;
153  }
154 
155  double getPixel(float[] pixels, int w, int h, int x, int y) {
156  if (x<0) x=0; else if (x>=w) x=w-1;
157  if (y<0) y=0; else if (y>=h) y=h-1;
158  return pixels[x+y*w];
159  }
160 
161  public void blurRGB(ImageProcessor ip, int boxw, int boxh) {
162  int width = ip.getWidth();
163  int height = ip.getHeight();
164  Rectangle roi = ip.getRoi();
165  int size = width*height;
166  if (slice==1) IJ.showStatus("Blur... (red)");
167  byte[] r = new byte[size];
168  byte[] g = new byte[size];
169  byte[] b = new byte[size];
170  ((ColorProcessor)ip).getRGB(r,g,b);
171  ImageProcessor rip = new ByteProcessor(width, height, r, null);
172  ImageProcessor gip = new ByteProcessor(width, height, g, null);
173  ImageProcessor bip = new ByteProcessor(width, height, b, null);
174  ImageProcessor ip2 = blur(rip, boxWidth, boxHeight);
175  if (canceled) return;
176  ImageProcessor r2 = ip2.convertToByte(false);
177  if (slice==1) IJ.showStatus("Blur... (green)");
178  ip2 = blur(gip, boxWidth, boxHeight);
179  if (canceled) return;
180  ImageProcessor g2 = ip2.convertToByte(false);
181  if (slice==1) IJ.showStatus("Blur... (blue)");
182  ip2 = blur(bip, boxWidth, boxHeight);
183  if (canceled) return;
184  ImageProcessor b2 = ip2.convertToByte(false);
185  ((ColorProcessor)ip).setRGB((byte[])r2.getPixels(), (byte[])g2.getPixels(), (byte[])b2.getPixels());
186  }
187 
188 }