use of net.imglib2.Cursor in project imagej-ops by imagej.
the class DefaultCreateKernelBiGauss 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)
dims[0] = Math.max(3, (2 * (int) (sigmas[0] + 2 * sigmas[1] + 0.5) + 1));
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
// eq. (6)
final double k = (sigmas[1] / sigmas[0]) * (sigmas[1] / sigmas[0]);
// eq. (9)
final double c0 = 0.24197 * ((sigmas[1] / sigmas[0]) - 1.0) / sigmas[0];
// 0.24197 = 1/sqrt(2*PI*e) = 1/sqrt(2*PI) * exp(-0.5)
final double[] C = { 1.0 / (2.50663 * sigmas[0]), 1.0 / (2.50663 * sigmas[1]) };
// 2.50663 = sqrt(2*PI)
// 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 = C[0] * Math.exp(-0.5 * dist / sigmasSq[0]) + c0;
} else {
// the outer one, get new distance first:
dist = Math.sqrt(dist) - (sigmas[0] - sigmas[1]);
dist *= dist;
val = k * C[1] * Math.exp(-0.5 * dist / sigmasSq[1]);
}
// compose the real value finally
cursor.get().setReal(val);
}
return out;
}
use of net.imglib2.Cursor in project imagej-ops by imagej.
the class CreateKernel2D method calculate.
@Override
public RandomAccessibleInterval<T> calculate(double[][] input) {
final long[] dims = { input.length, input[0].length };
final RandomAccessibleInterval<T> rai = createOp.calculate(new FinalInterval(dims));
final Cursor<T> cursor = Views.iterable(rai).cursor();
for (int j = 0; j < input.length; j++) {
for (int k = 0; k < input[j].length; k++) {
cursor.fwd();
cursor.get().setReal(input[j][k]);
}
}
return rai;
}
use of net.imglib2.Cursor in project imagej-ops by imagej.
the class AbstractThin method compute.
@Override
public void compute(final RandomAccessibleInterval<BitType> input, final RandomAccessibleInterval<BitType> output) {
// Create a new image as a buffer to store the thinning image in each
// iteration.
// This image and output are swapped each iteration since we need to work on
// the image
// without changing it.
final Img<BitType> buffer = ops().create().img(input, new BitType());
final IterableInterval<BitType> it1 = Views.iterable(buffer);
final IterableInterval<BitType> it2 = Views.iterable(output);
// Extend the buffer in order to be able to iterate care-free later.
final RandomAccessible<BitType> ra1 = Views.extendBorder(buffer);
final RandomAccessible<BitType> ra2 = Views.extendBorder(output);
// Used only in first iteration.
RandomAccessible<BitType> currRa = Views.extendBorder(input);
// Create cursors.
final Cursor<BitType> firstCursor = it1.localizingCursor();
Cursor<BitType> currentCursor = Views.iterable(input).localizingCursor();
final Cursor<BitType> secondCursor = it2.localizingCursor();
// Create pointers to the current and next cursor and set them to Buffer and
// output respectively.
Cursor<BitType> nextCursor;
nextCursor = secondCursor;
// The main loop.
boolean changes = true;
int i = 0;
// Until no more changes, do:
while (changes) {
changes = false;
// defined by the strategies).
for (int j = 0; j < m_strategy.getIterationsPerCycle(); ++j) {
// For each pixel in the image.
while (currentCursor.hasNext()) {
// Move both cursors
currentCursor.fwd();
nextCursor.fwd();
// Get the position of the current cursor.
final long[] coordinates = new long[currentCursor.numDimensions()];
currentCursor.localize(coordinates);
// Copy the value of the image currently operated upon.
final boolean curr = currentCursor.get().get();
nextCursor.get().set(curr);
// Only foreground pixels may be thinned
if (curr) {
// Ask the strategy whether to flip the foreground pixel or not.
final boolean flip = m_strategy.removePixel(coordinates, currRa, j);
// If yes - change and keep track of the change.
if (flip) {
nextCursor.get().set(false);
changes = true;
}
}
}
// One step of the cycle is finished, notify the strategy.
m_strategy.afterCycle();
// Reset the cursors to the beginning and assign pointers for the next
// iteration.
currentCursor.reset();
nextCursor.reset();
// Keep track of the most recent image. Needed for output.
if (currRa == ra2) {
currRa = ra1;
currentCursor = firstCursor;
nextCursor = secondCursor;
} else {
currRa = ra2;
currentCursor = secondCursor;
nextCursor = firstCursor;
}
// Keep track of iterations.
++i;
}
}
// ra2. Copy it to output.
if (i % 2 == 0) {
// Ra1 points to img1, ra2 points to output.
copy(buffer, output);
}
}
use of net.imglib2.Cursor in project imagej-ops by imagej.
the class IntegralVariance method compute.
@Override
public void compute(final RectangleNeighborhood<Composite<I>> input, final DoubleType output) {
// computation according to
// https://en.wikipedia.org/wiki/Summed_area_table
final IntegralCursor<Composite<I>> cursorS1 = new IntegralCursor<>(input);
final int dimensions = input.numDimensions();
// Compute \sum (-1)^{dim - ||cornerVector||_{1}} * I(x^{cornerVector})
final DoubleType sum1 = new DoubleType();
sum1.setZero();
// Convert from input to return type
final Converter<I, DoubleType> conv = new RealDoubleConverter<>();
// Compute \sum (-1)^{dim - ||cornerVector||_{1}} * I(x^{cornerVector})
final DoubleType sum2 = new DoubleType();
sum2.setZero();
final DoubleType valueAsDoubleType = new DoubleType();
while (cursorS1.hasNext()) {
final Composite<I> compositeValue = cursorS1.next();
final I value1 = compositeValue.get(0).copy();
conv.convert(value1, valueAsDoubleType);
// Obtain the cursor position encoded as corner vector
final int cornerInteger1 = cursorS1.getCornerRepresentation();
// Determine if the value has to be added (factor==1) or subtracted
// (factor==-1)
final DoubleType factor = new DoubleType(Math.pow(-1.0d, dimensions - IntegralMean.norm(cornerInteger1)));
valueAsDoubleType.mul(factor);
sum1.add(valueAsDoubleType);
final I value2 = compositeValue.get(1).copy();
conv.convert(value2, valueAsDoubleType);
// Determine if the value has to be added (factor==1) or subtracted
// (factor==-1)
valueAsDoubleType.mul(factor);
sum2.add(valueAsDoubleType);
}
final int area = (int) Intervals.numElements(Intervals.expand(input, -1l));
// NB: Reuse available DoubleType
valueAsDoubleType.set(area);
sum1.mul(sum1);
// NB
sum1.div(valueAsDoubleType);
sum2.sub(sum1);
// NB
valueAsDoubleType.sub(new DoubleType(1));
// NB
sum2.div(valueAsDoubleType);
output.set(sum2);
}
use of net.imglib2.Cursor in project imagej-ops by imagej.
the class RidgeDetectionUtils method getMaxCoords.
protected static long[] getMaxCoords(RandomAccessibleInterval<DoubleType> input, boolean useAbsoluteValue) {
long[] dims = new long[input.numDimensions()];
double max = Double.MIN_VALUE;
Cursor<DoubleType> cursor = Views.iterable(input).localizingCursor();
while (cursor.hasNext()) {
cursor.fwd();
double current = useAbsoluteValue ? Math.abs(cursor.get().get()) : cursor.get().get();
if (current > max) {
max = current;
for (int d = 0; d < input.numDimensions(); d++) {
dims[d] = cursor.getLongPosition(d);
}
}
}
return dims;
}
Aggregations