package ij.plugin.filter;
import ij.*;
import ij.gui.GenericDialog;
import ij.gui.DialogListener;
import ij.process.*;
import ij.plugin.filter.GaussianBlur;
import ij.measure.Measurements;
import java.awt.*;
public class UnsharpMask implements ExtendedPlugInFilter, DialogListener {
private static double sigma = 1.0; private static double weight = 0.6; private final int flags = DOES_ALL|SUPPORTS_MASKING|CONVERT_TO_FLOAT|SNAPSHOT|KEEP_PREVIEW;
private GaussianBlur gb;
public int setup(String arg, ImagePlus imp) {
return flags;
}
public void run(ImageProcessor ip) {
sharpenFloat((FloatProcessor)ip, sigma, (float)weight);
}
public void sharpenFloat(FloatProcessor fp, double sigma, float weight) {
if (gb == null) gb = new GaussianBlur();
gb.blurGaussian(fp, sigma, sigma, 0.01);
if (Thread.currentThread().isInterrupted()) return;
float[] pixels = (float[])fp.getPixels();
float[] snapshotPixels = (float[])fp.getSnapshotPixels();
int width = fp.getWidth();
Rectangle roi = fp.getRoi();
for (int y=roi.y; y<roi.y+roi.height; y++)
for (int x=roi.x, p=width*y+x; x<roi.x+roi.width; x++,p++)
pixels[p] = (snapshotPixels[p] - weight*pixels[p])/(1f - weight);
}
public int showDialog(ImagePlus imp, String command, PlugInFilterRunner pfr) {
String options = Macro.getOptions();
boolean oldMacro = false; if (options!=null) {
if (options.indexOf("gaussian=") >= 0) {
oldMacro = true;
Macro.setOptions(options.replaceAll("gaussian=", "radius="));
}
}
GenericDialog gd = new GenericDialog(command);
sigma = Math.abs(sigma);
if (weight<0) weight = 0;
if (weight>0.99) weight = 0.99;
gd.addNumericField("Radius (Sigma)", sigma, 1, 6, "pixels");
gd.addNumericField("Mask Weight (0.1-0.9)", weight,2);
gd.addPreviewCheckbox(pfr);
gd.addDialogListener(this);
gd.showDialog(); if (gd.wasCanceled()) return DONE;
if (oldMacro) sigma /= 2.5;
IJ.register(this.getClass()); return IJ.setupDialog(imp, flags); }
public boolean dialogItemChanged(GenericDialog gd, AWTEvent e) {
sigma = gd.getNextNumber();
weight = gd.getNextNumber();
if (sigma < 0 || weight < 0 || weight > 0.99 || gd.invalidNumber())
return false;
else return true;
}
public void setNPasses(int nPasses) {
if (gb == null) gb = new GaussianBlur();
gb.setNPasses(nPasses);
}
}