/*- * #%L * Fiji distribution of ImageJ for the life sciences. * %% * Copyright (C) 2007 - 2017 Fiji developers. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-2.0.html>. * #L% */ package spim.process.fusion.deconvolution; import java.util.concurrent.Callable; import net.imglib2.Cursor; import net.imglib2.RandomAccessibleInterval; import net.imglib2.RealRandomAccess; import net.imglib2.interpolation.randomaccess.NLinearInterpolatorFactory; import net.imglib2.realtransform.AffineTransform3D; import net.imglib2.type.numeric.real.FloatType; import net.imglib2.view.Views; import spim.process.fusion.FusionHelper; import spim.process.fusion.ImagePortion; /** * Fuse one portion of a paralell fusion, supports no weights * * @author Stephan Preibisch (stephan.preibisch@gmx.de) */ public class TransformInput implements Callable< String > { final ImagePortion portion; final RandomAccessibleInterval< FloatType > img; final AffineTransform3D transform; final RandomAccessibleInterval< FloatType > transformedImg; final int offsetX, offsetY, offsetZ, imgSizeX, imgSizeY, imgSizeZ; public TransformInput( final ImagePortion portion, final RandomAccessibleInterval< FloatType > img, final AffineTransform3D transform, final RandomAccessibleInterval< FloatType > transformedImg, final long[] offset ) { this.portion = portion; this.img = img; this.transform = transform; this.transformedImg = transformedImg; this.offsetX = (int)offset[ 0 ]; this.offsetY = (int)offset[ 1 ]; this.offsetZ = (int)offset[ 2 ]; this.imgSizeX = (int)img.dimension( 0 ); this.imgSizeY = (int)img.dimension( 1 ); this.imgSizeZ = (int)img.dimension( 2 ); } @Override public String call() throws Exception { final NLinearInterpolatorFactory< FloatType > f = new NLinearInterpolatorFactory< FloatType >(); // make the interpolators and get the transformations final RealRandomAccess< FloatType > ir = Views.interpolate( Views.extendMirrorSingle( img ), f ).realRandomAccess(); final Cursor< FloatType > cursor = Views.iterable( transformedImg ).localizingCursor(); final float[] s = new float[ 3 ]; final float[] t = new float[ 3 ]; cursor.jumpFwd( portion.getStartPosition() ); for ( int j = 0; j < portion.getLoopSize(); ++j ) loop( cursor, ir, transform, s, t, offsetX, offsetY, offsetZ, imgSizeX, imgSizeY, imgSizeZ ); return portion + " finished successfully (transform input & no weights)."; } private static final void loop( final Cursor< FloatType > cursor, final RealRandomAccess< FloatType > ir, final AffineTransform3D transform, final float[] s, final float[] t, final int offsetX, final int offsetY, final int offsetZ, final int imgSizeX, final int imgSizeY, final int imgSizeZ ) { // move img cursor forward any get the value (saves one access) final FloatType v = cursor.next(); cursor.localize( s ); s[ 0 ] += offsetX; s[ 1 ] += offsetY; s[ 2 ] += offsetZ; transform.applyInverse( t, s ); if ( FusionHelper.intersects( t[ 0 ], t[ 1 ], t[ 2 ], imgSizeX, imgSizeY, imgSizeZ ) ) { ir.setPosition( t ); // do not accept 0 values in the data where image data is present, 0 means no image data is available // (used in MVDeconvolution.computeQuotient) v.set( Math.max( MVDeconvolution.minValue, ir.get().get() ) ); } } }