use of net.imglib2.FinalInterval in project imagej-ops by imagej.
the class ListDilate method compute.
@Override
public void compute(final RandomAccessibleInterval<T> in1, final List<Shape> in2, final IterableInterval<T> out) {
final long[][] minSize = Morphologies.computeMinSize(in1, in2);
final Interval interval = new FinalInterval(minSize[1]);
Img<T> upstream = imgCreator.calculate(interval);
Img<T> downstream = imgCreator.calculate(interval);
Img<T> tmp;
dilateComputer.compute(in1, in2.get(0), Views.translate(downstream, minSize[0]));
for (int i = 1; i < in2.size(); i++) {
// Ping-ponging intermediate results between upstream and downstream to
// avoid repetitively creating new Imgs.
tmp = downstream;
downstream = upstream;
upstream = tmp;
dilateComputer.compute(upstream, in2.get(i), downstream);
}
if (isFull)
copyImg.compute(downstream, out);
else
copyImg.compute(Views.interval(Views.translate(downstream, minSize[0]), out), out);
}
use of net.imglib2.FinalInterval in project imagej-ops by imagej.
the class DefaultScaleView method calculate.
@Override
public RandomAccessibleInterval<T> calculate(RandomAccessibleInterval<T> input) {
final long[] newDims = Intervals.dimensionsAsLongArray(in());
for (int i = 0; i < Math.min(scaleFactors.length, in().numDimensions()); i++) {
newDims[i] = Math.round(in().dimension(i) * scaleFactors[i]);
}
IntervalView<T> interval = Views.interval(Views.raster(RealViews.affineReal(Views.interpolate(Views.extendMirrorSingle(input), interpolator), new Scale(scaleFactors))), new FinalInterval(newDims));
return interval;
}
use of net.imglib2.FinalInterval in project imagej-ops by imagej.
the class PaddingIntervalOrigin method calculate.
@Override
@SuppressWarnings("unchecked")
public O calculate(final I input, final Interval centeredInterval) {
int numDimensions = input.numDimensions();
// compute where to place the final Interval for the input so that the
// coordinate in the center
// of the input is at position (0,0).
final long[] min = new long[numDimensions];
final long[] max = new long[numDimensions];
for (int d = 0; d < numDimensions; ++d) {
min[d] = input.min(d) + input.dimension(d) / 2;
max[d] = min[d] + centeredInterval.dimension(d) - 1;
}
return (O) new FinalInterval(min, max);
}
use of net.imglib2.FinalInterval in project imagej-ops by imagej.
the class DefaultBilateral method compute.
@Override
public void compute(final RandomAccessibleInterval<I> input, final RandomAccessibleInterval<O> output) {
final long[] size = new long[input.numDimensions()];
input.dimensions(size);
final RandomAccess<O> outputRA = output.randomAccess();
final Cursor<I> inputCursor = Views.iterable(input).localizingCursor();
final long[] currentPos = new long[input.numDimensions()];
final long[] neighborhoodPos = new long[input.numDimensions()];
final long[] neighborhoodMin = new long[input.numDimensions()];
final long[] neighborhoodMax = new long[input.numDimensions()];
Neighborhood<I> neighborhood;
Cursor<I> neighborhoodCursor;
final RectangleNeighborhoodFactory<I> fac = RectangleNeighborhood.factory();
while (inputCursor.hasNext()) {
inputCursor.fwd();
inputCursor.localize(currentPos);
double distance;
inputCursor.localize(neighborhoodMin);
inputCursor.localize(neighborhoodMax);
neighborhoodMin[0] = Math.max(0, neighborhoodMin[0] - radius);
neighborhoodMin[1] = Math.max(0, neighborhoodMin[1] - radius);
neighborhoodMax[0] = Math.min(input.max(0), neighborhoodMax[0] + radius);
neighborhoodMax[1] = Math.min(input.max(1), neighborhoodMax[1] + radius);
final Interval interval = new FinalInterval(neighborhoodMin, neighborhoodMax);
neighborhood = fac.create(currentPos, neighborhoodMin, neighborhoodMax, interval, input.randomAccess());
neighborhoodCursor = neighborhood.localizingCursor();
double weight, v = 0.0;
double w = 0.0;
do {
neighborhoodCursor.fwd();
neighborhoodCursor.localize(neighborhoodPos);
distance = getDistance(currentPos, neighborhoodPos);
// spatial kernel
weight = gauss(distance, sigmaS);
// intensity
distance = Math.abs(inputCursor.get().getRealDouble() - neighborhoodCursor.get().getRealDouble());
// difference
// range kernel, then exponent addition
weight *= gauss(distance, sigmaR);
v += weight * neighborhoodCursor.get().getRealDouble();
w += weight;
} while (neighborhoodCursor.hasNext());
outputRA.setPosition(currentPos);
outputRA.get().setReal(v / w);
}
}
use of net.imglib2.FinalInterval in project imagej-ops by imagej.
the class DefaultCreateKernel2ndDerivBiGauss method calculate.
@Override
public RandomAccessibleInterval<T> calculate(final double[] sigmas, final Integer dimensionality) {
// both sigmas must be available
if (sigmas.length < 2)
throw new IllegalArgumentException("Two sigmas (for inner and outer Gauss)" + " must be supplied.");
// both sigmas must be reasonable
if (sigmas[0] <= 0 || sigmas[1] <= 0)
throw new IllegalArgumentException("Input sigmas must be both positive.");
// dimension as well...
if (dimensionality <= 0)
throw new IllegalArgumentException("Input dimensionality must both positive.");
// the size and center of the output image
final long[] dims = new long[dimensionality];
final long[] centre = new long[dimensionality];
// time-saver... (must hold now: dimensionality > 0)
// NB: size of the image is 2px wider than for 0th order BiGauss to have
// some space for smooth approach-to-zero at the kernel image borders
dims[0] = Math.max(3, (2 * (int) (sigmas[0] + 3 * sigmas[1] + 0.5) + 1)) + 2;
centre[0] = (int) (dims[0] / 2);
// fill the size and center arrays
for (int d = 1; d < dims.length; d++) {
dims[d] = dims[0];
centre[d] = centre[0];
}
// prepare some scaling constants
/*
//orig full math version:
final double k = (sigmas[1]/sigmas[0]) * (sigmas[1]/sigmas[0]); //eq. (6)
final double[] C = { 1.0/(2.50663*sigmas[0]*sigmas[0]*sigmas[0]), 1.0/(2.50663*sigmas[1]*sigmas[1]*sigmas[1]) };
//2.50663 = sqrt(2*PI)
*/
// less math version:
// note that originally there was C[0] for inner Gauss, k*C[1] for outer Gauss
// we get rid of k by using new C[0] and C[1]:
final double[] C = { 1.0 / (2.50663 * sigmas[0] * sigmas[0] * sigmas[0]), 1.0 / (2.50663 * sigmas[1] * sigmas[0] * sigmas[0]) };
// prepare squared input sigmas
final double[] sigmasSq = { sigmas[0] * sigmas[0], sigmas[1] * sigmas[1] };
// prepare the output image
final RandomAccessibleInterval<T> out = createImgOp.calculate(new FinalInterval(dims));
// fill the output image
final Cursor<T> cursor = Views.iterable(out).cursor();
while (cursor.hasNext()) {
cursor.fwd();
// obtain the current coordinate (use dims to store it)
cursor.localize(dims);
// calculate distance from the image centre
// TODO: can JVM reuse this var or is it allocated again and again (and multipling in the memory)?
double dist = 0.;
for (int d = 0; d < dims.length; d++) {
final double dx = dims[d] - centre[d];
dist += dx * dx;
}
// dist = Math.sqrt(dist); -- gonna work with squared distance
// which of the two Gaussians should we use?
double val = 0.;
if (dist < sigmasSq[0]) {
// the inner one
val = (dist / sigmasSq[0]) - 1.0;
val *= C[0] * Math.exp(-0.5 * dist / sigmasSq[0]);
} else {
// the outer one, get new distance first:
dist = Math.sqrt(dist) - (sigmas[0] - sigmas[1]);
dist *= dist;
val = (dist / sigmasSq[1]) - 1.0;
val *= C[1] * Math.exp(-0.5 * dist / sigmasSq[1]);
}
// compose the real value finally
cursor.get().setReal(val);
}
return out;
}
Aggregations