package ini.trakem2.imaging.filters;
import ij.process.ColorProcessor;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
import java.util.Map;
import java.util.Random;
public class ValueToNoise implements IFilter
{
final static private void processFloatNaN(final FloatProcessor ip, final double min, final double max) {
final double scale = max - min;
final Random rnd = new Random();
final int n = ip.getWidth() * ip.getHeight();
for (int i =0; i < n; ++i) {
final float v = ip.getf(i);
if (Float.isNaN(v))
ip.setf(i, (float)(rnd.nextDouble() * scale + min));
}
}
final static private void processFloat(final FloatProcessor ip, final float value, final double min, final double max) {
final double scale = max - min;
final Random rnd = new Random();
final int n = ip.getWidth() * ip.getHeight();
for (int i =0; i < n; ++i) {
final float v = ip.getf(i);
if (v == value)
ip.setf(i, (float)(rnd.nextDouble() * scale + min));
}
}
final static private void processGray(final ImageProcessor ip, final int value, final int min, final int max) {
final int scale = max - min + 1;
final Random rnd = new Random();
final int n = ip.getWidth() * ip.getHeight();
for (int i =0; i < n; ++i) {
final int v = ip.get(i);
if (v == value)
ip.set(i, rnd.nextInt(scale) + min);
}
}
final static private void processColor(final ColorProcessor ip, final int value, final int min, final int max) {
final int scale = max - min + 1;
final Random rnd = new Random();
final int n = ip.getWidth() * ip.getHeight();
for (int i =0; i < n; ++i) {
final int v = ip.get(i);
if (v == value)
{
final int r = rnd.nextInt(scale) + min;
final int g = rnd.nextInt(scale) + min;
final int b = rnd.nextInt(scale) + min;
ip.set(i, (((((0xff << 8) | r) << 8) | g) << 8) | b);
}
}
}
protected double value = Double.NaN, min = 0, max = 255;
public ValueToNoise() {}
public ValueToNoise(
final double value,
final double min,
final double max) {
set(value, min, max);
}
private final void set(
final double value,
final double min,
final double max) {
this.value = value;
this.min = min;
this.max = max;
}
public ValueToNoise(final Map<String,String> params) {
try {
set(
Double.parseDouble(params.get("value")),
Double.parseDouble(params.get("min")),
Double.parseDouble(params.get("max")));
} catch (final NumberFormatException nfe) {
throw new IllegalArgumentException("Could not create ValueToNoise filter!", nfe);
}
}
@Override
public ImageProcessor process(final ImageProcessor ip) {
try {
if (FloatProcessor.class.isInstance(ip)) {
if (Double.isNaN(value))
processFloatNaN((FloatProcessor)ip, min, max);
else
processFloat((FloatProcessor)ip, (float)value, min, max);
} else {
if (ColorProcessor.class.isInstance(ip))
processColor((ColorProcessor)ip, (int)Math.round(value), (int)Math.round(min), (int)Math.round(max));
else
processGray(ip, (int)Math.round(value), (int)Math.round(min), (int)Math.round(max));
}
} catch (final Exception e) {
e.printStackTrace();
}
return ip;
}
@Override
public String toXML(final String indent) {
return new StringBuilder(indent)
.append("<t2_filter class=\"").append(getClass().getName())
.append("\" value=\"").append(value)
.append("\" min=\"").append(min)
.append("\" max=\"").append(max)
.append("\" />\n").toString();
}
@Override
public boolean equals(final Object o) {
if (null == o) return false;
if (o.getClass() == ValueToNoise.class) {
final ValueToNoise c = (ValueToNoise)o;
return
(Double.isNaN(value) && Double.isNaN(c.value) || value == c.value) &&
min == c.min &&
max == c.max;
}
return false;
}
}