@Override public IntervalView<T> calculate(RandomAccessible<T> input) { return Views.offsetInterval(input, origin, dimension); }
@Override public IntervalView<T> calculate(RandomAccessible<T> input) { return Views.offsetInterval(input, interval); }
@Override public RandomAccessibleInterval<T> calculate(final RandomAccessibleInterval<T> input, final Interval interval) { boolean oneSizedDims = false; if (dropSingleDimensions) { for (int d = 0; d < interval.numDimensions(); d++) { if (interval.dimension(d) == 1) { oneSizedDims = true; break; } } } if (Intervals.equals(input, interval) && !oneSizedDims) return input; if (!Intervals.contains(input, interval)) throw new RuntimeException("Intervals don't match!"); IntervalView<T> res = Views.offsetInterval(input, interval); return oneSizedDims ? Views.dropSingletonDimensions(res) : res; } }
/** * Creates a view that spans from (x-1, y-1, ... i-1) to (x+1, y+1, ... i+1) * around the given coordinates * * @param interval the space of the coordinates * @param coordinates coordinates (x, y, ... i) * @return a view of a neighbourhood in the space */ private IntervalView<B> neighbourhoodInterval( final ExtendedRandomAccessibleInterval<B, RandomAccessibleInterval<B>> interval, final long[] coordinates) { final int dimensions = interval.numDimensions(); final BoundingBox box = new BoundingBox(dimensions); final long[] minBounds = Arrays.stream(coordinates).map(c -> c - 1) .toArray(); final long[] maxBounds = Arrays.stream(coordinates).map(c -> c + 1) .toArray(); box.update(minBounds); box.update(maxBounds); return Views.offsetInterval(interval, box); }
/** * View on interval of a source. If wanted, dims with size 1 are removed. * * @param src * The source {@link RandomAccessibleInterval} * @param interval * Interval */ public static final <T extends Type<T>> RandomAccessibleInterval<T> subsetView( final RandomAccessibleInterval<T> src, final Interval interval) { boolean oneSizedDims = false; for (int d = 0; d < interval.numDimensions(); d++) { if (interval.dimension(d) == 1) { oneSizedDims = true; break; } } if (intervalEquals(src, interval) && !oneSizedDims) return src; RandomAccessibleInterval<T> res; if (Intervals.contains(src, interval)) res = Views.offsetInterval(src, interval); else throw new IllegalArgumentException( "Interval must fit into src in SubsetViews.subsetView(...)"); for (int d = interval.numDimensions() - 1; d >= 0; --d) if (interval.dimension(d) == 1 && res.numDimensions() > 1) res = Views.hyperSlice(res, d, 0); return res; }
/** * View on interval of a source. If wanted, dims with size 1 are removed. * * @param src * The source {@link RandomAccessibleInterval} * @param interval * Interval */ public static final <T extends Type<T>> RandomAccessibleInterval<T> subsetView( final RandomAccessibleInterval<T> src, final Interval interval) { boolean oneSizedDims = false; for (int d = 0; d < interval.numDimensions(); d++) { if (interval.dimension(d) == 1) { oneSizedDims = true; break; } } if (intervalEquals(src, interval) && !oneSizedDims) return src; RandomAccessibleInterval<T> res; if (Intervals.contains(src, interval)) res = Views.offsetInterval(src, interval); else throw new IllegalArgumentException( "Interval must fit into src in SubsetViews.subsetView(...)"); for (int d = interval.numDimensions() - 1; d >= 0; --d) if (interval.dimension(d) == 1 && res.numDimensions() > 1) res = Views.hyperSlice(res, d, 0); return res; }
/** * Removes leading 0s from integral image after composite creation. * * @param input Input RAI (can be a RAI of Composite) * @return An extended and cropped version of input */ private <T> RandomAccessibleInterval<T> removeLeadingZeros( final RandomAccessibleInterval<T> input) { // Remove 0s from integralImg by shifting its interval by +1 final long[] min = Intervals.minAsLongArray(input); final long[] max = Intervals.maxAsLongArray(input); for (int d = 0; d < input.numDimensions(); ++d) { int correctedSpan = getShape().getSpan() - 1; min[d] += (1 + correctedSpan); max[d] -= correctedSpan; } // Define the Interval on the infinite random accessibles final FinalInterval interval = new FinalInterval(min, max); final RandomAccessibleInterval<T> extendedImg = Views.offsetInterval(Views .extendBorder(input), interval); return extendedImg; }
/** * Computes integral images of a given order and extends them such that * {@link IntegralMean} et al work with them. * * @param input The RAI for which an integral image is computed * @param order * @return An extended integral image for the input RAI */ @SuppressWarnings({ "unchecked", "rawtypes" }) private RandomAccessibleInterval<RealType> getIntegralImage( final RandomAccessibleInterval<I> input, final int order) { ExtendedRandomAccessibleInterval<I, RandomAccessibleInterval<I>> extendedInput = Views.extend(input, outOfBoundsFactory); FinalInterval expandedInterval = Intervals.expand(input, shape.getSpan()-1); IntervalView<I> offsetInterval2 = Views.offsetInterval(extendedInput, expandedInterval); RandomAccessibleInterval<RealType> img = null; switch (order) { case 1: img = (RandomAccessibleInterval) integralImgOp.calculate(offsetInterval2); break; case 2: img = (RandomAccessibleInterval) squareIntegralImgOp.calculate(offsetInterval2); break; } img = addLeadingZeros(img); return img; }
/** Test the op with a 2x2 square. The square is in the middle of a 4x4 img */ @Test public void testSquare() throws Exception { // SETUP final Img<BitType> img = ArrayImgs.bits(4, 4); final IntervalView<BitType> square = Views.offsetInterval(img, new long[] { 1, 1 }, new long[] { 2, 2 }); square.cursor().forEachRemaining(BitType::setOne); // EXECUTE final Img<BitType> result = (Img<BitType>) ops.morphology().outline(img, Boolean.TRUE); // VERIFY assertEquals("Wrong number of foreground elements in interval", 4, countForeground(result)); final IntervalView<BitType> resultSquare = Views.offsetInterval(result, new long[] { 1, 1 }, new long[] { 2, 2 }); assertTrue("Wrong number of foreground elements in object", allForeground( resultSquare)); }
Views.offsetInterval( Views.raster( RealViews.transform(
/** * Test the op with a 3x3x3x3 hypercube. The cube is in the middle of a * 5x5x5x5 img */ @Test public void testHyperCube() throws Exception { // SETUP final Img<BitType> img = ArrayImgs.bits(5, 5, 5, 5); final IntervalView<BitType> hyperCube = Views.offsetInterval(img, new long[] { 1, 1, 1, 1 }, new long[] { 3, 3, 3, 3 }); hyperCube.cursor().forEachRemaining(BitType::setOne); // EXECUTE final Img<BitType> result = (Img<BitType>) ops.morphology().outline(img, Boolean.TRUE); // VERIFY assertEquals("Wrong number of foreground elements in interval", 80, countForeground(result)); final IntervalView<BitType> resultHyperCube = Views.offsetInterval(result, new long[] { 1, 1, 1, 1 }, new long[] { 3, 3, 3, 3 }); assertEquals("Wrong number of foreground elements in object", 80, countForeground(resultHyperCube)); assertPositionBackground(result, new long[] { 2, 2, 2, 2 }); }
/** * Test the op with a 3x3 square starting from (0,1) in a 5x5 img without * excluding edges * * @see Outline#compute(RandomAccessibleInterval, Boolean, * RandomAccessibleInterval) * @see #testEdgeSquare() */ @Test public void testEdgeSquareExcludeEdgesFalse() throws Exception { // SETUP final Img<BitType> img = ArrayImgs.bits(5, 5); final IntervalView<BitType> square = Views.offsetInterval(img, new long[] { 0, 1 }, new long[] { 3, 3 }); square.cursor().forEachRemaining(BitType::setOne); final Img<BitType> result = (Img<BitType>) ops.morphology().outline(img, Boolean.FALSE); assertEquals("Wrong number of foreground elements in interval", 8, countForeground(result)); final IntervalView<BitType> resultSquare = Views.offsetInterval(result, new long[] { 0, 1 }, new long[] { 3, 3 }); assertEquals("Wrong number of foreground elements in object", 8, countForeground(resultSquare)); assertPositionBackground(result, new long[] { 1, 2 }); }
@Test public void testHyperCube() { // SETUP final double[] expectedSizes = DoubleStream.of(4, 2, 1).map(i -> -Math.log( i)).toArray(); final double[] expectedCounts = DoubleStream.of(1, 16, 16).map(Math::log) .toArray(); final Img<BitType> img = ArrayImgs.bits(4, 4, 4, 4); final IntervalView<BitType> hyperView = Views.offsetInterval(img, new long[] { 1, 1, 1, 1 }, new long[] { 2, 2, 2, 2 }); hyperView.forEach(BitType::setOne); // EXECUTE final List<ValuePair<DoubleType, DoubleType>> points = ops.topology() .boxCount(img, 4L, 1L, 2.0); // VERIFY for (int i = 0; i < expectedSizes.length; i++) { assertEquals(expectedSizes[i], points.get(i).a.get(), 1e-12); assertEquals(expectedCounts[i], points.get(i).b.get(), 1e-12); } }
@Test public void testFullSourceMapMixedAccess() { final long[] offset = new long[] { 1, 10, 0, -5 }; final long[] dim = new long[] { 10, 10, 10, 10 }; final RandomAccess< UnsignedByteType > a = Views.offsetInterval( Views.invertAxis( Views.hyperSlice( img, 2, 2 ), 3 ), offset, dim ).randomAccess(); assertTrue( FullSourceMapMixedRandomAccess.class.isInstance( a ) ); final long[] pos = new long[] { 28, 30, 2, 15 }; final long[] dist = new long[] { 2, 3, 4, 1 }; testlocalize( a, pos ); testfwd( a, pos ); testbck( a, pos ); testmove( a, pos, 3 ); testmove( a, pos, -2 ); testmove( a, pos, dist ); }
/** * Test the op with a 3x3 square starting from (0,1) in a 5x5 img * * @see Outline#compute(RandomAccessibleInterval, Boolean, * RandomAccessibleInterval) * @see #testEdgeSquare() */ @Test public void testEdgeSquare() throws Exception { // SETUP final Img<BitType> img = ArrayImgs.bits(5, 5); final IntervalView<BitType> square = Views.offsetInterval(img, new long[] { 0, 1 }, new long[] { 3, 3 }); square.cursor().forEachRemaining(BitType::setOne); // EXECUTION final Img<BitType> result = (Img<BitType>) ops.morphology().outline(img, Boolean.TRUE); // VERIFY assertEquals("Wrong number of foreground elements in interval", 7, countForeground(result)); final IntervalView<BitType> resultSquare = Views.offsetInterval(result, new long[] { 0, 1 }, new long[] { 3, 3 }); assertEquals("Wrong number of foreground elements in object", 7, countForeground(resultSquare)); assertPositionBackground(result, new long[] { 0, 2 }); assertPositionBackground(result, new long[] { 1, 2 }); }
/** * Test box counting with a hyper cube and one grid translation (should find a * better fit than in @see {@link #testHyperCube()}) */ @Test public void testHyperCubeTranslations() { final double[] expectedSizes = DoubleStream.of(4, 2, 1).map(i -> -Math.log( i)).toArray(); final double[] expectedCounts = DoubleStream.of(1, 1, 16).map(Math::log) .toArray(); final Img<BitType> img = ArrayImgs.bits(4, 4, 4, 4); final IntervalView<BitType> hyperView = Views.offsetInterval(img, new long[] { 1, 1, 1, 1 }, new long[] { 2, 2, 2, 2 }); hyperView.forEach(BitType::setOne); // EXECUTE final List<ValuePair<DoubleType, DoubleType>> points = ops.topology() .boxCount(img, 4L, 1L, 2.0, 1L); // VERIFY for (int i = 0; i < expectedSizes.length; i++) { assertEquals(expectedSizes[i], points.get(i).a.get(), 1e-12); assertEquals(expectedCounts[i], points.get(i).b.get(), 1e-12); } }
/** * Test the op with a 3x3 square with a hole in the middle. The square is in * the middle of a 5x5 img */ @Test public void testOutlineSquare() throws Exception { // SETUP final Img<BitType> img = ArrayImgs.bits(5, 5); final IntervalView<BitType> square = Views.offsetInterval(img, new long[] { 1, 1 }, new long[] { 3, 3 }); square.cursor().forEachRemaining(BitType::setOne); final RandomAccess<BitType> access = square.randomAccess(); access.setPosition(new long[] { 1, 1 }); access.get().setZero(); // EXECUTION final Img<BitType> result = (Img<BitType>) ops.morphology().outline(img, Boolean.TRUE); // VERIFY assertEquals("Wrong number of foreground elements in interval", 8, countForeground(result)); final IntervalView<BitType> resultSquare = Views.offsetInterval(result, new long[] { 1, 1 }, new long[] { 3, 3 }); assertEquals("Wrong number of foreground elements in object", 8, countForeground(resultSquare)); assertPositionBackground(result, new long[] { 2, 2 }); }
/** * @see DefaultIntegralImg * @see SquareIntegralImg */ @SuppressWarnings({ "unchecked" }) @Test public void testIntegralImageSimilarity() { RandomAccessibleInterval<LongType> out1 = (RandomAccessibleInterval<LongType>) ops.run(DefaultIntegralImg.class, in); RandomAccessibleInterval<DoubleType> out2 = (RandomAccessibleInterval<DoubleType>) ops.run(WrappedIntegralImg.class, in); // Remove 0s from integralImg by shifting its interval by +1 final long[] min = new long[out2.numDimensions()]; final long[] max = new long[out2.numDimensions()]; for (int d = 0; d < out2.numDimensions(); ++d) { min[d] = out2.min(d) + 1; max[d] = out2.max(d); } // Define the Interval on the infinite random accessibles final FinalInterval interval = new FinalInterval(min, max); LocalThresholdTest.testIterableIntervalSimilarity(Views.iterable(out1), Views.iterable(Views.offsetInterval(out2, interval))); }
@Test public void defaultOffsetStartEndTest() { Img<DoubleType> img = new ArrayImgFactory<DoubleType>().create(new int[] { 10, 10 }, new DoubleType()); IntervalView<DoubleType> il2 = Views.offsetInterval(img, new long[] { 2, 2 }, new long[] { 9, 9 }); IntervalView<DoubleType> opr = ops.transform().offsetView(img, new long[] { 2, 2 }, new long[] { 9, 9 }); assertEquals(il2.realMax(0), opr.realMax(0), 1e-10); assertEquals(il2.realMin(0), opr.realMin(0), 1e-10); assertEquals(il2.realMax(1), opr.realMax(1), 1e-10); assertEquals(il2.realMin(1), opr.realMin(1), 1e-10); } }
@Test public void defaultOffsetIntervalTest() { Img<DoubleType> img = new ArrayImgFactory<DoubleType>().create(new int[] { 10, 10 }, new DoubleType()); IntervalView<DoubleType> il2 = Views.offsetInterval(img, new FinalInterval(new long[] { 2, 2 }, new long[] { 9, 9 })); IntervalView<DoubleType> opr = ops.transform().offsetView(img, new FinalInterval(new long[] { 2, 2 }, new long[] { 9, 9 })); assertEquals(il2.realMax(0), opr.realMax(0), 1e-10); assertEquals(il2.realMin(0), opr.realMin(0), 1e-10); assertEquals(il2.realMax(1), opr.realMax(1), 1e-10); assertEquals(il2.realMin(1), opr.realMin(1), 1e-10); }