Skip to content

Commit 434ae65

Browse files
authored
Merge pull request #115 from scijava/stale/imagej/imagej-ops2/noise-multithreading
Uniform Noise Adder using LoopBuilder
2 parents 8439a41 + 684c0e0 commit 434ae65

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

scijava-ops-image/src/main/java/org/scijava/ops/image/filter/addNoise/NoiseAdders.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import net.imglib2.RandomAccessibleInterval;
3535
import net.imglib2.loops.LoopBuilder;
3636
import net.imglib2.type.numeric.RealType;
37+
import org.scijava.common3.MersenneTwisterFast;
3738
import org.scijava.ops.spi.Nullable;
3839

3940
/**
@@ -164,4 +165,48 @@ public static <I extends RealType<I>, O extends RealType<O>> void addPoissonNois
164165
output.setReal(k - 1);
165166
}
166167

168+
// -- UNIFORM NOISE -- //
169+
170+
/**
171+
* Sets the real component of an output real number to the addition of the real
172+
* component of an input real number with an amount of uniform noise.
173+
*
174+
* @param input the input {@link RandomAccessibleInterval}
175+
* @param rangeMin the "most negative" value that can be added to each element
176+
* @param rangeMax the "most positive" value that can be added to each element
177+
* @param seed the seed to the random number generator
178+
* @param output the output {@link RandomAccessibleInterval}
179+
* @implNote op names='filter.addUniformNoise', type=Computer
180+
*/
181+
public static <I extends RealType<I>> void addUniformNoise( //
182+
RandomAccessibleInterval<I> input, //
183+
I rangeMin, //
184+
I rangeMax, //
185+
@Nullable Long seed, //
186+
RandomAccessibleInterval<I> output //
187+
) {
188+
// Set seed to default if necessary
189+
if (seed == null) {
190+
seed = 0xabcdef1234567890L;
191+
}
192+
// Construct the Random Number Generator
193+
MersenneTwisterFast rng = new MersenneTwisterFast(seed);
194+
// Find the range
195+
I range = rangeMax.createVariable();
196+
range.set(rangeMax);
197+
range.sub(rangeMin);
198+
199+
// Loop over the images
200+
LoopBuilder.setImages(input, output).forEachPixel( (i, o) -> {
201+
// Random value = next double * range
202+
o.set(range);
203+
o.mul(rng.nextDouble(true, true));
204+
// Add the range minimum
205+
o.add(rangeMin);
206+
// Add the original value
207+
o.add(i);
208+
});
209+
210+
}
211+
167212
}

scijava-ops-image/src/test/java/org/scijava/ops/image/OpRegressionTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class OpRegressionTest {
4242

4343
@Test
4444
public void opDiscoveryRegressionIT() {
45-
long expected = 1882;
45+
long expected = 1884;
4646
long actual = ops.infos().size();
4747
assertEquals(expected, actual);
4848
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.scijava.ops.image.filter.addNoise;
2+
3+
import net.imglib2.img.array.ArrayImgs;
4+
import net.imglib2.type.numeric.integer.ByteType;
5+
import org.junit.jupiter.api.Assertions;
6+
import org.junit.jupiter.api.Test;
7+
import org.scijava.ops.image.AbstractOpTest;
8+
9+
import java.util.Arrays;
10+
import java.util.List;
11+
12+
public class NoiseAddersTest extends AbstractOpTest {
13+
14+
@Test
15+
public void testAddUniformNoiseRegression() {
16+
var input = ArrayImgs.bytes(2, 2);
17+
ops.unary("image.fill").input(new ByteType((byte) 1)).output(input).compute();
18+
var output = ArrayImgs.bytes(2, 2);
19+
var rangeMin = new ByteType((byte) -1);
20+
var rangeMax = new ByteType((byte) 1);
21+
ops.ternary("filter.addUniformNoise").input(input, rangeMin, rangeMax).output(output).compute();
22+
var cursor = output.cursor();
23+
List<Byte> expected = Arrays.asList((byte) 0, (byte) 2, (byte) 1, (byte) 1);
24+
for(var e : expected) {
25+
Assertions.assertEquals(e, cursor.next().get());
26+
}
27+
Assertions.assertFalse(cursor.hasNext());
28+
}
29+
}

0 commit comments

Comments
 (0)