1 package ij.plugin.filter;
8 import java.awt.event.*;
15 static final int BYTE=0, SHORT=1, FLOAT=2, RGB=3;
25 static String kernelText =
"-1 -1 -1 -1 -1\n-1 -1 -1 -1 -1\n-1 -1 24 -1 -1\n-1 -1 -1 -1 -1\n-1 -1 -1 -1 -1\n";
26 static boolean normalize =
true;
34 Roi roi = imp.getRoi();
35 isLineRoi= roi!=null && roi.getType()>=Roi.LINE;
40 IJ.
showMessage(
"Convolver",
"The kernel must be square and have an\n"
41 +
"odd width. This kernel is "+kw+
"x"+kh+
".");
52 public void run(ImageProcessor ip) {
57 convolve(ip, kernel, kw, kh);
64 gd.addTextAreas(kernelText, null, 10, 30);
65 gd.addCheckbox(
"Normalize Kernel", normalize);
67 if (gd.wasCanceled()) {
71 kernelText = gd.getNextText();
72 normalize = gd.getNextBoolean();
73 StringTokenizer st =
new StringTokenizer(kernelText);
74 int n = st.countTokens();
75 kw = (int)Math.sqrt(n);
78 float[] k =
new float[n];
79 for (
int i=0; i<n; i++)
80 k[i] = (
float)getNum(st);
87 double getNum(StringTokenizer st) {
89 String token = st.nextToken();
90 try {d =
new Double(token);}
91 catch (NumberFormatException e){d = null;}
93 return(d.doubleValue());
98 public void convolve(ImageProcessor ip,
float[] kernel,
int kw,
int kh) {
99 if ((kw&1)!=1 || (kh&1)!=1)
100 throw new IllegalArgumentException(
"Kernel width or height not odd");
102 if (ip instanceof ByteProcessor)
104 else if (ip instanceof ShortProcessor)
106 else if (ip instanceof FloatProcessor)
111 ip.setCalibrationTable(null);
112 ImageProcessor ip2 = ip.convertToFloat();
113 ip2.setRoi(ip.getRoi());
114 ip2.setMask(ip.getMask());
115 convolveFloat(ip2, kernel, kw, kh);
118 ip2 = ip2.convertToByte(
false);
119 byte[] pixels = (byte[])ip.getPixels();
120 byte[] pixels2 = (byte[])ip2.getPixels();
121 System.arraycopy(pixels2, 0, pixels, 0, pixels.length);
124 ip2 = ip2.convertToShort(
false);
125 short[] pixels16 = (
short[])ip.getPixels();
126 short[] pixels16b = (
short[])ip2.getPixels();
127 System.arraycopy(pixels16b, 0, pixels16, 0, pixels16.length);
134 public void setNormalize(
boolean normalizeKernel) {
135 normalize = normalizeKernel;
138 public void convolveFloat(ImageProcessor ip,
float[] kernel,
int kw,
int kh) {
139 int width = ip.getWidth();
140 int height = ip.getHeight();
141 Rectangle r = ip.getRoi();
142 boolean isRoi = r.width!=width||r.height!=height;
143 boolean nonRectRoi = isRoi && ip.getMask()!=null;
148 int x2 = x1 + r.width;
149 int y2 = y1 + r.height;
152 float[] pixels = (
float[])ip.getPixels();
153 float[] pixels2 = (
float[])ip.getPixelsCopy();
160 for (
int i=0; i<kernel.length; i++)
163 scale = (float)(1.0/sum);
166 int progress = Math.max((y2-y1)/25,1);
170 int xedge = width-uc;
171 int yedge = height-vc;
172 for(
int y=y1; y<y2; y++) {
173 if (y%progress ==0) IJ.showProgress((
double)y/height);
174 for(
int x=x1; x<x2; x++) {
177 edgePixel = y<vc || y>=yedge || x<uc || x>=xedge;
178 for(
int v=-vc; v <= vc; v++) {
179 offset = x+(y+v)*width;
180 for(
int u = -uc; u <= uc; u++) {
182 sum += getPixel(x+u, y+v, pixels2, width, height)*kernel[i++];
184 sum += pixels2[offset+u]*kernel[i++];
187 pixels[x+y*width] = (float)(sum*scale);
191 ip.reset(ip.getMask());
192 IJ.showProgress(1.0);
195 private float getPixel(
int x,
int y,
float[] pixels,
int width,
int height) {
197 if (x>=width) x = width-1;
199 if (y>=height) y = height-1;
200 return pixels[x+y*width];