Search in sources :

Example 1 with CursorBasedChunk

use of net.imagej.ops.thread.chunker.CursorBasedChunk in project imagej-ops by imagej.

the class HistogramOfOrientedGradients2D method compute.

@SuppressWarnings("unchecked")
@Override
public void compute(RandomAccessibleInterval<T> in, RandomAccessibleInterval<T> out) {
    final RandomAccessible<FloatType> convertedIn = Converters.convert(Views.extendMirrorDouble(in), converterToFloat, new FloatType());
    // compute partial derivative for each dimension
    RandomAccessibleInterval<FloatType> derivative0 = createImgOp.calculate();
    RandomAccessibleInterval<FloatType> derivative1 = createImgOp.calculate();
    // case of grayscale image
    if (in.numDimensions() == 2) {
        PartialDerivative.gradientCentralDifference(convertedIn, derivative0, 0);
        PartialDerivative.gradientCentralDifference(convertedIn, derivative1, 1);
    } else // case of color image
    {
        List<RandomAccessibleInterval<FloatType>> listDerivs0 = new ArrayList<>();
        List<RandomAccessibleInterval<FloatType>> listDerivs1 = new ArrayList<>();
        for (int i = 0; i < in.dimension(2); i++) {
            final RandomAccessibleInterval<FloatType> deriv0 = createImgOp.calculate();
            final RandomAccessibleInterval<FloatType> deriv1 = createImgOp.calculate();
            PartialDerivative.gradientCentralDifference(Views.interval(convertedIn, new long[] { 0, 0, i }, new long[] { in.max(0), in.max(1), i }), deriv0, 0);
            PartialDerivative.gradientCentralDifference(Views.interval(convertedIn, new long[] { 0, 0, i }, new long[] { in.max(0), in.max(1), i }), deriv1, 1);
            listDerivs0.add(deriv0);
            listDerivs1.add(deriv1);
        }
        derivative0 = Converters.convert(Views.collapse(Views.stack(listDerivs0)), converterGetMax, new FloatType());
        derivative1 = Converters.convert(Views.collapse(Views.stack(listDerivs1)), converterGetMax, new FloatType());
    }
    final RandomAccessibleInterval<FloatType> finalderivative0 = derivative0;
    final RandomAccessibleInterval<FloatType> finalderivative1 = derivative1;
    // compute angles and magnitudes
    final RandomAccessibleInterval<FloatType> angles = createImgOp.calculate();
    final RandomAccessibleInterval<FloatType> magnitudes = createImgOp.calculate();
    final CursorBasedChunk chunkable = new CursorBasedChunk() {

        @Override
        public void execute(int startIndex, int stepSize, int numSteps) {
            final Cursor<FloatType> cursorAngles = Views.flatIterable(angles).localizingCursor();
            final Cursor<FloatType> cursorMagnitudes = Views.flatIterable(magnitudes).localizingCursor();
            final Cursor<FloatType> cursorDerivative0 = Views.flatIterable(finalderivative0).localizingCursor();
            final Cursor<FloatType> cursorDerivative1 = Views.flatIterable(finalderivative1).localizingCursor();
            setToStart(cursorAngles, startIndex);
            setToStart(cursorMagnitudes, startIndex);
            setToStart(cursorDerivative0, startIndex);
            setToStart(cursorDerivative1, startIndex);
            for (int i = 0; i < numSteps; i++) {
                final float x = cursorDerivative0.get().getRealFloat();
                final float y = cursorDerivative1.get().getRealFloat();
                cursorAngles.get().setReal(getAngle(x, y));
                cursorMagnitudes.get().setReal(getMagnitude(x, y));
                cursorAngles.jumpFwd(stepSize);
                cursorMagnitudes.jumpFwd(stepSize);
                cursorDerivative0.jumpFwd(stepSize);
                cursorDerivative1.jumpFwd(stepSize);
            }
        }
    };
    ops().thread().chunker(chunkable, Views.flatIterable(magnitudes).size());
    // stores each Thread to execute
    final List<Callable<Void>> listCallables = new ArrayList<>();
    // compute descriptor (default 3x3, i.e. 9 channels: one channel for
    // each bin)
    final RectangleShape shape = new RectangleShape(spanOfNeighborhood, false);
    final NeighborhoodsAccessible<FloatType> neighborHood = shape.neighborhoodsRandomAccessible(angles);
    for (int i = 0; i < in.dimension(0); i++) {
        listCallables.add(new ComputeDescriptor(Views.interval(convertedIn, in), i, angles.randomAccess(), magnitudes.randomAccess(), (RandomAccess<FloatType>) out.randomAccess(), neighborHood.randomAccess()));
    }
    try {
        es.invokeAll(listCallables);
    } catch (final InterruptedException e) {
        throw new RuntimeException(e);
    }
    listCallables.clear();
}
Also used : CursorBasedChunk(net.imagej.ops.thread.chunker.CursorBasedChunk) ArrayList(java.util.ArrayList) RandomAccess(net.imglib2.RandomAccess) Callable(java.util.concurrent.Callable) FloatType(net.imglib2.type.numeric.real.FloatType) RectangleShape(net.imglib2.algorithm.neighborhood.RectangleShape) RandomAccessibleInterval(net.imglib2.RandomAccessibleInterval)

Aggregations

ArrayList (java.util.ArrayList)1 Callable (java.util.concurrent.Callable)1 CursorBasedChunk (net.imagej.ops.thread.chunker.CursorBasedChunk)1 RandomAccess (net.imglib2.RandomAccess)1 RandomAccessibleInterval (net.imglib2.RandomAccessibleInterval)1 RectangleShape (net.imglib2.algorithm.neighborhood.RectangleShape)1 FloatType (net.imglib2.type.numeric.real.FloatType)1