/** * Computes a Gaussian convolution with double precision on an entire {@link Img} * * @param sigma - the sigma for the convolution * @param img - the img {@link Img} * @param outofbounds - the {@link OutOfBoundsFactory} * @return the convolved img having the input type */ @SuppressWarnings({"unchecked", "rawtypes"}) public static <T extends RealType<T>> Img<T> inDouble( final double[] sigma, final Img<T> img, final OutOfBoundsFactory<DoubleType, RandomAccessibleInterval<DoubleType>> outofbounds) { try { if (DoubleType.class.isInstance(img.firstElement())) { return (Img) toDouble(sigma, img, outofbounds); } final Img<T> output = img.factory().create(img, img.firstElement()); final RandomAccessible<DoubleType> rIn = Views.extend( new WriteConvertedRandomAccessibleInterval<T, DoubleType>( img, new RealDoubleSamplerConverter<T>()), outofbounds); final RandomAccessible<DoubleType> rOut = new WriteConvertedRandomAccessible<T, DoubleType>( output, new RealDoubleSamplerConverter<T>()); inDouble( sigma, rIn, img, rOut, new Point(sigma.length), img.factory().imgFactory(new DoubleType())); return output; } catch (final IncompatibleTypeException e) { return null; } }
/** * Computes a Gaussian convolution with double precision on an entire {@link Img} * * @param sigma - the sigma for the convolution * @param img - the img {@link Img} * @param outofbounds - the {@link OutOfBoundsFactory} * @return the convolved img in {@link DoubleType} */ public static <T extends RealType<T>> Img<DoubleType> toDouble( final double[] sigma, final Img<T> img, final OutOfBoundsFactory<DoubleType, RandomAccessibleInterval<DoubleType>> outofbounds) { GaussDouble gauss = null; try { if (DoubleType.class.isInstance(img.firstElement())) { @SuppressWarnings({"rawtypes", "unchecked"}) final Img<DoubleType> img2 = (Img) img; gauss = new GaussDouble(sigma, img2); } else { final RandomAccessibleInterval<DoubleType> rIn = new WriteConvertedIterableRandomAccessibleInterval<T, DoubleType, Img<T>>( img, new RealDoubleSamplerConverter<T>()); gauss = new GaussDouble( sigma, Views.extend(rIn, outofbounds), img, img.factory().imgFactory(new DoubleType())); } } catch (final IncompatibleTypeException e) { return null; } gauss.call(); return (Img<DoubleType>) gauss.getResult(); }
/** * Computes a Gaussian convolution with the precision of the type provided on an entire {@link * Img} * * @param sigma - the sigma for the convolution * @param img - the img {@link Img} * @param outofbounds - the {@link OutOfBoundsFactory} * @return the convolved img */ public static <T extends NumericType<T>> Img<T> inNumericType( final double[] sigma, final Img<T> img, final OutOfBoundsFactory<T, RandomAccessibleInterval<T>> outofbounds) { final Img<T> output = img.factory().create(img, img.firstElement()); inNumericType( sigma, Views.extend(img, outofbounds), img, output, new Point(sigma.length), img.factory()); return output; }
/** @see LocalContrastThreshold */ @Test public void testLocalContrastThreshold() { ops.run( LocalContrastThreshold.class, out, in, new RectangleShape(3, false), new OutOfBoundsMirrorFactory<ByteType, Img<ByteType>>(Boundary.SINGLE)); assertEquals(out.firstElement().get(), false); }
/** With a default {@link OutOfBoundsStrategyValueFactory} with @param outside. */ @SuppressWarnings("unchecked") public AbstractAffine3D( final Img<T> img, final float[] matrix, final Mode mode, final Number outside) throws Exception { this( img, matrix, mode, new OutOfBoundsConstantValueFactory<T, Img<T>>( (T) withValue( img, img.firstElement().createVariable(), outside))); // default value is zero }
/** @see LocalBernsenThreshold */ @Test public void testLocalBernsenThreshold() { ops.run( LocalBernsenThreshold.class, out, in, new RectangleShape(3, false), new OutOfBoundsMirrorFactory<ByteType, Img<ByteType>>(Boundary.SINGLE), 1.0, Double.MAX_VALUE * 0.5); assertEquals(out.firstElement().get(), true); }
/** Makes sure input is okay and creates output image */ @Override public boolean checkInput() { final Img inputImage = dataset.getImgPlus(); // TODO - raw type required // here inputDimensions = new long[inputImage.numDimensions()]; inputImage.dimensions(inputDimensions); final long[] outputDimensions = flipper.calcOutputDimensions(inputDimensions); outputImage = inputImage.factory().create(outputDimensions, inputImage.firstElement()); return true; }
public Example1c() { // create the ImgFactory based on cells (cellsize = 5x5x5...x5) that will // instantiate the Img final ImgFactory<FloatType> imgFactory = new CellImgFactory<FloatType>(5); // create an 3d-Img with dimensions 20x30x40 (here cellsize is 5x5x5)Ø final Img<FloatType> img1 = imgFactory.create(new long[] {20, 30, 40}, new FloatType()); // create another image with the same size // note that the input provides the size for the new image as it implements // the Interval interface final Img<FloatType> img2 = imgFactory.create(img1, img1.firstElement()); // display both (but they are empty) ImageJFunctions.show(img1); ImageJFunctions.show(img2); }
/** With a default {@link OutOfBoundsStrategyValueFactory} with @param outside. */ @SuppressWarnings("unchecked") public AbstractAffine3D( final Img<T> img, final float scaleX, final float shearX, final float shearY, final float scaleY, final float translateX, final float translateY, final Mode mode, final Number outside) throws Exception { this( img, new float[] {scaleX, shearX, 0, translateX, shearY, scaleY, 0, translateY, 0, 0, 1, 0}, mode, new OutOfBoundsConstantValueFactory<T, Img<T>>( (T) withValue(img, img.firstElement().createVariable(), outside))); }
@SuppressWarnings({"unchecked", "rawtypes"}) private static final <N extends NumericType<N>> Img<N> process( final Img<N> img, final float[] matrix, final Mode mode, final OutOfBoundsFactory<N, Img<N>> oobf) throws Exception { if (matrix.length < 12) { throw new IllegalArgumentException( "Affine transform in 2D requires a matrix array of 12 elements."); } final Type<?> type = img.firstElement().createVariable(); if (ARGBType.class.isAssignableFrom( type.getClass())) { // type instanceof RGBALegacyType fails to compile return (Img) processRGBA((Img) img, matrix, mode, (OutOfBoundsFactory) oobf); } else if (type instanceof RealType<?>) { return processReal((Img) img, matrix, mode, (OutOfBoundsFactory) oobf); } else { throw new Exception("Affine transform: cannot handle type " + type.getClass()); } }
/** * Computes a Gaussian convolution in-place (temporary imgs are necessary) with float precision on * an entire {@link Img} * * @param sigma - the sigma for the convolution * @param img - the img {@link Img} that will be convolved in place */ public static <T extends RealType<T>> void inFloatInPlace( final double[] sigma, final Img<T> img, final OutOfBoundsFactory<FloatType, RandomAccessibleInterval<FloatType>> outofbounds) { GaussFloat gauss = null; try { if (FloatType.class.isInstance(img.firstElement())) { @SuppressWarnings({"rawtypes", "unchecked"}) final Img<FloatType> img2 = (Img) img; gauss = new GaussFloat( sigma, Views.extend(img2, outofbounds), img2, img2, new Point(sigma.length), img2.factory().imgFactory(new FloatType())); } else { final RandomAccessibleInterval<FloatType> rIn = new WriteConvertedIterableRandomAccessibleInterval<T, FloatType, Img<T>>( img, new RealFloatSamplerConverter<T>()); gauss = new GaussFloat( sigma, Views.extend(rIn, outofbounds), img, rIn, new Point(sigma.length), img.factory().imgFactory(new FloatType())); } } catch (final IncompatibleTypeException e) { System.out.println(e); return; } gauss.call(); }
@Override public boolean process() { final int numDimensions = img.numDimensions(); final long integralSize[] = new long[numDimensions]; // the size of the first dimension is changed for (int d = 0; d < numDimensions; ++d) integralSize[d] = img.dimension(d) + 1; final Img<T> integral = imgFactory.create(integralSize, type); // not enough RAM or disc space if (integral == null) return false; this.integral = integral; if (numDimensions > 1) { final long[] fakeSize = new long[numDimensions - 1]; // the size of dimension 0 final long size = integralSize[0]; for (int d = 1; d < numDimensions; ++d) fakeSize[d - 1] = integralSize[d]; final long imageSize = getNumPixels(fakeSize); final AtomicInteger ai = new AtomicInteger(0); final Thread[] threads = SimpleMultiThreading.newThreads(); final Vector<Chunk> threadChunks = SimpleMultiThreading.divideIntoChunks(imageSize, threads.length); for (int ithread = 0; ithread < threads.length; ++ithread) threads[ithread] = new Thread( new Runnable() { @Override public void run() { // Thread ID final int myNumber = ai.getAndIncrement(); // get chunk of pixels to process final Chunk myChunk = threadChunks.get(myNumber); final long loopSize = myChunk.getLoopSize(); final LocalizingZeroMinIntervalIterator cursorDim = new LocalizingZeroMinIntervalIterator(fakeSize); // location for the input location final long[] tmpIn = new long[numDimensions]; // location for the integral location final long[] tmpOut = new long[numDimensions]; final long[] tmp = new long[numDimensions - 1]; final RandomAccess<R> cursorIn = img.randomAccess(); final RandomAccess<T> cursorOut = integral.randomAccess(); final T tmpVar = integral.firstElement().createVariable(); final T sum = integral.firstElement().createVariable(); cursorDim.jumpFwd(myChunk.getStartPosition()); // iterate over all dimensions except the one we are computing the integral in, // which is dim=0 here main: for (long j = 0; j < loopSize; ++j) { cursorDim.fwd(); // get all dimensions except the one we are currently doing the integral on cursorDim.localize(tmp); tmpIn[0] = 0; tmpOut[0] = 1; for (int d = 1; d < numDimensions; ++d) { tmpIn[d] = tmp[d - 1] - 1; tmpOut[d] = tmp[d - 1]; // all entries of position 0 are 0 if (tmpOut[d] == 0) continue main; } // set the cursor to the beginning of the correct line cursorIn.setPosition(tmpIn); // set the cursor in the integral image to the right position cursorOut.setPosition(tmpOut); // integrate over the line integrateLineDim0(converter, cursorIn, cursorOut, sum, tmpVar, size); } } }); SimpleMultiThreading.startAndJoin(threads); } else { final T tmpVar = integral.firstElement().createVariable(); final T sum = integral.firstElement().createVariable(); // the size of dimension 0 final long size = integralSize[0]; final RandomAccess<R> cursorIn = img.randomAccess(); final RandomAccess<T> cursorOut = integral.randomAccess(); cursorIn.setPosition(0, 0); cursorOut.setPosition(1, 0); // compute the first pixel converter.convert(cursorIn.get(), sum); cursorOut.get().set(sum); for (long i = 2; i < size; ++i) { cursorIn.fwd(0); cursorOut.fwd(0); converter.convert(cursorIn.get(), tmpVar); sum.add(tmpVar); cursorOut.get().set(sum); } return true; } for (int d = 1; d < numDimensions; ++d) { final int dim = d; final long[] fakeSize = new long[numDimensions - 1]; // the size of dimension d final long size = integralSize[d]; // get all dimensions except the one we are currently doing the integral on int countDim = 0; for (int e = 0; e < numDimensions; ++e) if (e != d) fakeSize[countDim++] = integralSize[e]; final long imageSize = getNumPixels(fakeSize); final AtomicInteger ai = new AtomicInteger(0); final Thread[] threads = SimpleMultiThreading.newThreads(); final Vector<Chunk> threadChunks = SimpleMultiThreading.divideIntoChunks(imageSize, threads.length); for (int ithread = 0; ithread < threads.length; ++ithread) threads[ithread] = new Thread( new Runnable() { @Override public void run() { // Thread ID final int myNumber = ai.getAndIncrement(); // get chunk of pixels to process final Chunk myChunk = threadChunks.get(myNumber); final long loopSize = myChunk.getLoopSize(); final LocalizingZeroMinIntervalIterator cursorDim = new LocalizingZeroMinIntervalIterator(fakeSize); // local instances final long[] tmp2 = new long[numDimensions - 1]; final long[] tmp = new long[numDimensions]; final RandomAccess<T> cursor = integral.randomAccess(); final T sum = integral.firstElement().createVariable(); cursorDim.jumpFwd(myChunk.getStartPosition()); for (long j = 0; j < loopSize; ++j) { cursorDim.fwd(); // get all dimensions except the one we are currently doing the integral on cursorDim.localize(tmp2); tmp[dim] = 1; int countDim = 0; for (int e = 0; e < numDimensions; ++e) if (e != dim) tmp[e] = tmp2[countDim++]; // update the cursor in the input image to the current dimension position cursor.setPosition(tmp); // sum up line integrateLine(dim, cursor, sum, size); } } }); SimpleMultiThreading.startAndJoin(threads); } return true; }