use of uk.ac.sussex.gdsc.test.api.function.FloatFloatBiPredicate in project GDSC-SMLM by aherbert.
the class WeightedKernelFilterTest method filterPerformsWeightedKernelFiltering.
@SeededTest
void filterPerformsWeightedKernelFiltering(RandomSeed seed) {
final DataFilter filter = createDataFilter();
final UniformRandomProvider rg = RngUtils.create(seed.getSeed());
final SharedStateContinuousSampler gs = SamplerUtils.createGaussianSampler(rg, 2, 0.2);
final float[] offsets = getOffsets(filter);
final int[] boxSizes = getBoxSizes(filter);
final TDoubleArrayList l1 = new TDoubleArrayList();
final FloatFloatBiPredicate equality = TestHelper.floatsAreClose(1e-6, 0);
for (final int width : primes) {
for (final int height : new int[] { 29 }) {
final float[] data = createData(width, height, rg);
l1.reset();
// Uniform weights
final float[] w1 = new float[width * height];
Arrays.fill(w1, 0.5f);
// Weights simulating the variance of sCMOS pixels
final float[] w2 = new float[width * height];
for (int i = 0; i < w2.length; i++) {
w2[i] = (float) (1.0 / Math.max(0.01, gs.sample()));
}
for (final int boxSize : boxSizes) {
for (final float offset : offsets) {
for (final boolean internal : checkInternal) {
// For each pixel over the range around the pixel (vi).
// kernel filter: sum(vi * ki) / sum(ki)
// Weighted kernel filter: sum(vi * wi * ki) / sum(ki * wi)
// Note: The kernel filter is like a weighted filter
// (New kernel = wi * ki)
filter.setWeights(null, width, height);
// Uniform weights
testfilterPerformsWeightedFiltering(filter, width, height, data, w1, boxSize, offset, internal, equality);
// Random weights.
testfilterPerformsWeightedFiltering(filter, width, height, data, w2, boxSize, offset, internal, equality);
}
}
}
}
}
}
use of uk.ac.sussex.gdsc.test.api.function.FloatFloatBiPredicate in project GDSC-SMLM by aherbert.
the class WeightedFilterTest method evenWeightsDoesNotAlterFiltering.
@SeededTest
void evenWeightsDoesNotAlterFiltering(RandomSeed seed) {
final UniformRandomProvider rg = RngUtils.create(seed.getSeed());
final DataFilter filter1 = createDataFilter();
final DataFilter filter2 = createDataFilter();
final float[] offsets = getOffsets(filter1);
final int[] boxSizes = getBoxSizes(filter1);
final int[] primes = Arrays.copyOf(WeightedFilterTest.primes, WeightedFilterTest.primes.length - 1);
final FloatFloatBiPredicate equality = TestHelper.floatsAreClose(1e-4, 0);
for (final int width : primes) {
for (final int height : primes) {
final float[] data = createData(width, height, rg);
// Uniform weights
final float[] w = new float[width * height];
Arrays.fill(w, 0.5f);
filter2.setWeights(w, width, height);
for (final int boxSize : boxSizes) {
for (final float offset : offsets) {
for (final boolean internal : checkInternal) {
final float[] e = filter(data, width, height, boxSize - offset, internal, filter1);
final float[] o = filter(data, width, height, boxSize - offset, internal, filter2);
try {
TestAssertions.assertArrayTest(e, o, equality);
} catch (final AssertionError ex) {
final String msg = String.format("%s : [%dx%d] @ %.1f [internal=%b]", filter2.name, width, height, boxSize - offset, internal);
throw new AssertionError(msg, ex);
}
}
}
}
}
}
}
use of uk.ac.sussex.gdsc.test.api.function.FloatFloatBiPredicate in project GDSC-SMLM by aherbert.
the class WeightedMeanFilterTest method filterPerformsWeightedMeanFiltering.
@SeededTest
void filterPerformsWeightedMeanFiltering(RandomSeed seed) {
final DataFilter filter = createDataFilter();
final UniformRandomProvider rg = RngUtils.create(seed.getSeed());
final SharedStateContinuousSampler gs = SamplerUtils.createGaussianSampler(rg, 2, 0.2);
final float[] offsets = getOffsets(filter);
final int[] boxSizes = getBoxSizes(filter);
final TDoubleArrayList l1 = new TDoubleArrayList();
final FloatFloatBiPredicate equality = TestHelper.floatsAreClose(1e-6, 0);
for (final int width : primes) {
for (final int height : primes) {
final float[] data = createData(width, height, rg);
l1.reset();
// Uniform weights
final float[] w1 = new float[width * height];
Arrays.fill(w1, 0.5f);
// Weights simulating the variance of sCMOS pixels
final float[] w2 = new float[width * height];
for (int i = 0; i < w2.length; i++) {
w2[i] = (float) (1.0 / Math.max(0.01, gs.sample()));
}
for (final int boxSize : boxSizes) {
for (final float offset : offsets) {
for (final boolean internal : checkInternal) {
// For each pixel over the range around the pixel (vi).
// Mean filter: sum(vi) / n
// Weighted mean: sum(vi * wi) / sum(wi) == mean(vi * wi) / mean(wi)
filter.setWeights(null, width, height);
// Uniform weights
testfilterPerformsWeightedFiltering(filter, width, height, data, w1, boxSize, offset, internal, equality);
// Random weights.
testfilterPerformsWeightedFiltering(filter, width, height, data, w2, boxSize, offset, internal, equality);
}
}
}
}
}
}
use of uk.ac.sussex.gdsc.test.api.function.FloatFloatBiPredicate in project GDSC-SMLM by aherbert.
the class FhtFilterTest method canFilter.
private static void canFilter(RandomSeed seed, Operation operation) {
final int size = 16;
final int ex = 5;
final int ey = 7;
final int ox = 1;
final int oy = 2;
final UniformRandomProvider r = RngUtils.create(seed.getSeed());
final FloatProcessor fp1 = createProcessor(size, ex, ey, 4, 4, r);
// This is offset from the centre
final FloatProcessor fp2 = createProcessor(size, size / 2 + ox, size / 2 + oy, 4, 4, r);
final float[] input1 = ((float[]) fp1.getPixels()).clone();
final float[] input2 = ((float[]) fp2.getPixels()).clone();
final FHT fht1 = new FHT(fp1);
fht1.transform();
final FHT fht2 = new FHT(fp2);
fht2.transform();
FHT fhtE;
switch(operation) {
case CONVOLUTION:
fhtE = fht1.multiply(fht2);
break;
case CORRELATION:
fhtE = fht1.conjugateMultiply(fht2);
break;
case DECONVOLUTION:
fhtE = fht1.divide(fht2);
break;
default:
throw new RuntimeException();
}
fhtE.inverseTransform();
fhtE.swapQuadrants();
final float[] e = (float[]) fhtE.getPixels();
if (operation == Operation.CORRELATION) {
// Test the max correlation position
final int max = SimpleArrayUtils.findMaxIndex(e);
final int x = max % 16;
final int y = max / 16;
Assertions.assertEquals(ex, x + ox);
Assertions.assertEquals(ey, y + oy);
}
// Test verses a spatial domain filter in the middle of the image
if (operation != Operation.DECONVOLUTION) {
double sum = 0;
float[] i2 = input2;
if (operation == Operation.CONVOLUTION) {
i2 = i2.clone();
KernelFilter.rotate180(i2);
}
for (int i = 0; i < input1.length; i++) {
sum += input1[i] * i2[i];
}
// double exp = e[size / 2 * size + size / 2];
// logger.fine(() -> String.format("Sum = %f vs [%d] %f", sum, size / 2 * size + size / 2,
// exp);
Assertions.assertEquals(sum, sum, 1e-3);
}
// Test the FHT filter
final FhtFilter ff = new FhtFilter(input2, size, size);
ff.setOperation(operation);
ff.filter(input1, size, size);
// There may be differences due to the use of the JTransforms library
final double error = (operation == Operation.DECONVOLUTION) ? 5e-2 : 1e-4;
final FloatFloatBiPredicate predicate = TestHelper.floatsAreClose(error, 0);
// This tests everything and can fail easily depending on the random generator
// due to edge artifacts.
// TestAssertions.assertArrayTest(e, input1, TestHelper.almostEqualFloats(error, 0));
// This tests the centre to ignore edge differences
final int min = size / 4;
final int max = size - min;
int repeats = 0;
for (int y = min; y < max; y++) {
for (int x = min; x < max; x++) {
repeats++;
}
}
// Use a fail counter for a 'soft' test that detects major problems
final int failureLimit = TestCounter.computeFailureLimit(repeats, 0.1);
final TestCounter failCounter = new TestCounter(failureLimit);
final IndexSupplier msg = new IndexSupplier(2);
for (int y = min; y < max; y++) {
msg.set(1, y);
for (int x = min; x < max; x++) {
final int xx = x;
final int i = y * size + x;
failCounter.run(() -> {
TestAssertions.assertTest(e[i], input1[i], predicate, msg.set(0, xx));
});
}
}
}
use of uk.ac.sussex.gdsc.test.api.function.FloatFloatBiPredicate in project GDSC-SMLM by aherbert.
the class WeightedSumFilterTest method filterPerformsWeightedSumFiltering.
@SeededTest
void filterPerformsWeightedSumFiltering(RandomSeed seed) {
final DataFilter filter = createDataFilter();
final UniformRandomProvider rg = RngUtils.create(seed.getSeed());
final SharedStateContinuousSampler gs = SamplerUtils.createGaussianSampler(rg, 2, 0.2);
final float[] offsets = getOffsets(filter);
final int[] boxSizes = getBoxSizes(filter);
final TDoubleArrayList l1 = new TDoubleArrayList();
final FloatFloatBiPredicate equality = TestHelper.floatsAreClose(1e-6, 0);
for (final int width : primes) {
for (final int height : primes) {
final float[] data = createData(width, height, rg);
l1.reset();
// Ones used for normalisation
final float[] ones = new float[width * height];
Arrays.fill(ones, 1f);
// Uniform weights
final float[] w1 = new float[width * height];
Arrays.fill(w1, 0.5f);
// Weights simulating the variance of sCMOS pixels
final float[] w2 = new float[width * height];
for (int i = 0; i < w2.length; i++) {
w2[i] = (float) (1.0 / Math.max(0.01, gs.sample()));
}
for (final int boxSize : boxSizes) {
for (final float offset : offsets) {
for (final boolean internal : checkInternal) {
// For each pixel over the range around the pixel (vi).
// Sum filter: sum(vi)
// Weighted sum: sum(vi * wi) / mean(wi)
// (This makes the output image have a similar mean)
filter.setWeights(null, width, height);
// Uniform weights
testfilterPerformsWeightedFiltering(filter, width, height, data, w1, boxSize, offset, internal, ones, equality);
// Random weights.
testfilterPerformsWeightedFiltering(filter, width, height, data, w2, boxSize, offset, internal, ones, equality);
}
}
}
}
}
}
Aggregations