/*- * #%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 mpicbg.util; import spim.vecmath.Transform3D; import spim.vecmath.Matrix4d; import spim.vecmath.Vector3d; import mpicbg.imglib.util.Util; import mpicbg.models.AbstractAffineModel3D; import mpicbg.models.AffineModel3D; import mpicbg.models.CoordinateTransform; import mpicbg.models.RigidModel3D; public class TransformUtils { /** * Return the min and max coordinate of the transformed image in each dimension * relative to the dimensions of the image it is based on. This is important * for computing bounding boxes. * * @param dimensions - the dimensions of the image * @param transform - the transformation * * @return - double[ numDimensions ][ 2 ], in the respective dimension d * double[ d ][ 0 ] is min, double[ d ][ 1 ] is max */ public static double[][] getMinMaxDim( final int[] dimensions, final CoordinateTransform transform ) { final int numDimensions = dimensions.length; final double[] tmp = new double[ numDimensions ]; final double[][] minMaxDim = new double[ numDimensions ][ 2 ]; for ( int d = 0; d < numDimensions; ++d ) { minMaxDim[ d ][ 0 ] = Double.MAX_VALUE; minMaxDim[ d ][ 1 ] = -Double.MAX_VALUE; } // recursively get all corner points of the image, assuming they will still be the extremum points // in the transformed image final boolean[][] positions = new boolean[ Util.pow( 2, numDimensions ) ][ numDimensions ]; Util.setCoordinateRecursive( numDimensions - 1, numDimensions, new int[ numDimensions ], positions ); // get the min and max location for each dimension independently for ( int i = 0; i < positions.length; ++i ) { for ( int d = 0; d < numDimensions; ++d ) { if ( positions[ i ][ d ]) tmp[ d ] = dimensions[ d ]; else tmp[ d ] = 0; } transform.applyInPlace( tmp ); for ( int d = 0; d < numDimensions; ++d ) { if ( tmp[ d ] < minMaxDim[ d ][ 0 ]) minMaxDim[ d ][ 0 ] = tmp[ d ]; if ( tmp[ d ] > minMaxDim[ d ][ 1 ]) minMaxDim[ d ][ 1 ] = tmp[ d ]; } } return minMaxDim; } public static Matrix4d getMatrix4d( final AffineModel3D model ) { final Matrix4d matrix = new Matrix4d(); final double[] m = new double[ 12 ]; model.getMatrix( m ); matrix.m00 = m[ 0 ]; matrix.m01 = m[ 1 ]; matrix.m02 = m[ 2 ]; matrix.m03 = m[ 3 ]; matrix.m10 = m[ 4 ]; matrix.m11 = m[ 5 ]; matrix.m12 = m[ 6 ]; matrix.m13 = m[ 7 ]; matrix.m20 = m[ 8 ]; matrix.m21 = m[ 9 ]; matrix.m22 = m[ 10 ]; matrix.m23 = m[ 11 ]; matrix.m30 = 0; matrix.m31 = 0; matrix.m32 = 0; matrix.m33 = 0; return matrix; } public static Matrix4d getMatrix4d( final RigidModel3D model ) { final Matrix4d matrix = new Matrix4d(); final double[] m = new double[ 12 ]; model.getMatrix( m ); matrix.m00 = m[ 0 ]; matrix.m01 = m[ 1 ]; matrix.m02 = m[ 2 ]; matrix.m03 = m[ 3 ]; matrix.m10 = m[ 4 ]; matrix.m11 = m[ 5 ]; matrix.m12 = m[ 6 ]; matrix.m13 = m[ 7 ]; matrix.m20 = m[ 8 ]; matrix.m21 = m[ 9 ]; matrix.m22 = m[ 10 ]; matrix.m23 = m[ 11 ]; matrix.m30 = 0; matrix.m31 = 0; matrix.m32 = 0; matrix.m33 = 0; return matrix; } public static Transform3D getTransform3D1( final AbstractAffineModel3D<?> model ) { final Transform3D transform = new Transform3D(); final double[] m = model.getMatrix( null ); final double[] m2 = new double[ 16 ]; transform.get( m2 ); for ( int i = 0; i < m.length; ++i ) m2[ i ] = m[ i ]; transform.set( m2 ); return transform; } public static <M extends AbstractAffineModel3D<M>> Transform3D getTransform3D( final M model ) { final Transform3D transform = new Transform3D(); final double[] m = model.getMatrix( null ); final double[] m2 = new double[ 16 ]; transform.get( m2 ); for ( int i = 0; i < m.length; ++i ) m2[ i ] = m[ i ]; transform.set( m2 ); return transform; } public static AffineModel3D getAffineModel3D( Transform3D transform ) { final double[] m = new double[16]; transform.get( m ); AffineModel3D model = new AffineModel3D(); model.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] ); return model; } public static RigidModel3D getRigidModel3D( Transform3D transform ) { final double[] m = new double[16]; transform.get( m ); RigidModel3D model = new RigidModel3D(); model.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] ); return model; } public static void main( String[] args ) { AffineModel3D m = new AffineModel3D(); m.set( 0.87912226f, 0.425894f, 0.21391234f, -169.3024f, -0.47269103f, 0.836501f, 0.2771809f, 42.627777f, -0.0608882f, -0.34479034f, 0.93670285f, 246.59639f ); Transform3D t = TransformUtils.getTransform3D1( m ); Vector3d s = new Vector3d(); t.getScale( s ); System.out.println( s ); } }