Search in sources :

Example 6 with ImgLabeling

use of net.imglib2.roi.labeling.ImgLabeling in project imagej-ops by imagej.

the class CreateLabelingTest method testImageDimensions.

@Test
public void testImageDimensions() {
    final Random randomGenerator = new Random();
    for (int i = 0; i < TEST_SIZE; i++) {
        // between 2 and 5 dimensions
        final long[] dim = new long[randomGenerator.nextInt(4) + 2];
        // between 2 and 10 pixels per dimensions
        for (int j = 0; j < dim.length; j++) {
            dim[j] = randomGenerator.nextInt(9) + 2;
        }
        // create imglabeling
        @SuppressWarnings("unchecked") final ImgLabeling<String, ?> img = (ImgLabeling<String, ?>) ops.run(DefaultCreateImgLabeling.class, dim);
        assertArrayEquals("Labeling Dimensions:", dim, Intervals.dimensionsAsLongArray(img));
    }
}
Also used : Random(java.util.Random) DefaultCreateImgLabeling(net.imagej.ops.create.imgLabeling.DefaultCreateImgLabeling) ImgLabeling(net.imglib2.roi.labeling.ImgLabeling) DefaultCreateImgLabeling(net.imagej.ops.create.imgLabeling.DefaultCreateImgLabeling) AbstractOpTest(net.imagej.ops.AbstractOpTest) Test(org.junit.Test)

Example 7 with ImgLabeling

use of net.imglib2.roi.labeling.ImgLabeling in project imagej-ops by imagej.

the class WatershedBinarySingleSigmaTest method test.

@SuppressWarnings("unchecked")
@Test
public void test() {
    // load test image
    Img<FloatType> watershedTestImg = openFloatImg(WatershedTest.class, "watershed_test_image.png");
    // threshold it
    RandomAccessibleInterval<BitType> thresholdedImg = ops.create().img(watershedTestImg, new BitType());
    ops.threshold().apply(Views.flatIterable(thresholdedImg), Views.flatIterable(watershedTestImg), new FloatType(1));
    // compute inverted distance transform and smooth it with gaussian
    // filtering
    final RandomAccessibleInterval<FloatType> distMap = ops.image().distancetransform(thresholdedImg);
    final RandomAccessibleInterval<FloatType> invertedDistMap = ops.create().img(distMap, new FloatType());
    ops.image().invert(Views.iterable(invertedDistMap), Views.iterable(distMap));
    double sigma = 3.0;
    final RandomAccessibleInterval<FloatType> gauss = ops.filter().gauss(invertedDistMap, sigma);
    // run randomly only one configuration to save execution time
    int nextInt = new Random().nextInt(3);
    if (nextInt == 0) {
        // compute result
        final ImgLabeling<Integer, IntType> out1 = (ImgLabeling<Integer, IntType>) ops.run(WatershedBinarySingleSigma.class, null, thresholdedImg, true, false, sigma, thresholdedImg);
        final ImgLabeling<Integer, IntType> expOut1 = (ImgLabeling<Integer, IntType>) ops.run(Watershed.class, null, gauss, true, false, thresholdedImg);
        assertResults(expOut1, out1);
        final ImgLabeling<Integer, IntType> out2 = (ImgLabeling<Integer, IntType>) ops.run(WatershedBinarySingleSigma.class, null, thresholdedImg, true, false, sigma);
        final ImgLabeling<Integer, IntType> expOut2 = (ImgLabeling<Integer, IntType>) ops.run(Watershed.class, null, gauss, true, false);
        assertResults(expOut2, out2);
    } else if (nextInt == 1) {
        // compute result
        final ImgLabeling<Integer, IntType> out1 = (ImgLabeling<Integer, IntType>) ops.run(WatershedBinarySingleSigma.class, null, thresholdedImg, true, true, sigma, thresholdedImg);
        final ImgLabeling<Integer, IntType> expOut1 = (ImgLabeling<Integer, IntType>) ops.run(Watershed.class, null, gauss, true, true, thresholdedImg);
        assertResults(expOut1, out1);
        final ImgLabeling<Integer, IntType> out2 = (ImgLabeling<Integer, IntType>) ops.run(WatershedBinarySingleSigma.class, null, thresholdedImg, true, true, sigma);
        final ImgLabeling<Integer, IntType> expOut2 = (ImgLabeling<Integer, IntType>) ops.run(Watershed.class, null, gauss, true, true);
        assertResults(expOut2, out2);
    } else {
        // compute result
        final ImgLabeling<Integer, IntType> out1 = (ImgLabeling<Integer, IntType>) ops.run(WatershedBinarySingleSigma.class, null, thresholdedImg, false, true, sigma, thresholdedImg);
        final ImgLabeling<Integer, IntType> expOut1 = (ImgLabeling<Integer, IntType>) ops.run(Watershed.class, null, gauss, false, true, thresholdedImg);
        assertResults(expOut1, out1);
        final ImgLabeling<Integer, IntType> out2 = (ImgLabeling<Integer, IntType>) ops.run(WatershedBinarySingleSigma.class, null, thresholdedImg, false, true, sigma);
        final ImgLabeling<Integer, IntType> expOut2 = (ImgLabeling<Integer, IntType>) ops.run(Watershed.class, null, gauss, false, true);
        assertResults(expOut2, out2);
    }
}
Also used : ImgLabeling(net.imglib2.roi.labeling.ImgLabeling) FloatType(net.imglib2.type.numeric.real.FloatType) IntType(net.imglib2.type.numeric.integer.IntType) Random(java.util.Random) BitType(net.imglib2.type.logic.BitType) AbstractOpTest(net.imagej.ops.AbstractOpTest) Test(org.junit.Test)

Example 8 with ImgLabeling

use of net.imglib2.roi.labeling.ImgLabeling in project imagej-ops by imagej.

the class WatershedSeededTest method testWithoutMask.

@SuppressWarnings("unchecked")
private void testWithoutMask(final RandomAccessibleInterval<FloatType> in, final ImgLabeling<Integer, IntType> seeds) {
    // create mask which is 1 everywhere
    long[] dims = new long[in.numDimensions()];
    in.dimensions(dims);
    Img<BitType> mask = ArrayImgs.bits(dims);
    for (BitType b : mask) {
        b.setOne();
    }
    /*
		 * use 8-connected neighborhood
		 */
    // compute result without watersheds
    ImgLabeling<Integer, IntType> out = (ImgLabeling<Integer, IntType>) ops.run(WatershedSeeded.class, null, in, seeds, true, false);
    assertResults(in, out, seeds, mask, false, false);
    // compute result with watersheds
    ImgLabeling<Integer, IntType> out2 = (ImgLabeling<Integer, IntType>) ops.run(WatershedSeeded.class, null, in, seeds, true, true);
    assertResults(in, out2, seeds, mask, true, false);
    /*
		 * use 4-connected neighborhood
		 */
    // compute result without watersheds
    ImgLabeling<Integer, IntType> out3 = (ImgLabeling<Integer, IntType>) ops.run(WatershedSeeded.class, null, in, seeds, false, false);
    assertResults(in, out3, seeds, mask, false, false);
    // compute result with watersheds
    ImgLabeling<Integer, IntType> out4 = (ImgLabeling<Integer, IntType>) ops.run(WatershedSeeded.class, null, in, seeds, false, true);
    assertResults(in, out4, seeds, mask, true, false);
}
Also used : BitType(net.imglib2.type.logic.BitType) ImgLabeling(net.imglib2.roi.labeling.ImgLabeling) IntType(net.imglib2.type.numeric.integer.IntType)

Example 9 with ImgLabeling

use of net.imglib2.roi.labeling.ImgLabeling in project imagej-ops by imagej.

the class WatershedTest method testWithMask.

@SuppressWarnings("unchecked")
private void testWithMask(final RandomAccessibleInterval<FloatType> in) {
    // create mask which is 1 everywhere
    long[] dims = new long[in.numDimensions()];
    in.dimensions(dims);
    Img<BitType> mask = ArrayImgs.bits(dims);
    RandomAccess<BitType> raMask = mask.randomAccess();
    for (BitType b : mask) {
        b.setZero();
    }
    for (int x = 0; x < dims[0] / 2; x++) {
        for (int y = 0; y < dims[1] / 2; y++) {
            raMask.setPosition(new int[] { x, y });
            raMask.get().setOne();
        }
    }
    /*
		 * use 8-connected neighborhood
		 */
    // compute result without watersheds
    ImgLabeling<Integer, IntType> out = (ImgLabeling<Integer, IntType>) ops.run(Watershed.class, null, in, true, false, mask);
    assertResults(in, out, mask, true, false, true);
    // compute result with watersheds
    ImgLabeling<Integer, IntType> out2 = (ImgLabeling<Integer, IntType>) ops.run(Watershed.class, null, in, true, true, mask);
    assertResults(in, out2, mask, true, true, true);
    /*
		 * use 4-connected neighborhood
		 */
    // compute result without watersheds
    ImgLabeling<Integer, IntType> out3 = (ImgLabeling<Integer, IntType>) ops.run(Watershed.class, null, in, false, false, mask);
    assertResults(in, out3, mask, false, false, true);
    // compute result with watersheds
    ImgLabeling<Integer, IntType> out4 = (ImgLabeling<Integer, IntType>) ops.run(Watershed.class, null, in, false, true, mask);
    assertResults(in, out4, mask, false, true, true);
}
Also used : BitType(net.imglib2.type.logic.BitType) ImgLabeling(net.imglib2.roi.labeling.ImgLabeling) IntType(net.imglib2.type.numeric.integer.IntType)

Example 10 with ImgLabeling

use of net.imglib2.roi.labeling.ImgLabeling in project imagej-ops by imagej.

the class Watershed method compute.

@Override
public void compute(final RandomAccessibleInterval<T> in, final ImgLabeling<Integer, IntType> out) {
    final RandomAccess<T> raIn = in.randomAccess();
    RandomAccess<B> raMask = null;
    if (mask != null) {
        raMask = mask.randomAccess();
    }
    // stores the size of each dimension
    final long[] dimensSizes = new long[in.numDimensions()];
    in.dimensions(dimensSizes);
    // calculates the number of points in the n-d space
    long numPixels = Intervals.numElements(in);
    // the pixels indices are stored in an array, which is sorted depending
    // on the pixel values
    final List<Long> imiList = new ArrayList<>();
    if (mask != null) {
        final Cursor<Void> c = Regions.iterable(mask).localizingCursor();
        while (c.hasNext()) {
            c.next();
            imiList.add(IntervalIndexer.positionToIndex(c, in));
        }
    } else {
        for (long i = 0; i < numPixels; i++) {
            imiList.add(i);
        }
    }
    final Long[] imi = imiList.toArray(new Long[imiList.size()]);
    /*
		 * Sort the pixels of imi in the increasing order of their grey value
		 * (only the pixel indices are stored)
		 */
    Arrays.sort(imi, new Comparator<Long>() {

        @Override
        public int compare(final Long o1, final Long o2) {
            IntervalIndexer.indexToPosition(o1, in, raIn);
            final T value = raIn.get().copy();
            IntervalIndexer.indexToPosition(o2, in, raIn);
            return value.compareTo(raIn.get());
        }
    });
    // lab and dist store the values calculated after each phase
    final RandomAccessibleInterval<IntType> lab = ops().create().img(in, new IntType());
    // extend border to be able to do a quick check, if a voxel is inside
    final ExtendedRandomAccessibleInterval<IntType, RandomAccessibleInterval<IntType>> labExt = Views.extendBorder(lab);
    final OutOfBounds<IntType> raLab = labExt.randomAccess();
    final RandomAccessibleInterval<IntType> dist = ops().create().img(in, new IntType());
    final RandomAccess<IntType> raDist = dist.randomAccess();
    // initial values
    for (final IntType pixel : Views.flatIterable(lab)) {
        pixel.set(INIT);
    }
    int current_label = 0;
    int current_dist;
    final ArrayList<Long> fifo = new ArrayList<>();
    // RandomAccess for Neighborhoods
    final Shape shape;
    if (useEightConnectivity) {
        shape = new RectangleShape(1, true);
    } else {
        shape = new DiamondShape(1);
    }
    final RandomAccessible<Neighborhood<T>> neighborhoods = shape.neighborhoodsRandomAccessible(in);
    final RandomAccess<Neighborhood<T>> raNeighbor = neighborhoods.randomAccess();
    /*
		 * Start flooding
		 */
    for (int j = 0; j < imi.length; j++) {
        IntervalIndexer.indexToPosition(imi[j], in, raIn);
        final T actualH = raIn.get().copy();
        int i = j;
        while (actualH.compareTo(raIn.get()) == 0) {
            final long p = imi[i];
            IntervalIndexer.indexToPosition(p, in, raIn);
            raLab.setPosition(raIn);
            raLab.get().set(MASK);
            raNeighbor.setPosition(raIn);
            final Cursor<T> neighborHood = raNeighbor.get().cursor();
            while (neighborHood.hasNext()) {
                neighborHood.fwd();
                raLab.setPosition(neighborHood);
                if (!raLab.isOutOfBounds()) {
                    final int f = raLab.get().get();
                    if ((f > 0) || (f == WSHED)) {
                        raDist.setPosition(raIn);
                        raDist.get().set(1);
                        fifo.add(p);
                        break;
                    }
                }
            }
            i++;
            if (i == imi.length) {
                break;
            }
            IntervalIndexer.indexToPosition(imi[i], in, raIn);
        }
        current_dist = 1;
        // add fictitious pixel
        fifo.add(-1l);
        while (true) {
            long p = fifo.remove(0);
            if (p == -1) {
                if (fifo.isEmpty()) {
                    break;
                }
                fifo.add(-1l);
                current_dist++;
                p = fifo.remove(0);
            }
            IntervalIndexer.indexToPosition(p, in, raNeighbor);
            final Cursor<T> neighborHood = raNeighbor.get().cursor();
            raLab.setPosition(raNeighbor);
            int labp = raLab.get().get();
            final long[] posNeighbor = new long[neighborHood.numDimensions()];
            while (neighborHood.hasNext()) {
                neighborHood.fwd();
                neighborHood.localize(posNeighbor);
                raLab.setPosition(posNeighbor);
                if (!raLab.isOutOfBounds()) {
                    raDist.setPosition(posNeighbor);
                    final int labq = raLab.get().get();
                    final int distq = raDist.get().get();
                    if ((distq < current_dist) && ((labq > 0) || (labq == WSHED))) {
                        // the watersheds
                        if (labq > 0) {
                            if ((labp == MASK) || (labp == WSHED)) {
                                labp = labq;
                            } else {
                                if (labp != labq) {
                                    labp = WSHED;
                                }
                            }
                        } else {
                            if (labp == MASK) {
                                labp = WSHED;
                            }
                        }
                        raLab.setPosition(raNeighbor);
                        raLab.get().set(labp);
                    } else {
                        if ((labq == MASK) && (distq == 0)) {
                            raDist.setPosition(posNeighbor);
                            raDist.get().set(current_dist + 1);
                            fifo.add(IntervalIndexer.positionToIndex(posNeighbor, dimensSizes));
                        }
                    }
                }
            }
        }
        // checks if new minima have been discovered
        IntervalIndexer.indexToPosition(imi[j], in, raIn);
        i = j;
        while (actualH.compareTo(raIn.get()) == 0) {
            final long p = imi[i];
            IntervalIndexer.indexToPosition(p, dist, raDist);
            // the distance associated with p is reseted to 0
            raDist.get().set(0);
            raLab.setPosition(raDist);
            if (raLab.get().get() == MASK) {
                current_label++;
                fifo.add(p);
                raLab.get().set(current_label);
                while (!fifo.isEmpty()) {
                    final long q = fifo.remove(0);
                    IntervalIndexer.indexToPosition(q, in, raNeighbor);
                    final Cursor<T> neighborHood = raNeighbor.get().cursor();
                    final long[] posNeighbor = new long[neighborHood.numDimensions()];
                    while (neighborHood.hasNext()) {
                        neighborHood.fwd();
                        neighborHood.localize(posNeighbor);
                        raLab.setPosition(posNeighbor);
                        if (!raLab.isOutOfBounds()) {
                            final long r = IntervalIndexer.positionToIndex(posNeighbor, dimensSizes);
                            if (raLab.get().get() == MASK) {
                                fifo.add(r);
                                raLab.get().set(current_label);
                            }
                        }
                    }
                }
            }
            i++;
            if (i == imi.length) {
                break;
            }
            IntervalIndexer.indexToPosition(imi[i], in, raIn);
        }
        j = i - 1;
    }
    /*
		 * Draw output and remove as the case may be the watersheds
		 */
    final Cursor<LabelingType<Integer>> cursorOut = out.cursor();
    while (cursorOut.hasNext()) {
        cursorOut.fwd();
        boolean maskValue = true;
        if (mask != null) {
            raMask.setPosition(cursorOut);
            if (!raMask.get().get()) {
                maskValue = false;
            }
        }
        raLab.setPosition(cursorOut);
        if (!maskValue) {
            cursorOut.get().clear();
        } else {
            if (!drawWatersheds && raLab.get().get() == WSHED) {
                raNeighbor.setPosition(cursorOut);
                final Cursor<T> neighborHood = raNeighbor.get().cursor();
                int newLab = WSHED;
                while (neighborHood.hasNext()) {
                    neighborHood.fwd();
                    raLab.setPosition(neighborHood);
                    if (!raLab.isOutOfBounds()) {
                        newLab = raLab.get().get();
                        if (newLab > WSHED) {
                            break;
                        }
                    }
                }
                if (newLab == WSHED) {
                    cursorOut.get().clear();
                } else {
                    cursorOut.get().add(newLab);
                }
            } else {
                cursorOut.get().add(raLab.get().get());
            }
        }
    }
    /*
		 * Merge already present labels before calculation of watershed
		 */
    if (out() != null) {
        final Cursor<LabelingType<Integer>> cursor = out().cursor();
        final RandomAccess<LabelingType<Integer>> raOut = out.randomAccess();
        while (cursor.hasNext()) {
            cursor.fwd();
            raOut.setPosition(cursor);
            final List<Integer> labels = new ArrayList<>();
            cursor.get().iterator().forEachRemaining(labels::add);
            raOut.get().addAll(labels);
        }
    }
}
Also used : DiamondShape(net.imglib2.algorithm.neighborhood.DiamondShape) Shape(net.imglib2.algorithm.neighborhood.Shape) RectangleShape(net.imglib2.algorithm.neighborhood.RectangleShape) ArrayList(java.util.ArrayList) IntType(net.imglib2.type.numeric.integer.IntType) LabelingType(net.imglib2.roi.labeling.LabelingType) DiamondShape(net.imglib2.algorithm.neighborhood.DiamondShape) Neighborhood(net.imglib2.algorithm.neighborhood.Neighborhood) RectangleShape(net.imglib2.algorithm.neighborhood.RectangleShape) RandomAccessibleInterval(net.imglib2.RandomAccessibleInterval) ExtendedRandomAccessibleInterval(net.imglib2.view.ExtendedRandomAccessibleInterval)

Aggregations

IntType (net.imglib2.type.numeric.integer.IntType)11 ImgLabeling (net.imglib2.roi.labeling.ImgLabeling)8 BitType (net.imglib2.type.logic.BitType)8 AbstractOpTest (net.imagej.ops.AbstractOpTest)5 FloatType (net.imglib2.type.numeric.real.FloatType)5 Test (org.junit.Test)5 Random (java.util.Random)4 LabelingType (net.imglib2.roi.labeling.LabelingType)3 ArrayList (java.util.ArrayList)2 RandomAccessibleInterval (net.imglib2.RandomAccessibleInterval)2 DiamondShape (net.imglib2.algorithm.neighborhood.DiamondShape)2 Neighborhood (net.imglib2.algorithm.neighborhood.Neighborhood)2 RectangleShape (net.imglib2.algorithm.neighborhood.RectangleShape)2 Shape (net.imglib2.algorithm.neighborhood.Shape)2 ExtendedRandomAccessibleInterval (net.imglib2.view.ExtendedRandomAccessibleInterval)2 Collections (java.util.Collections)1 Comparator (java.util.Comparator)1 List (java.util.List)1 Map (java.util.Map)1 PriorityQueue (java.util.PriorityQueue)1