/** * 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 in-place (temporary imgs are necessary) 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} that will be convolved in place */ public static <T extends NumericType<T>> void inNumericTypeInPlace( final double[] sigma, final Img<T> img, final OutOfBoundsFactory<T, RandomAccessibleInterval<T>> outofbounds) { inNumericType( sigma, Views.extend(img, outofbounds), img, img, new Point(sigma.length), img.factory()); }
/** * 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; }
/** * 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(); }
private static final <R extends RealType<R>> Img<R> processReal( final Img<R> img, final float[] m, final Mode mode, final OutOfBoundsFactory<R, Img<R>> oobf) throws Exception { final InterpolatorFactory<R, RandomAccessible<R>> inter; switch (mode) { case LINEAR: inter = new NLinearInterpolatorFactory<R>(); break; case NEAREST_NEIGHBOR: inter = new NearestNeighborInterpolatorFactory<R>(); break; default: throw new IllegalArgumentException("Scale: don't know how to scale with mode " + mode); } final ImageTransform<R> transform; final ExtendedRandomAccessibleInterval<R, Img<R>> imgExt = Views.extend(img, oobf); if (2 == img.numDimensions()) { // Transform the single-plane image in 2D AffineModel2D aff = new AffineModel2D(); aff.set(m[0], m[4], m[1], m[5], m[3], m[7]); transform = new ImageTransform<R>(imgExt, aff, (InterpolatorFactory) inter); } else if (3 == img.numDimensions()) { // Transform the image in 3D, or each plane in 2D if (m.length < 12) { throw new IllegalArgumentException( "Affine transform in 3D requires a matrix array of 12 elements."); } AffineModel3D aff = new AffineModel3D(); aff.set(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11]); transform = new ImageTransform<R>(imgExt, aff, (InterpolatorFactory) inter); // Ensure Z dimension is not altered if scaleZ is 1: if (Math.abs(m[10] - 1.0f) < 0.000001 && 0 == m[8] && 0 == m[9]) { long[] d = transform.getNewImageSize(); d[2] = img.dimension(2); // 0-based: '2' is the third dimension transform.setNewImageSize(d); } } else { throw new Exception("Affine transform: only 2D and 3D images are supported."); } if (!transform.checkInput() || !transform.process()) { throw new Exception("Could not affine transform the image: " + transform.getErrorMessage()); } return transform.getResult(); }
@Override public RandomAccessibleInterval<T> compute( final RandomAccessibleInterval<T> input, final RandomAccessibleInterval<T> output) { final StructuringElementCursor<T> inStructure = new StructuringElementCursor<T>(Views.extend(input, m_factory).randomAccess(), m_struc); final Cursor<T> out = Views.iterable(output).localizingCursor(); double m; while (out.hasNext()) { out.next(); inStructure.relocate(out); inStructure.next(); m = inStructure.get().getRealDouble(); while (inStructure.hasNext()) { inStructure.next(); m = Math.min(m, inStructure.get().getRealDouble()); } out.get().setReal(m); } return output; }