Java Code Examples for net.imglib2.realtransform.AffineTransform3D#apply()

The following examples show how to use net.imglib2.realtransform.AffineTransform3D#apply() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: PaintUtils.java    From paintera with GNU General Public License v2.0 6 votes vote down vote up
public static double[] maximumVoxelDiagonalLengthPerDimension(
		final AffineTransform3D labelToGlobalTransform,
		final AffineTransform3D viewerTransform)
{
	final double[]          unitX                                    = {1.0, 0.0, 0.0};
	final double[]          unitY                                    = {0.0, 1.0, 0.0};
	final double[]          unitZ                                    = {0.0, 0.0, 1.0};
	final AffineTransform3D labelToGlobalTransformWithoutTranslation = duplicateWithoutTranslation(labelToGlobalTransform);
	final AffineTransform3D viewerTransformWithoutTranslation        = duplicateWithoutTranslation(viewerTransform);
	labelToGlobalTransformWithoutTranslation.apply(unitX, unitX);
	labelToGlobalTransformWithoutTranslation.apply(unitY, unitY);
	labelToGlobalTransformWithoutTranslation.apply(unitZ, unitZ);
	viewerTransformWithoutTranslation.apply(unitX, unitX);
	viewerTransformWithoutTranslation.apply(unitY, unitY);
	viewerTransformWithoutTranslation.apply(unitZ, unitZ);
	LOG.debug("Transformed unit vectors x={} y={} z={}", unitX, unitY, unitZ);
	final double[] projections = new double[] {
			length(unitX[0], unitY[0], unitZ[0]),
			length(unitX[1], unitY[1], unitZ[1]),
			length(unitX[2], unitY[2], unitZ[2])
	};
	LOG.debug("Projections={}", projections);
	return projections;
}
 
Example 2
Source File: FitToInterval.java    From paintera with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void onChanged(final Change<? extends Source<?>> change)
{
	while (change.next())
		if (change.wasAdded() && change.getList().size() == 1)
		{
			final Source<?>         addedSource = change.getAddedSubList().get(0);
			final double[]          min         = Arrays.stream(Intervals.minAsLongArray(addedSource.getSource(
					0,
					0
			                                                                                                  ))).asDoubleStream().toArray();
			final double[]          max         = Arrays.stream(Intervals.maxAsLongArray(addedSource.getSource(
					0,
					0
			                                                                                                  ))).asDoubleStream().toArray();
			final AffineTransform3D tf          = new AffineTransform3D();
			addedSource.getSourceTransform(0, 0, tf);
			tf.apply(min, min);
			tf.apply(max, max);
			fitToInterval.fit(Intervals.smallestContainingInterval(new FinalRealInterval(min, max)));
		}

}
 
Example 3
Source File: RemoveRotation.java    From paintera with GNU General Public License v2.0 5 votes vote down vote up
public void removeRotationCenteredAt(final double x, final double y)
{

	final double[] mouseLocation = new double[3];

	final RealPoint p = RealPoint.wrap(mouseLocation);
	p.setPosition(x, 0);
	p.setPosition(y, 1);
	p.setPosition(0, 2);

	final AffineTransform3D global = new AffineTransform3D();

	synchronized (lock)
	{
		global.set(globalTransform);
		viewerTransform.applyInverse(mouseLocation, mouseLocation);
	}
	final double[] inOriginalSpace = mouseLocation.clone();
	global.apply(mouseLocation, mouseLocation);

	final AffineTransform3D affine = new AffineTransform3D();
	for (int i = 0; i < affine.numDimensions(); ++i)
	{
		double val = 0.0;
		for (int k = 0; k < affine.numDimensions(); ++k)
		{
			final double entry = global.get(k, i);
			val += entry * entry;
		}
		val = Math.sqrt(val);
		affine.set(val, i, i);
		affine.set(mouseLocation[i] - inOriginalSpace[i] * val, i, 3);
	}
	LOG.debug("Updating transform to {}", affine);
	submitTransform.accept(affine);
}
 
Example 4
Source File: OrthogonalCrossSectionsIntersect.java    From paintera with GNU General Public License v2.0 5 votes vote down vote up
public static void centerAt(
		final AffineTransform3D transform,
		final double x,
		final double y,
		final double z)
{
	final double[] center = new double[] {x, y, z};
	LOG.debug("Centering at {}", center);
	transform.apply(center, center);
	transform.set(transform.get(0, 3) - center[0], 0, 3);
	transform.set(transform.get(1, 3) - center[1], 1, 3);
	transform.set(transform.get(2, 3) - center[2], 2, 3);
}
 
Example 5
Source File: Zoom.java    From paintera with GNU General Public License v2.0 5 votes vote down vote up
public void zoomCenteredAt(final double delta, final double x, final double y)
{

	if (delta == 0.0)
	{
		return;
	}

	final AffineTransform3D global = new AffineTransform3D();
	synchronized (lock)
	{
		global.set(this.global);
	}
	final double[] location = new double[] {x, y, 0};
	concatenated.applyInverse(location, location);
	global.apply(location, location);

	final double dScale = speed.getAsDouble();
	final double scale  = delta > 0 ? 1.0 / dScale : dScale;

	for (int d = 0; d < location.length; ++d)
		global.set(global.get(d, 3) - location[d], d, 3);
	global.scale(scale);
	for (int d = 0; d < location.length; ++d)
		global.set(global.get(d, 3) + location[d], d, 3);

	manager.setTransform(global);
}
 
Example 6
Source File: PaintUtils.java    From paintera with GNU General Public License v2.0 5 votes vote down vote up
/**
 * This should be equivalent to {@link #maximumVoxelDiagonalLengthPerDimension(AffineTransform3D,
 * AffineTransform3D)}.
 *
 * @param labelToGlobalTransform
 * @param viewerTransform
 *
 * @return
 */
public static double[] labelUnitLengthAlongViewerAxis(
		final AffineTransform3D labelToGlobalTransform,
		final AffineTransform3D viewerTransform)
{
	final AffineTransform3D labelToGlobalTransformWithoutTranslation = duplicateWithoutTranslation(labelToGlobalTransform);
	final AffineTransform3D viewerTransformWithoutTranslation        = duplicateWithoutTranslation(viewerTransform);
	final AffineTransform3D labelToViewerTransformWithoutTranslation = labelToGlobalTransformWithoutTranslation.preConcatenate(viewerTransformWithoutTranslation);

	final double[] unitX = {1.0, 0.0, 0.0};
	final double[] unitY = {0.0, 1.0, 0.0};
	final double[] unitZ = {0.0, 0.0, 1.0};
	labelToViewerTransformWithoutTranslation.applyInverse(unitX, unitX);
	labelToViewerTransformWithoutTranslation.applyInverse(unitY, unitY);
	labelToViewerTransformWithoutTranslation.applyInverse(unitZ, unitZ);

	LinAlgHelpers.normalize(unitX);
	LinAlgHelpers.normalize(unitY);
	LinAlgHelpers.normalize(unitZ);

	labelToViewerTransformWithoutTranslation.apply(unitX, unitX);
	labelToViewerTransformWithoutTranslation.apply(unitY, unitY);
	labelToViewerTransformWithoutTranslation.apply(unitZ, unitZ);

	return new double[] {
			unitX[0],
			unitY[1],
			unitZ[2]
	};

}
 
Example 7
Source File: DifferenceOf.java    From SPIM_Registration with GNU General Public License v2.0 5 votes vote down vote up
protected void correctForDownsampling( final List< InterestPoint > ips, final AffineTransform3D t )
{
	IOFunctions.println("(" + new Date(System.currentTimeMillis()) + "): Correcting coordinates for downsampling (xy=" + downsampleXY + "x, z=" + downsampleZ + "x) using AffineTransform: " + t );

	if ( ips == null || ips.size() == 0 )
	{
		IOFunctions.println("(" + new Date(System.currentTimeMillis()) + "): WARNING: List is empty." );
		return;
	}

	final double[] tmp = new double[ ips.get( 0 ).getL().length ];

	for ( final InterestPoint ip : ips )
	{
		t.apply( ip.getL(), tmp );

		ip.getL()[ 0 ] = tmp[ 0 ];
		ip.getL()[ 1 ] = tmp[ 1 ];
		ip.getL()[ 2 ] = tmp[ 2 ];

		t.apply( ip.getW(), tmp );

		ip.getW()[ 0 ] = tmp[ 0 ];
		ip.getW()[ 1 ] = tmp[ 1 ];
		ip.getW()[ 2 ] = tmp[ 2 ];
	}
}
 
Example 8
Source File: InterestPointOverlay.java    From SPIM_Registration with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void drawOverlays( final Graphics g )
{
	final Graphics2D graphics = ( Graphics2D ) g;
	final int t = viewer.getState().getCurrentTimepoint();
	final double[] lPos = new double[ 3 ];
	final double[] gPos = new double[ 3 ];
	final AffineTransform3D transform = new AffineTransform3D();

	for ( final InterestPointSource pointSource : interestPointSources )
	{
		pointSource.getLocalToGlobalTransform( t, transform );
		transform.preConcatenate( viewerTransform );

		for ( final RealLocalizable p : pointSource.getLocalCoordinates( t ) )
		{
			p.localize( lPos );
			transform.apply( lPos, gPos );
			final double size = getPointSize( gPos );
			final int x = ( int ) ( gPos[ 0 ] - 0.5 * size );
			final int y = ( int ) ( gPos[ 1 ] - 0.5 * size );
			final int w = ( int ) size;
			graphics.setColor( getColor( gPos ) );
			graphics.fillOval( x, y, w, w );
		}
	}
}
 
Example 9
Source File: RenderBoxHelperFX.java    From paintera with GNU General Public License v2.0 4 votes vote down vote up
public void renderBox(final Interval sourceInterval, final AffineTransform3D transform, final Path front, final
Path back)
{
	final double sX0 = sourceInterval.min(0);
	final double sX1 = sourceInterval.max(0);
	final double sY0 = sourceInterval.min(1);
	final double sY1 = sourceInterval.max(1);
	final double sZ0 = sourceInterval.min(2);
	final double sZ1 = sourceInterval.max(2);

	final double[] p000 = new double[] {sX0, sY0, sZ0};
	final double[] p100 = new double[] {sX1, sY0, sZ0};
	final double[] p010 = new double[] {sX0, sY1, sZ0};
	final double[] p110 = new double[] {sX1, sY1, sZ0};
	final double[] p001 = new double[] {sX0, sY0, sZ1};
	final double[] p101 = new double[] {sX1, sY0, sZ1};
	final double[] p011 = new double[] {sX0, sY1, sZ1};
	final double[] p111 = new double[] {sX1, sY1, sZ1};

	final double[] q000 = new double[3];
	final double[] q100 = new double[3];
	final double[] q010 = new double[3];
	final double[] q110 = new double[3];
	final double[] q001 = new double[3];
	final double[] q101 = new double[3];
	final double[] q011 = new double[3];
	final double[] q111 = new double[3];

	transform.apply(p000, q000);
	transform.apply(p100, q100);
	transform.apply(p010, q010);
	transform.apply(p110, q110);
	transform.apply(p001, q001);
	transform.apply(p101, q101);
	transform.apply(p011, q011);
	transform.apply(p111, q111);

	splitEdge(q000, q100, front, back);
	splitEdge(q100, q110, front, back);
	splitEdge(q110, q010, front, back);
	splitEdge(q010, q000, front, back);

	splitEdge(q001, q101, front, back);
	splitEdge(q101, q111, front, back);
	splitEdge(q111, q011, front, back);
	splitEdge(q011, q001, front, back);

	splitEdge(q000, q001, front, back);
	splitEdge(q100, q101, front, back);
	splitEdge(q110, q111, front, back);
	splitEdge(q010, q011, front, back);
}
 
Example 10
Source File: FloodFillTransformedCylinder3D.java    From paintera with GNU General Public License v2.0 4 votes vote down vote up
public FloodFillTransformedCylinder3D(
		final AffineTransform3D localToWorld,
		final double radiusX,
		final double radiusY,
		final double zRangePos,
		final double zRangeNeg)
{
	super();
	this.localToWorld = localToWorld;
	this.radiusXSquared = radiusX * radiusX;
	this.radiusYSquared = radiusY * radiusY;
	this.radiusXSquaredRadiusYSquared = radiusXSquared * radiusYSquared;
	this.zRangePos = zRangePos;
	this.zRangeNeg = zRangeNeg;

	final double[] dx = D_X_LOCAL.clone();
	final double[] dy = D_Y_LOCAL.clone();
	final double[] dz = D_Z_LOCAL.clone();

	final AffineTransform3D transformNoTranslation = this.localToWorld.copy();
	transformNoTranslation.setTranslation(0.0, 0.0, 0.0);
	transformNoTranslation.apply(dx, dx);
	transformNoTranslation.apply(dy, dy);
	transformNoTranslation.apply(dz, dz);

	this.dxx = dx[0];
	this.dxy = dx[1];
	this.dxz = dx[2];

	this.dyx = dy[0];
	this.dyy = dy[1];
	this.dyz = dy[2];

	this.dzx = dz[0];
	this.dzy = dz[1];
	this.dzz = dz[2];

	this.dxxHalf = 0.5 * dxx;
	this.dxyHalf = 0.5 * dxy;
	this.dxzHalf = 0.5 * dxz;

	this.dyxHalf = 0.5 * dyx;
	this.dyyHalf = 0.5 * dyy;
	this.dyzHalf = 0.5 * dyz;

	this.dzxHalf = 0.5 * dzx;
	this.dzyHalf = 0.5 * dzy;
	this.dzzHalf = 0.5 * dzz;

}
 
Example 11
Source File: FloodFillTransformedPlane.java    From paintera with GNU General Public License v2.0 4 votes vote down vote up
public FloodFillTransformedPlane(
		final AffineTransform3D localToWorld,
		final double minX,
		final double minY,
		final double maxX,
		final double maxY,
		final double zRangePos,
		final double zRangeNeg)
{
	super();
	this.minX = minX;
	this.minY = minY;
	this.maxX = maxX;
	this.maxY = maxY;
	this.localToWorld = localToWorld;
	this.zRangePos = zRangePos;
	this.zRangeNeg = zRangeNeg;

	final double[] dx = D_X_LOCAL.clone();
	final double[] dy = D_Y_LOCAL.clone();
	final double[] dz = D_Z_LOCAL.clone();

	final AffineTransform3D transformNoTranslation = this.localToWorld.copy();
	transformNoTranslation.setTranslation(0.0, 0.0, 0.0);
	transformNoTranslation.apply(dx, dx);
	transformNoTranslation.apply(dy, dy);
	transformNoTranslation.apply(dz, dz);

	this.dxx = dx[0];
	this.dxy = dx[1];
	this.dxz = dx[2];

	this.dyx = dy[0];
	this.dyy = dy[1];
	this.dyz = dy[2];

	this.dzx = dz[0];
	this.dzy = dz[1];
	this.dzz = dz[2];

}
 
Example 12
Source File: ViewFrustumCulling.java    From paintera with GNU General Public License v2.0 4 votes vote down vote up
/**
 * For culling in the target coordinate space defined by the {@code transform} that maps the camera space into the target space.
 *
 * @param viewFrustumCamera
 * 			view frustum in the camera space, where the camera is placed at (0,0,0) and is looking towards positive Z axis.
 * @param transform
 * 			transform that maps points from the camera space into the target space
 */
public ViewFrustumCulling(final ViewFrustum viewFrustumCamera, final AffineTransform3D transform)
{
	this.viewFrustumCamera = viewFrustumCamera;
	this.transform = transform;

	final ViewFrustumPlane[] cameraNearFarPlanes = viewFrustumCamera.getNearFarPlanes().toArray();
	final ViewFrustumPlane[] targetNearFarPlanes = new ViewFrustumPlane[2];
	for (int i = 0; i < 2; ++i)
	{
		targetNearFarPlanes[i] = new ViewFrustumPlane();
		transform.apply(cameraNearFarPlanes[i].minMin, targetNearFarPlanes[i].minMin);
		transform.apply(cameraNearFarPlanes[i].minMax, targetNearFarPlanes[i].minMax);
		transform.apply(cameraNearFarPlanes[i].maxMin, targetNearFarPlanes[i].maxMin);
		transform.apply(cameraNearFarPlanes[i].maxMax, targetNearFarPlanes[i].maxMax);
	}

	this.points = new RealPoint[] {
			targetNearFarPlanes[0].minMin,
			targetNearFarPlanes[0].minMax,
			targetNearFarPlanes[0].maxMin,
			targetNearFarPlanes[0].maxMax,
			targetNearFarPlanes[1].minMin,
			targetNearFarPlanes[1].minMax,
			targetNearFarPlanes[1].maxMin,
			targetNearFarPlanes[1].maxMax
	};

	this.planes = new Vec4d[6];
	int planeIndex = 0;

	// near plane
	this.planes[planeIndex++] = Geom3DUtils.createPlane(targetNearFarPlanes[0].maxMax, targetNearFarPlanes[0].minMax, targetNearFarPlanes[0].maxMin);

	// far plane
	this.planes[planeIndex++] = Geom3DUtils.createPlane(targetNearFarPlanes[1].maxMin, targetNearFarPlanes[1].minMin, targetNearFarPlanes[1].maxMax);

	// side planes
	this.planes[planeIndex++] = Geom3DUtils.createPlane(targetNearFarPlanes[1].minMin, targetNearFarPlanes[0].minMin, targetNearFarPlanes[1].minMax);
	this.planes[planeIndex++] = Geom3DUtils.createPlane(targetNearFarPlanes[0].maxMin, targetNearFarPlanes[0].minMin, targetNearFarPlanes[1].maxMin);
	this.planes[planeIndex++] = Geom3DUtils.createPlane(targetNearFarPlanes[0].maxMin, targetNearFarPlanes[1].maxMin, targetNearFarPlanes[0].maxMax);
	this.planes[planeIndex++] = Geom3DUtils.createPlane(targetNearFarPlanes[0].maxMax, targetNearFarPlanes[1].maxMax, targetNearFarPlanes[0].minMax);
}
 
Example 13
Source File: TransformTools.java    From BigStitcher with GNU General Public License v2.0 4 votes vote down vote up
public static void main(String[] args)
{
	AffineTransform3D scale = new AffineTransform3D();
	
	scale.scale( 2.0 );
	//scale.rotate( 0, 45 );
	
	
	AffineTransform3D translate = new AffineTransform3D();
	translate.translate( new double[] {100.0, 100.0, 100.0} );
	AffineTransform3D translate2 = new AffineTransform3D();
	translate2.translate( new double[] {200.0, 200.0, 200.0} );
	
	AffineTransform3D conc = scale.copy().preConcatenate( translate );
	scale.scale( 3.0 );
	AffineTransform3D conc2 = scale.copy().preConcatenate( translate2 );
	//System.out.println( scale );
	//System.out.println( translate );
	System.out.println( conc );
	System.out.println( conc2 );
	
	RealPoint p1 = new RealPoint( 3 );
	conc.apply( p1, p1 );
	RealPoint p2 = new RealPoint( 3 );
	conc2.apply( p2, p2 );
	
	System.out.println( p1 );
	System.out.println( p2 );
	
	AffineTransform3D everythingbuttraslation = conc.copy();
	everythingbuttraslation.set( 0, 0, 3 );
	everythingbuttraslation.set( 0, 1, 3 );
	everythingbuttraslation.set( 0, 2, 3 );
	
	AffineTransform3D everythingbuttraslation2 = conc2.copy();
	everythingbuttraslation2.set( 0, 0, 3 );
	everythingbuttraslation2.set( 0, 1, 3 );
	everythingbuttraslation2.set( 0, 2, 3 );
	
	double[] trans1 = conc.getTranslation();
	double[] trans2 = conc2.getTranslation();
	
	everythingbuttraslation.inverse().apply( trans1, trans1 );
	everythingbuttraslation2.inverse().apply( trans2, trans2 );
	
	System.out.println( new RealPoint( trans1 ) );
	System.out.println( new RealPoint( trans2 ) );
	
	
	System.out.println( mapBackTransform( everythingbuttraslation, everythingbuttraslation2 ) );
	
	
	
	
}
 
Example 14
Source File: LinkOverlay.java    From BigStitcher with GNU General Public License v2.0 4 votes vote down vote up
public static void drawViewOutlines( final Graphics2D g, final Dimensions dims, final AffineTransform3D transfrom, final Color color )
{
	final int n = dims.numDimensions();

	final Queue< List< Boolean > > worklist = new LinkedList<>();
	// add 0,0,..
	final List< Boolean > origin = new ArrayList<>();
	for (int d = 0; d < n; d++)
		origin.add( false );
	worklist.add( origin );

	while ( worklist.size() > 0 )
	{
		final List< Boolean > vertex1 = worklist.poll();
		final List< List< Boolean > > neighbors = getHigherVertices( vertex1 );

		worklist.addAll( neighbors );

		for (final List<Boolean> vertex2 : neighbors)
		{
			final double[] v1Pos = new double[ n ];
			final double[] v2Pos = new double[ n ];

			for (int d = 0; d < n; d++)
			{
				// the outline goes from -0.5 to dimension(d) - 0.5 (compared to the actual range of (0, dim(d)-1))
				// this is because BDV (correctly) draws pixels with center at pixel location 
				v1Pos[d] = vertex1.get( d ) ? dims.dimension( d ) - 0.5 : -0.5;
				v2Pos[d] = vertex2.get( d ) ? dims.dimension( d ) - 0.5 : -0.5;
			}

			transfrom.apply( v1Pos, v1Pos );
			transfrom.apply( v2Pos, v2Pos );

			g.setColor( color );
			g.setStroke( new BasicStroke( 1.0f ) );
			g.drawLine((int) v1Pos[0],(int) v1Pos[1],(int) v2Pos[0],(int) v2Pos[1] );
		}
		
	}
	
}
 
Example 15
Source File: GlobalOptimizationType.java    From SPIM_Registration with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Creates lists of input points for the registration, based on the current transformation of the views
 * 
 * Note: this always duplicates the location array from the input List&gt; InterestPoint &lt; !!!
 * 
 * @param timepoint
 */
protected HashMap< ViewId, MatchPointList > getInterestPoints( final TimePoint timepoint )
{
	final HashMap< ViewId, MatchPointList > interestPoints = new HashMap< ViewId, MatchPointList >();
	final ViewRegistrations registrations = spimData.getViewRegistrations();
	final ViewInterestPoints interestpoints = spimData.getViewInterestPoints();
	
	for ( final ViewDescription vd : SpimData2.getAllViewIdsForTimePointSorted( spimData, viewIdsToProcess, timepoint) )
	{
		if ( !vd.isPresent() )
			continue;

		final ChannelProcess c = getChannelProcessForChannel( channelsToProcess, vd.getViewSetup().getChannel() );

		// no registration for this viewdescription
		if ( c == null )
			continue;

		final Angle a = vd.getViewSetup().getAngle();
		final Illumination i = vd.getViewSetup().getIllumination();

		// assemble a new list
		final ArrayList< InterestPoint > list = new ArrayList< InterestPoint >();

		// check the existing lists of points
		final ViewInterestPointLists lists = interestpoints.getViewInterestPointLists( vd );

		if ( !lists.contains( c.getLabel() ) )
		{
			IOFunctions.println( "Interest points for label '" + c.getLabel() + "' not found for timepoint: " + timepoint.getId() + " angle: " + 
					a.getId() + " channel: " + c.getChannel().getId() + " illum: " + i.getId() );
			
			continue;
		}
		
		if ( lists.getInterestPointList( c.getLabel() ).getInterestPoints() == null )
		{
			if ( !lists.getInterestPointList( c.getLabel() ).loadInterestPoints() )
			{
				IOFunctions.println( "Interest points for label '" + c.getLabel() + "' could not be loaded for timepoint: " + timepoint.getId() + " angle: " + 
						a.getId() + " channel: " + c.getChannel().getId() + " illum: " + i.getId() );
				
				continue;
			}
		}
		
		final List< InterestPoint > ptList = lists.getInterestPointList( c.getLabel() ).getInterestPoints();
		
		final ViewRegistration r = registrations.getViewRegistration( vd );
		r.updateModel();
		final AffineTransform3D m = r.getModel();
		
		for ( final InterestPoint p : ptList )
		{
			final double[] l = new double[ 3 ];
			m.apply( p.getL(), l );
			
			list.add( new InterestPoint( p.getId(), l ) );
		}
		
		interestPoints.put( vd, new MatchPointList( list, c ) );
	}

	return interestPoints;
}
 
Example 16
Source File: ExtractPSF.java    From SPIM_Registration with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Transforms the extracted PSF using the affine transformation of the corresponding view
 * 
 * @param psf - the extracted psf (NOT z-scaling corrected)
 * @param model - the transformation model
 * @return the transformed psf which has odd sizes and where the center of the psf is also the center of the transformed psf
 */
protected static < T extends RealType< T > & NativeType< T > > ArrayImg< T, ? > transformPSF(
		final RandomAccessibleInterval< T > psf,
		final AffineTransform3D model )
{
	// here we compute a slightly different transformation than the ImageTransform does
	// two things are necessary:
	// a) the center pixel stays the center pixel
	// b) the transformed psf has a odd size in all dimensions
	
	final int numDimensions = psf.numDimensions();
	
	final RealInterval minMaxDim = model.estimateBounds( psf );
	
	final double[] size = new double[ numDimensions ];		
	final long[] newSize = new long[ numDimensions ];		
	final double[] offset = new double[ numDimensions ];
	
	// the center of the psf has to be the center of the transformed psf as well
	// this is important!
	final double[] center = new double[ numDimensions ];
	final double[] tmp = new double[ numDimensions ];

	for ( int d = 0; d < numDimensions; ++d )
		center[ d ] = psf.dimension( d ) / 2;
	
	model.apply( center, tmp );

	for ( int d = 0; d < numDimensions; ++d )
	{
		size[ d ] = minMaxDim.realMax( d ) - minMaxDim.realMin( d );
		
		newSize[ d ] = (int)size[ d ] + 1;
		if ( newSize[ d ] % 2 == 0 )
			++newSize[ d ];
			
		// the offset is defined like this:
		// the transformed coordinates of the center of the psf
		// are the center of the transformed psf
		offset[ d ] = tmp[ d ] - newSize[ d ]/2;
	}
	
	return transform( psf, model, newSize, offset );
}