Skip to content

Commit 67f7e97

Browse files
committed
WIP: Work
TODO: Split into multiple commits
1 parent 5440061 commit 67f7e97

File tree

4 files changed

+212
-10
lines changed

4 files changed

+212
-10
lines changed

src/main/java/net/imagej/ops/filter/FilterNamespace.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,21 +132,21 @@ public <I extends RealType<I>, O extends RealType<O>> O addPoissonNoise(
132132
}
133133

134134
@OpMethod(op = net.imagej.ops.filter.addUniformNoise.AddUniformNoiseRealType.class)
135-
public <I extends RealType<I>, O extends RealType<O>> O addUniformNoise(final O out,
135+
public <I extends RealType<I>> I addUniformNoise(final I out,
136136
final I in, final double rangeMin, final double rangeMax)
137137
{
138138
@SuppressWarnings("unchecked")
139-
final O result = (O) ops().run(Ops.Filter.AddUniformNoise.class, out, in, rangeMin,
139+
final I result = (I) ops().run(Ops.Filter.AddUniformNoise.class, out, in, rangeMin,
140140
rangeMax);
141141
return result;
142142
}
143143

144144
@OpMethod(op = net.imagej.ops.filter.addUniformNoise.AddUniformNoiseRealType.class)
145-
public <I extends RealType<I>, O extends RealType<O>> O addUniformNoise(final O out,
145+
public <I extends RealType<I>> I addUniformNoise(final I out,
146146
final I in, final double rangeMin, final double rangeMax, final long seed)
147147
{
148148
@SuppressWarnings("unchecked")
149-
final O result = (O) ops().run(Ops.Filter.AddUniformNoise.class, out, in, rangeMin,
149+
final I result = (I) ops().run(Ops.Filter.AddUniformNoise.class, out, in, rangeMin,
150150
rangeMax, seed);
151151
return result;
152152
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2014 - 2018 ImageJ developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
30+
package net.imagej.ops.filter.addUniformNoise;
31+
32+
import net.imagej.ops.Ops;
33+
import net.imagej.ops.special.computer.AbstractUnaryComputerOp;
34+
import net.imglib2.type.numeric.IntegerType;
35+
36+
import org.scijava.Priority;
37+
import org.scijava.plugin.Parameter;
38+
import org.scijava.plugin.Plugin;
39+
import org.scijava.util.MersenneTwisterFast;
40+
41+
/**
42+
* Adds a pseudorandomly generated value {@code x} to a {@link IntegerType}
43+
* {@code I}, such that {@code x} is (inclusively) bounded by {@code rangeMin}
44+
* and {@code rangeMax} parameters, i.e. {@code rangeMin <= x <= rangeMax}.
45+
*
46+
* @author Gabe Selzer
47+
*/
48+
@Plugin(type = Ops.Filter.AddUniformNoise.class, priority = Priority.HIGH)
49+
public class AddUniformNoiseIntegerType<I extends IntegerType<I>>
50+
extends AbstractUnaryComputerOp<I, I> implements Ops.Filter.AddUniformNoise
51+
{
52+
53+
/**
54+
* The greatest that an input value can be decreased.
55+
*/
56+
@Parameter
57+
private long rangeMin;
58+
59+
/**
60+
* The greatest that an input value can be <b> increased </b>
61+
*/
62+
@Parameter
63+
private long rangeMax;
64+
65+
/**
66+
* If false, the Op will wrap outputs that are outside of the type bounds,
67+
* instead of clamping them
68+
*/
69+
@Parameter(required = false)
70+
private boolean clampOutput = true;
71+
72+
@Parameter(required = false)
73+
private long seed = 0xabcdef1234567890L;
74+
75+
private MersenneTwisterFast rng;
76+
77+
@Override
78+
public void initialize() {
79+
if (rng == null) rng = new MersenneTwisterFast(seed);
80+
if (rangeMax < rangeMin) {
81+
long temp = rangeMax;
82+
rangeMax = rangeMin;
83+
rangeMin = temp;
84+
}
85+
86+
}
87+
88+
@Override
89+
public void compute(I input, I output) {
90+
final long newVal = rng.nextLong(rangeMax - rangeMin + 1) +
91+
rangeMin + input.getIntegerLong();
92+
93+
// clamp output
94+
if (clampOutput) {
95+
output.setReal(Math.max(input.getMinValue(), Math.min(input.getMaxValue(),
96+
newVal)));
97+
}
98+
99+
// wrap output
100+
else {
101+
double outVal = newVal;
102+
// when output larger than max value, add difference of output and max
103+
// value to the min value
104+
while (outVal > input.getMaxValue()) {
105+
outVal = input.getMinValue() + (outVal - input.getMaxValue() - 1);
106+
}
107+
// when output smaller than min value, subtract difference of output and
108+
// min value from the max value
109+
while (outVal < input.getMinValue()) {
110+
outVal = input.getMaxValue() - (outVal - input.getMinValue() + 1);
111+
}
112+
113+
output.setReal(outVal);
114+
}
115+
116+
}
117+
118+
}

src/main/java/net/imagej/ops/filter/addUniformNoise/AddUniformNoiseRealType.java

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ public class AddUniformNoiseRealType<I extends RealType<I>>
6161
@Parameter
6262
private double rangeMax;
6363

64+
/**
65+
* If false, the Op will wrap outputs that are outside of the type bounds,
66+
* instead of clamping them
67+
*/
68+
@Parameter(required = false)
69+
private boolean clampOutput = true;
70+
6471
@Parameter(required = false)
6572
private long seed = 0xabcdef1234567890L;
6673

@@ -86,12 +93,30 @@ public void initialize() {
8693
public void compute(I input, I output) {
8794
final double newVal = (rangeMax - rangeMin) * rng.nextDouble(true, true) +
8895
rangeMin + input.getRealDouble();
89-
if (newVal > input.getMaxValue())
90-
output.setReal(input.getMaxValue());
91-
else if (newVal < input.getMinValue())
92-
output.setReal(input.getMinValue());
93-
else
94-
output.setReal(newVal);
96+
97+
// clamp output
98+
if (clampOutput) {
99+
output.setReal(Math.max(input.getMinValue(), Math.min(input.getMaxValue(),
100+
newVal)));
101+
}
102+
103+
// wrap output
104+
else {
105+
double outVal = newVal;
106+
// when output larger than max value, add difference of output and max
107+
// value to the min value
108+
while (outVal > input.getMaxValue()) {
109+
outVal = input.getMinValue() + (outVal - input.getMaxValue());
110+
}
111+
// when output smaller than min value, subtract difference of output and
112+
// min value from the max value
113+
while (outVal < input.getMinValue()) {
114+
outVal = input.getMaxValue() - (outVal - input.getMinValue());
115+
}
116+
117+
output.setReal(outVal);
118+
}
119+
95120
}
96121

97122
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
package net.imagej.ops.filter.addUniformNoise;
3+
4+
import net.imagej.ops.AbstractOpTest;
5+
import net.imagej.ops.Ops;
6+
import net.imagej.ops.special.computer.Computers;
7+
import net.imagej.ops.special.computer.UnaryComputerOp;
8+
import net.imglib2.type.numeric.integer.UnsignedByteType;
9+
import net.imglib2.type.numeric.real.DoubleType;
10+
11+
import org.junit.Assert;
12+
import org.junit.Test;
13+
14+
/**
15+
* Tests {@link AddUniformNoiseRealType}.
16+
*
17+
* @author Gabriel Selzer
18+
*/
19+
public class AddUniformNoiseTest extends AbstractOpTest {
20+
21+
@Test
22+
public void realTypeRegressionTest() {
23+
UnaryComputerOp<DoubleType, DoubleType> noiseFunc = Computers
24+
.unary(ops, Ops.Filter.AddUniformNoise.class, DoubleType.class,
25+
DoubleType.class, 0d, 2d);
26+
27+
double[] actual = new double[9];
28+
DoubleType temp = new DoubleType();
29+
for (int i = 0; i < actual.length; i++) {
30+
noiseFunc.compute(new DoubleType(254), temp);
31+
actual[i] = temp.getRealDouble();
32+
}
33+
34+
double[] expected = { 254.10073053454738, 255.88056371733813,
35+
255.15987104925694, 255.32176185269049, 254.92408976012726,
36+
255.04150474558148, 255.4924837511821, 254.66400205149753,
37+
254.45238896293924 };
38+
Assert.assertArrayEquals(expected, actual, 1e-6);
39+
}
40+
41+
@Test
42+
public void testWrapping() {
43+
UnaryComputerOp<UnsignedByteType, UnsignedByteType> noiseFunc = Computers
44+
.unary(ops, Ops.Filter.AddUniformNoise.class, UnsignedByteType.class,
45+
UnsignedByteType.class, 0l, 3l, false);
46+
47+
int[] actual = new int[9];
48+
UnsignedByteType temp = new UnsignedByteType();
49+
for (int i = 0; i < actual.length; i++) {
50+
noiseFunc.compute(new UnsignedByteType(254), temp);
51+
System.out.println(temp.get());
52+
actual[i] = temp.get();
53+
}
54+
55+
int[] expected = {254, 255, 255, 255, 255, 255, 255, 255, 254};
56+
Assert.assertArrayEquals(expected, actual);
57+
}
58+
59+
}

0 commit comments

Comments
 (0)