Java源码示例:net.imglib2.RealInterval

示例1
private void setRenderedImageListener()
{
	renderUnit.getRenderedImageProperty().addListener((obs, oldv, newv) -> {
		if (newv != null && newv.getImage() != null) {
			final Interval screenInterval = newv.getScreenInterval();
			final RealInterval renderTargetRealInterval = newv.getRenderTargetRealInterval();
			canvasPane.getCanvas().getGraphicsContext2D().drawImage(
				newv.getImage(), // src
				renderTargetRealInterval.realMin(0), // src X
				renderTargetRealInterval.realMin(1), // src Y
				renderTargetRealInterval.realMax(0) - renderTargetRealInterval.realMin(0), // src width
				renderTargetRealInterval.realMax(1) - renderTargetRealInterval.realMin(1), // src height
				screenInterval.min(0), // dst X
				screenInterval.min(1), // dst Y
				screenInterval.dimension(0), // dst width
				screenInterval.dimension(1)  // dst height
			);
		}
	});
}
 
示例2
public static FinalRealInterval applyTranslation(RealInterval img, TranslationGet translation, boolean[] ignoreDims){

		// get number of dimensions we actually use
		int n = 0;
		for (int d = 0; d < ignoreDims.length; ++d)
			if (!ignoreDims[d])
				n++;
		
		final double [] min = new double [n];
		final double [] max = new double [n];
		
		int i2 = 0;
		for (int i = 0; i< img.numDimensions();++i)
		{
			if (!ignoreDims[i])
			{
				min[i2] = img.realMin(i) + translation.getTranslation(i);
				max[i2] = img.realMax(i) + translation.getTranslation(i);
				i2++;
			}
		}
		return new FinalRealInterval(min, max);
	}
 
示例3
/**
 * create an integer interval from real interval, being conservatie on the size
 * (min is ceiled, max is floored)
 * @param overlap real input
 * @return interger interval, with mins ceiled and maxs floored
 */
public static FinalInterval getLocalRasterOverlap(RealInterval overlap)
{
	final int n = overlap.numDimensions();
	final long [] min = new long [n];
	final long [] max = new long [n];
	
	for (int i = 0; i< n; i++)
	{
		// round down errors when it is exactly 0.5, if we do not do this we end up with two intervals
		// of different size, e.g.:
		// if the first interval starts at 139.5 going to 199, the second one at 0.0 going to 59.5
		// then the rastered 1st would go from round(139.5)=140 + 1 = 141 -to- round(199)=199 - 1 = 198, dim=58
		// and  the rastered 2nd would go from round(0.0)=0 + 1     =   1 -to- round(59.5)=60 - 1 = 59,  dim=59
		min[i] = Math.round((overlap.realMin(i) - 0.0001 )) + 1;
		max[i] = Math.round((overlap.realMax(i) + 0.0001 )) - 1;
	}
	
	return new FinalInterval(min, max);
}
 
示例4
public static FinalRealInterval getOverlap(final RealInterval img1, final RealInterval img2){
	final int n = img1.numDimensions();
	final double [] min = new double [n];
	final double [] max = new double [n];
	
	for (int i = 0; i< n; i++)
	{
		min[i] = Math.max(img1.realMin(i), img2.realMin(i));
		max[i] = Math.min(img1.realMax(i), img2.realMax(i));
		
		// intervals do not overlap
		if ( max[i] < min [i])
			return null;
	}
	
	return new FinalRealInterval(min, max);
}
 
示例5
public RenderResult(
		final Image image,
		final Interval screenInterval,
		final RealInterval renderTargetRealInterval,
		final int screenScaleIndex) {
	this.image = image;
	this.screenInterval = screenInterval;
	this.renderTargetRealInterval = renderTargetRealInterval;
	this.screenScaleIndex = screenScaleIndex;
}
 
示例6
private RandomAccessibleInterval<UnsignedLongType> getTransformedMaskSection(final SectionInfo sectionInfo)
{
	final RealInterval sectionBounds = sectionInfo.sourceToDisplayTransform.estimateBounds(sectionInfo.sourceBoundingBox);
	final Interval sectionInterval = Intervals.smallestContainingInterval(sectionBounds);
	final RealRandomAccessible<UnsignedLongType> transformedMask = getTransformedMask(sectionInfo.mask, sectionInfo.sourceToDisplayTransform);
	final RandomAccessibleInterval<UnsignedLongType> transformedMaskInterval = Views.interval(Views.raster(transformedMask), sectionInterval);
	return Views.hyperSlice(transformedMaskInterval, 2, 0l);
}
 
示例7
private synchronized void paint(final double viewerX, final double viewerY)
{

	LOG.debug( "At {} {}", viewerX, viewerY );

	if (!this.isPainting) {
		LOG.debug("Not currently activated for painting, returning without action");
		return;
	}

	final RandomAccessibleInterval<UnsignedLongType> mask = getMaskIfIsPaintingOrNull();
	if (mask == null) {
		LOG.debug("Current mask is null, returning without action");
		return;
	}
	final double radius = brushRadius.getAsDouble();
	final Interval trackedInterval = Paint2D.paint(
			Views.extendValue(mask, new UnsignedLongType(Label.INVALID)),
			this.fillLabel,
			viewerX,
			viewerY,
			radius,
			brushDepth.getAsDouble(),
			labelToViewerTransform,
			globalToViewerTransform,
			labelToGlobalTransform);
	this.interval = this.interval == null
			? trackedInterval
			: Intervals.union(trackedInterval, this.interval);
	++this.fillLabel;

	final RealInterval trackedIntervalInGlobalSpace = IntervalHelpers.extendAndTransformBoundingBox(trackedInterval, labelToGlobalTransform, 0.5);
	this.paintera.orthogonalViews().requestRepaint(trackedIntervalInGlobalSpace);

}
 
示例8
public ViewFrustum(final PerspectiveCamera camera, final double[] screenSize)
{
	this.screenSize = screenSize.clone();
	this.tanHalfFov = new double[2];

	final double widthToHeightRatio = screenSize[0] / screenSize[1];
	final double halfFovMainDimension = Math.toRadians(camera.getFieldOfView() / 2);
	if (camera.isVerticalFieldOfView())
	{
		tanHalfFov[1] = Math.tan(halfFovMainDimension);
		tanHalfFov[0] = tanHalfFov[1] * widthToHeightRatio;
	}
	else
	{
		tanHalfFov[0] = Math.tan(halfFovMainDimension);
		tanHalfFov[1] = tanHalfFov[0] / widthToHeightRatio;
	}

	final ViewFrustumPlane[] newNearFarPlanes = new ViewFrustumPlane[2];
	final double[] clipValues = {camera.getNearClip(), camera.getFarClip()};
	for (int i = 0; i < 2; ++i)
	{
		final double clipVal = clipValues[i];
		final RealInterval viewPlane2D = viewPlaneAtGivenDistance(clipVal);
		newNearFarPlanes[i] = new ViewFrustumPlane();
		newNearFarPlanes[i].minMin.setPosition(new double[] {viewPlane2D.realMin(0), viewPlane2D.realMin(1), clipVal});
		newNearFarPlanes[i].minMax.setPosition(new double[] {viewPlane2D.realMin(0), viewPlane2D.realMax(1), clipVal});
		newNearFarPlanes[i].maxMin.setPosition(new double[] {viewPlane2D.realMax(0), viewPlane2D.realMin(1), clipVal});
		newNearFarPlanes[i].maxMax.setPosition(new double[] {viewPlane2D.realMax(0), viewPlane2D.realMax(1), clipVal});
	}

	nearFarPlanes = new ViewFrustumPlanes(
			newNearFarPlanes[0],
			newNearFarPlanes[1]
		);
}
 
示例9
public RealInterval viewPlaneAtGivenDistance(final double z)
{
	final double[] min = new double[2], max = new double[2];
	for (int d = 0; d < 2; ++d)
	{
		final double halfLen = tanHalfFov[d] * z;
		min[d] = -halfLen;
		max[d] = +halfLen;
	}
	return new FinalRealInterval(min, max);
}
 
示例10
@Override
public RealRandomAccessible<T> getInterpolatedSource(final int t, final int level, final Interpolation method)
{
	final RealRandomAccessible<T> sourceToExtend;

	// ignore interpolation method because we cannot use linear interpolation on LabelMultisetType
	final RealRandomAccessible<T> interpolatedSource = this.source.getInterpolatedSource(t, level, Interpolation.NEARESTNEIGHBOR);
	if (!this.showCanvasOverBackground.get() || this.affectedBlocks.size() == 0 && this.currentMask == null)
	{
		LOG.debug("Hide canvas or no mask/canvas data present -- delegate to underlying source");
		sourceToExtend = interpolatedSource;
	}
	else
	{
		final RealRandomAccessible<VolatileUnsignedLongType> canvas = interpolateNearestNeighbor(Views.extendValue(this.canvases[level].getRai(), new VolatileUnsignedLongType(Label.INVALID)));
		final RealRandomAccessible<VolatileUnsignedLongType> mask = this.tMasks[level];
		final RealRandomAccessibleTriple<T, VolatileUnsignedLongType, VolatileUnsignedLongType> composed = new
				RealRandomAccessibleTriple<>(
				interpolatedSource,
				canvas,
				mask
		);
		sourceToExtend = new PickOne<>(composed, pacT.copyWithDifferentNumOccurences(numContainedVoxels(level)));
	}

	// extend the interpolated source with the specified out of bounds value
	final RealInterval bounds = new FinalRealInterval(source.getSource(t, level));
	final RealRandomAccessibleRealInterval<T> boundedSource = new FinalRealRandomAccessibleRealInterval<>(sourceToExtend, bounds);
	return new ExtendedRealRandomAccessibleRealInterval<>(boundedSource, new RealOutOfBoundsConstantValueFactory<>(extensionT.copy()));
}
 
示例11
@Override
public RealRandomAccessible<D> getInterpolatedDataSource(final int t, final int level, final Interpolation method)
{
	final RealRandomAccessible<D> dataSourceToExtend;

	// ignore interpolation method because we cannot use linear interpolation on LabelMultisetType
	final RealRandomAccessible<D> interpolatedDataSource = this.source.getInterpolatedDataSource(t, level, Interpolation.NEARESTNEIGHBOR);
	if (!this.showCanvasOverBackground.get() || this.affectedBlocks.size() == 0 && this.currentMask == null)
	{
		LOG.debug("Hide canvas or no mask/canvas data present -- delegate to underlying source");
		dataSourceToExtend = interpolatedDataSource;
	}
	else
	{
		final RealRandomAccessible<UnsignedLongType> dataCanvas = interpolateNearestNeighbor(Views.extendValue(this.dataCanvases[level], new UnsignedLongType(Label.INVALID)));
		final RealRandomAccessible<UnsignedLongType> dataMask = this.dMasks[level];
		final RealRandomAccessibleTriple<D, UnsignedLongType, UnsignedLongType> composed = new RealRandomAccessibleTriple<>(
				interpolatedDataSource,
				dataCanvas,
				dataMask);
		dataSourceToExtend = new PickOne<>(composed, pacD.copyWithDifferentNumOccurences(numContainedVoxels(level)));
	}

	// extend the interpolated source with the specified out of bounds value
	final RealInterval bounds = new FinalRealInterval(source.getDataSource(t, level));
	final RealRandomAccessibleRealInterval<D> boundedDataSource = new FinalRealRandomAccessibleRealInterval<>(dataSourceToExtend, bounds);
	return new ExtendedRealRandomAccessibleRealInterval<>(boundedDataSource, new RealOutOfBoundsConstantValueFactory<>(extensionD.copy()));
}
 
示例12
private Node createBlockShape(final ShapeKey<T> key)
	{
		final Interval keyInterval = key.interval();
		final double[] worldMin = new double[3], worldMax = new double[3];
		Arrays.setAll(worldMin, d -> keyInterval.min(d));
		Arrays.setAll(worldMax, d -> keyInterval.min(d) + keyInterval.dimension(d));
		unshiftedWorldTransforms.apply(key.scaleIndex()).apply(worldMin, worldMin);
		unshiftedWorldTransforms.apply(key.scaleIndex()).apply(worldMax, worldMax);

		final RealInterval blockWorldInterval = new FinalRealInterval(worldMin, worldMax);
		final double[] blockWorldSize = new double[blockWorldInterval.numDimensions()];
		Arrays.setAll(blockWorldSize, d -> blockWorldInterval.realMax(d) - blockWorldInterval.realMin(d));

		// the standard Box primitive is made up of triangles, so the unwanted diagonals are visible when using DrawMode.Line
//		final Box box = new Box(
//				blockWorldSize[0],
//				blockWorldSize[1],
//				blockWorldSize[2]
//			);
		final PolygonMeshView box = new PolygonMeshView(Meshes.createQuadrilateralMesh(
				(float) blockWorldSize[0],
				(float) blockWorldSize[1],
				(float) blockWorldSize[2]
		));

		final double[] blockWorldTranslation = new double[blockWorldInterval.numDimensions()];
		Arrays.setAll(blockWorldTranslation, d -> blockWorldInterval.realMin(d) + blockWorldSize[d] * 0.5);

		box.setTranslateX(blockWorldTranslation[0]);
		box.setTranslateY(blockWorldTranslation[1]);
		box.setTranslateZ(blockWorldTranslation[2]);

		final PhongMaterial material = Meshes.painteraPhongMaterial();
		box.setCullFace(CullFace.NONE);
		box.setMaterial(material);
		box.setDrawMode(DrawMode.LINE);

		return box;
	}
 
示例13
/**
 * Get all blocks/cells of a {@link CellGrid} that the real interval defined by {@code min} and {@code max}
 * intersects with, represented as linear indices.
 * @param interval interval
 * @param cellGrid defines grid (block size/cell size)
 * @return linear indices of all cells/blocks that intersect with interval defined by {@code min}, {@code max}.
 */
public static long[] getIntersectingBlocks(
		final RealInterval interval,
		final CellGrid cellGrid)
{
	return getIntersectingBlocks(
			Intervals.minAsDoubleArray(interval),
			Intervals.maxAsDoubleArray(interval),
			cellGrid
		);
}
 
示例14
public < F extends RealInterval & RealRandomAccessible< T > > AbstractRealOutOfBoundsValue( final F f )
{
	super( f.numDimensions() );
	this.sampler = f.realRandomAccess();
	min = new double[ n ];
	f.realMin( min );
	max = new double[ n ];
	f.realMax( max );
	dimIsOutOfBounds = new boolean[ n ];
}
 
示例15
/**
 * get overlap in local image coordinates (assuming min = (0,0,..))
 * @param img image interval (global coordinates)
 * @param overlap overlap interval (global coordinates)
 * @return overlap interval  in local coordinates
 */
public static FinalRealInterval getLocalOverlap(RealInterval img, RealInterval overlap){
	final int n = img.numDimensions();
	final double [] min = new double [n];
	final double [] max = new double [n];
	
	for (int i = 0; i< n; i++)
	{
		min[i] = Math.max(0, overlap.realMin(i) - img.realMin(i)) ;
		max[i] = Math.max(0, overlap.realMax(i) - img.realMin(i));
	}
	return new FinalRealInterval(min, max);
}
 
示例16
@Override
public RealRandomAccess<FloatType> realRandomAccess( final RealInterval interval )
{
	return Views.interpolate(
			Views.extendZero( this.contentBasedImg ),
			new NLinearInterpolatorFactory< FloatType >()
			).realRandomAccess( interval );
}
 
示例17
@Override
public void paint()
{
	final List<SourceAndConverter<?>> sacs = new ArrayList<>();
	final AffineTransform3D viewerTransform = new AffineTransform3D();
	final int timepoint;
	synchronized (RenderUnit.this)
	{
		if (renderer != null && renderTarget != null)
		{
			final ViewerState viewerState = RenderUnit.this.viewerState.get();
			synchronized (viewerState)
			{
				viewerState.getViewerTransform(viewerTransform);
				timepoint = viewerState.getTimepoint();
				sacs.addAll(viewerState.getSources());
			}
		}
		else
		{
			return;
		}
	}

	final int renderedScreenScaleIndex = renderer.paint(
		sacs,
		timepoint,
		viewerTransform,
		interpolation,
		null
	);

	if (renderedScreenScaleIndex != -1)
	{
		final Interval screenInterval = renderer.getLastRenderedScreenInterval();
		final RealInterval renderTargetRealInterval = renderer.getLastRenderTargetRealInterval();

		renderTarget.drawOverlays(img -> renderResultProperty.set(new RenderResult(
			img,
			screenInterval,
			renderTargetRealInterval,
			renderedScreenScaleIndex
		)));
	}
}
 
示例18
public RealInterval getRenderTargetRealInterval() {
	return renderTargetRealInterval;
}
 
示例19
public synchronized RealInterval getLastRenderTargetRealInterval()
{
	return lastRenderTargetRealInterval;
}
 
示例20
public void requestRepaint(final RealInterval intervalInGlobalSpace)
{
	this.applyToAll(v -> v.requestRepaint(intervalInGlobalSpace));
}
 
示例21
@Override
public AbstractConvertedRealRandomAccess<Triple<A, B, C>, D> realRandomAccess(final RealInterval interval)
{
	return realRandomAccess();
}
 
示例22
@Override
public RealRandomAccess realRandomAccess(final RealInterval interval)
{
	return new RealRandomAccess();
}
 
示例23
public < F extends RealInterval & RealRandomAccessible< T > > RealOutOfBoundsConstantValue( final F f, final T value )
{
	super( f );
	this.value = value;
}
 
示例24
public static void main(String[] args)
{
	RandomAccessibleInterval< FloatType > a = ImgLib2Util.openAs32Bit( new File( "73.tif.zip" ) );
	RandomAccessibleInterval< FloatType > b = ImgLib2Util.openAs32Bit( new File( "74.tif.zip" ) );
	
	long slice = 40;
	ImageJFunctions.show( a );
	
	a = Views.zeroMin( Views.hyperSlice( a, 2, slice ));
	b = Views.zeroMin( Views.hyperSlice( b, 2, slice ));

	TranslationGet t1 = new Translation2D();
	TranslationGet t2 = new Translation2D(460, 0);
	ArrayList< Pair< RealInterval, AffineGet > > views = new ArrayList<Pair<RealInterval, AffineGet>>();
	views.add( new ValuePair< RealInterval, AffineGet >( a, t1 ) );
	views.add( new ValuePair< RealInterval, AffineGet >( b, t2 ) );

	RealInterval overlap = BoundingBoxMaximalGroupOverlap.getMinBoundingIntervalSingle( views );

	final RealInterval transformed1 = TransformTools.applyTranslation( a, t1, new boolean[] {false, false} );
	final RealInterval transformed2 = TransformTools.applyTranslation( b, t2, new boolean[] {false, false} );

	// get overlap in images' coordinates
	final RealInterval localOverlap1 = TransformTools.getLocalOverlap( transformed1, overlap );
	final RealInterval localOverlap2 = TransformTools.getLocalOverlap( transformed2, overlap );

	// round to integer interval
	final Interval interval1 = TransformTools.getLocalRasterOverlap( localOverlap1 );
	final Interval interval2 = TransformTools.getLocalRasterOverlap( localOverlap2 );

	//final WarpFunction warp = new TranslationWarp(3);
	final WarpFunction warp = new RigidWarp(2);
	//final WarpFunction warp = new AffineWarp( 3 );

	// rotate second image
	AffineTransform2D rot = new AffineTransform2D();
	rot.rotate( 1.4 * Math.PI / 180 );
	RandomAccessibleInterval< FloatType > rotated = Views.interval(
			RealViews.affine( 
					Views.interpolate( Views.extendMirrorSingle( Views.zeroMin( Views.interval( b, interval2 ) ) ), new NLinearInterpolatorFactory<>() ),
					rot.copy() ),
			interval2);

	// show input
	new ImageJ();
	ImageJFunctions.show( Views.interval( a,  interval1 ) );
	ImageJFunctions.show( rotated );

	// downsample input
	RandomAccessibleInterval< FloatType > simple2x1 = Downsample.simple2x( Views.zeroMin( Views.interval( a, interval1 ) ), new ArrayImgFactory<>(), new boolean[] {false, false} );
	RandomAccessibleInterval< FloatType > simple2x2 = Downsample.simple2x( Views.zeroMin( Views.interval( rotated, interval2 ) ), new ArrayImgFactory<>(), new boolean[] {false, false} );

	// align

	//Align< FloatType > lk = new Align<>( Views.zeroMin( Views.interval( a, interval1 ) ), new ArrayImgFactory<>(), warp );
	Align< FloatType > lk = new Align<>( simple2x1, new ArrayImgFactory<>(), warp );
	//System.out.println( Util.printCoordinates( lk.align( Views.zeroMin( Views.interval( b, interval2 ) ), 100, 0.01 ).getRowPackedCopy() ) );
	//final AffineTransform transform = lk.align( Views.zeroMin( rotated ), 100, 0.01 );
	final AffineTransform transform = lk.align( simple2x2, 100, 0.1 );

	// transformation matrix
	System.out.println( Util.printCoordinates( transform.getRowPackedCopy() ) );

	// correct input and show
	RandomAccessibleInterval< FloatType > backRotated = Views.interval(
			RealViews.affine( 
					Views.interpolate( Views.extendMirrorSingle( Views.zeroMin( Views.interval( b, interval2 ) ) ), new NLinearInterpolatorFactory<>() ),
					rot.copy().preConcatenate( transform ).copy() ),
			interval2);

	ImageJFunctions.show( backRotated );

	// constructor needs column packed matrix, therefore the transpose
	Matrix mt = new Matrix( transform.getRowPackedCopy(), 3).transpose();
	Matrix rigid = mt.getMatrix( 0, 1, 0, 1 );

	// check whether result is rotation matrix (det == +-1, orthogonal)
	System.out.println( rigid.det() );
	System.out.println( Util.printCoordinates( rigid.times( rigid.transpose() ).getRowPackedCopy() ) );
}
 
示例25
public static void main(String[] args)
{
	Img< FloatType > a = ImgLib2Util.openAs32Bit( new File( "73.tif.zip" ) );
	Img< FloatType > b = ImgLib2Util.openAs32Bit( new File( "74.tif.zip" ) );

	TranslationGet t1 = new Translation3D();
	TranslationGet t2 = new Translation3D(460, 0, 0);
	ArrayList< Pair< RealInterval, AffineGet > > views = new ArrayList<Pair<RealInterval, AffineGet>>();
	views.add( new ValuePair< RealInterval, AffineGet >( a, t1 ) );
	views.add( new ValuePair< RealInterval, AffineGet >( b, t2 ) );

	RealInterval overlap = BoundingBoxMaximalGroupOverlap.getMinBoundingIntervalSingle( views );

	final RealInterval transformed1 = TransformTools.applyTranslation( a, t1, new boolean[] {false, false, false} );
	final RealInterval transformed2 = TransformTools.applyTranslation( b, t2, new boolean[] {false, false, false} );

	// get overlap in images' coordinates
	final RealInterval localOverlap1 = TransformTools.getLocalOverlap( transformed1, overlap );
	final RealInterval localOverlap2 = TransformTools.getLocalOverlap( transformed2, overlap );

	// round to integer interval
	final Interval interval1 = TransformTools.getLocalRasterOverlap( localOverlap1 );
	final Interval interval2 = TransformTools.getLocalRasterOverlap( localOverlap2 );

	//final WarpFunction warp = new TranslationWarp(3);
	final WarpFunction warp = new RigidWarp(3);
	//final WarpFunction warp = new AffineWarp( 3 );

	// rotate second image
	AffineTransform3D rot = new AffineTransform3D();
	rot.rotate( 2, 2 * Math.PI / 180 );
	RandomAccessibleInterval< FloatType > rotated = Views.interval(
			RealViews.affine( 
					Views.interpolate( Views.extendBorder( Views.zeroMin( Views.interval( b, interval2 ) ) ), new NLinearInterpolatorFactory<>() ),
					rot.copy() ),
			interval2);

	// show input
	new ImageJ();
	ImageJFunctions.show( Views.interval( a,  interval1 ), "target" );
	ImageJFunctions.show( rotated, "in");

	// downsample input
	RandomAccessibleInterval< FloatType > simple2x1 = Downsample.simple2x( Views.zeroMin( Views.interval( a, interval1 ) ), new ArrayImgFactory<>(), new boolean[] {true, true, false} );
	RandomAccessibleInterval< FloatType > simple2x2 = Downsample.simple2x( Views.zeroMin( Views.interval( rotated, interval2 ) ), new ArrayImgFactory<>(), new boolean[] {true, true, false} );

	// align

	//Align< FloatType > lk = new Align<>( Views.zeroMin( Views.interval( a, interval1 ) ), new ArrayImgFactory<>(), warp );
	Align< FloatType > lk = new Align<>( simple2x1, new ArrayImgFactory<>(), warp );
	//System.out.println( Util.printCoordinates( lk.align( Views.zeroMin( Views.interval( b, interval2 ) ), 100, 0.01 ).getRowPackedCopy() ) );
	//final AffineTransform transform = lk.align( Views.zeroMin( rotated ), 100, 0.01 );
	final AffineTransform transform = lk.align( simple2x2, 100, 0.01 );

	final AffineTransform scale = new AffineTransform( 3 );
	scale.set( 2, 0, 0 );
	scale.set( 1, 1, 1 );

	transform.preConcatenate( scale );

	// transformation matrix
	System.out.println( Util.printCoordinates( transform.getRowPackedCopy() ) );

	// correct input and show
	RandomAccessibleInterval< FloatType > backRotated = Views.interval(
			RealViews.affine( 
					Views.interpolate( Views.extendBorder( Views.zeroMin( Views.interval( b, interval2 ) ) ), new NLinearInterpolatorFactory<>() ),
					rot.copy().preConcatenate( transform ).copy() ),
			interval2);

	ImageJFunctions.show( backRotated, "out" );

	// constructor needs column packed matrix, therefore the transpose
	Matrix mt = new Matrix( transform.getRowPackedCopy(), 4).transpose();
	Matrix rigid = mt.getMatrix( 0, 2, 0, 2 );

	// check whether result is rotation matrix (det == +-1, orthogonal)
	System.out.println( rigid.det() );
	System.out.println( Util.printCoordinates( rigid.times( rigid.transpose() ).getRowPackedCopy() ) );
}
 
示例26
public static < T extends RealType< T > > Pair<Pair< AffineGet, Double >, RealInterval> computeStitchingNonEqualTransformations(
		final Group<? extends ViewId> viewIdsA,
		final Group<? extends ViewId> viewIdsB,
		final ViewRegistrations vrs,
		final PairwiseStitchingParameters params,
		final AbstractSequenceDescription< ?,? extends BasicViewDescription<?>, ? > sd,
		final GroupedViewAggregator gva,
		final long[] downsampleFactors,
		final ExecutorService service )
{

	final double[] downsampleDbl = new double[downsampleFactors.length];
	for (int d = 0; d < downsampleFactors.length; d++)
		downsampleDbl[d] = downsampleFactors[d];

	// get Overlap Bounding Box
	final List<List<ViewId>> views = new ArrayList<>();
	views.add( new ArrayList<>(viewIdsA.getViews()) );
	views.add( new ArrayList<>(viewIdsB.getViews()) );
	BoundingBoxMaximalGroupOverlap< ViewId > bbDet = new BoundingBoxMaximalGroupOverlap<ViewId>( views, sd, vrs );
	BoundingBox bbOverlap = bbDet.estimate( "Max Overlap" );

	// we could not find overlap -> ignore this pair
	if (bbOverlap == null)
		return null;

	List<RandomAccessibleInterval< FloatType >> raiOverlaps = new ArrayList<>();		
	for (List< ViewId > tileViews : views)
	{
		// wrap every view id (corresponding e.g. to different channels, illums,.. ) in list
		List<List< ViewId >> wrapped = tileViews.stream().map( v -> {
			ArrayList< ViewId > wrp = new ArrayList<ViewId>();
			wrp.add( v );
			return wrp;} ).collect( Collectors.toList() );

		// open all of them "virtually fused"
		List< RandomAccessibleInterval< FloatType > > openFused = 
				DisplayOverlapTestPopup.openVirtuallyFused( sd, vrs, wrapped, bbOverlap, downsampleDbl );

		// aggregate the group into one image
		RandomAccessibleInterval< FloatType > raiI = gva.aggregate( 
				openFused, 
				tileViews,
				sd );

		raiOverlaps.add(raiI);
	}

	// the overlap in both images
	final RandomAccessibleInterval< FloatType > img1 = raiOverlaps.get(0);
	final RandomAccessibleInterval< FloatType > img2 = raiOverlaps.get(1);
	
	// compute phase correlation shift (passing (0,0,..) translations prevents any overlap correction inside)
	final Pair< Translation, Double > result = PairwiseStitching.getShift(
			img1,
			img2,
			new Translation( img1.numDimensions() ),
			new Translation( img1.numDimensions() ),
			params,
			service );

	if (result == null)
		return null;

	for (int i = 0; i< result.getA().numDimensions(); ++i)			
		result.getA().set( result.getA().get(i, result.getA().numDimensions()) * downsampleFactors[i], i ); 

	// TODO (?): Different translational part of downsample Transformations should be considered via TransformTools.getInitialTransforms
	// we probalbly do not have to correct for them ?
	final AffineTransform3D vr = vrs.getViewRegistration(viewIdsB.iterator().next()).getModel();		
	final AffineTransform resCorrected = new AffineTransform( result.getA().numDimensions() );
	resCorrected.set( result.getA() );

	System.out.println("shift: " + Util.printCoordinates(result.getA().getTranslationCopy()));
	System.out.print("cross-corr: " + result.getB());

	return new ValuePair<>( new ValuePair<>( resCorrected, result.getB() ), bbOverlap );
}
 
示例27
public static < T extends RealType< T > > Pair<Pair< AffineGet, Double >, RealInterval> computeStitchingNonEqualTransformationsLucasKanade(
		final Group<? extends ViewId> viewIdsA,
		final Group<? extends ViewId> viewIdsB,
		final ViewRegistrations vrs,
		final LucasKanadeParameters params,
		final AbstractSequenceDescription< ?,? extends BasicViewDescription<?>, ? > sd,
		final GroupedViewAggregator gva,
		final long[] downsampleFactors,
		final ExecutorService service )
{
	final double[] downsampleDbl = new double[downsampleFactors.length];
	for (int d = 0; d < downsampleFactors.length; d++)
		downsampleDbl[d] = downsampleFactors[d];

	// get Overlap Bounding Box
	final List<List<ViewId>> views = new ArrayList<>();
	views.add( new ArrayList<>(viewIdsA.getViews()) );
	views.add( new ArrayList<>(viewIdsB.getViews()) );
	BoundingBoxMaximalGroupOverlap< ViewId > bbDet = new BoundingBoxMaximalGroupOverlap<ViewId>( views, sd, vrs );
	BoundingBox bbOverlap = bbDet.estimate( "Max Overlap" );

	// we could not find overlap -> ignore this pair
	if (bbOverlap == null)
		return null;

	List<RandomAccessibleInterval< FloatType >> raiOverlaps = new ArrayList<>();		
	for (List< ViewId > tileViews : views)
	{
		// wrap every view id (corresponding e.g. to different channels, illums,.. ) in list
		List<List< ViewId >> wrapped = tileViews.stream().map( v -> {
			ArrayList< ViewId > wrp = new ArrayList<ViewId>();
			wrp.add( v );
			return wrp;} ).collect( Collectors.toList() );

		// open all of them "virtually fused"
		List< RandomAccessibleInterval< FloatType > > openFused = 
				DisplayOverlapTestPopup.openVirtuallyFused( sd, vrs, wrapped, bbOverlap, downsampleDbl );

		// aggregate the group into one image
		RandomAccessibleInterval< FloatType > raiI = gva.aggregate( 
				openFused, 
				tileViews,
				sd );

		raiOverlaps.add(raiI);
	}

	// the overlap in both images
	final RandomAccessibleInterval< FloatType > img1 = raiOverlaps.get(0);
	final RandomAccessibleInterval< FloatType > img2 = raiOverlaps.get(1);
	
	// compute phase correlation shift (passing (0,0,..) translations prevents any overlap correction inside)
	final Pair< AffineTransform, Double > result = PairwiseStitching.getShiftLucasKanade(
			img1,
			img2,
			new Translation( img1.numDimensions() ),
			new Translation( img1.numDimensions() ),
			params,
			service );

	if (result == null)
		return null;

	// scale just the translational part
	for (int i = 0; i< result.getA().numDimensions(); ++i)			
		result.getA().set( result.getA().get(i, result.getA().numDimensions()) * downsampleFactors[i], i ); 

	// TODO (?): Different translational part of downsample Transformations should be considered via TransformTools.getInitialTransforms
	// we probalbly do not have to correct for them ?

	final AffineTransform3D vr = vrs.getViewRegistration(viewIdsB.iterator().next()).getModel();		
	final AffineTransform resCorrected = new AffineTransform( result.getA().numDimensions() );
	resCorrected.set( result.getA() );

	IOFunctions.println("resulting transformation: " + Util.printCoordinates(result.getA().getRowPackedCopy()));

	return new ValuePair<>( new ValuePair<>( resCorrected, result.getB() ), bbOverlap );
}
 
示例28
public static < T extends RealType< T > > Pair<Pair< AffineGet, Double >, RealInterval> computeStitching(
		final Group<? extends ViewId> viewIdsA,
		final Group<? extends ViewId> viewIdsB,
		final ViewRegistrations vrs,
		final PairwiseStitchingParameters params,
		final AbstractSequenceDescription< ?,? extends BasicViewDescription<?>, ? > sd,
		final GroupedViewAggregator gva,
		final long[] downsampleFactors,
		final ExecutorService service )
{

	// the transformation that maps the downsampled image coordinates back to the original input(!) image space
	final AffineTransform3D dsCorrectionT1 = new AffineTransform3D();
	final AffineTransform3D dsCorrectionT2 = new AffineTransform3D();

	// get Overlap Bounding Box
	final List<List<ViewId>> views = new ArrayList<>();
	views.add( new ArrayList<>(viewIdsA.getViews()) );
	views.add( new ArrayList<>(viewIdsB.getViews()) );
	BoundingBoxMaximalGroupOverlap< ViewId > bbDet = new BoundingBoxMaximalGroupOverlap<ViewId>( views, sd, vrs );
	BoundingBox bbOverlap = bbDet.estimate( "Max Overlap" );

	// this should be caught outside of this method already, but check nonetheless
	if (bbOverlap == null)
		return null;

	// get one image per group
	final RandomAccessibleInterval<T> img1 = gva.aggregate( viewIdsA, sd, downsampleFactors, dsCorrectionT1 );	
	final RandomAccessibleInterval<T> img2 = gva.aggregate( viewIdsB, sd, downsampleFactors, dsCorrectionT2 );

	if (img1 == null || img2 == null)
	{
		IOFunctions.println( "WARNING: Tried to open missing View when computing Stitching for " + viewIdsA + " and " + 
					viewIdsB + ". No link between those could be determined");
		return null;
	}

	// get translations
	// TODO: is the 2d check here meaningful?
	// everything will probably be 3d at this point, since ImgLoaders return 3d images
	boolean is2d = img1.numDimensions() == 2;
	Pair< AffineGet, TranslationGet > t1 = TransformTools.getInitialTransforms( vrs.getViewRegistration(viewIdsA.iterator().next()), is2d, dsCorrectionT1 );
	Pair< AffineGet, TranslationGet > t2 = TransformTools.getInitialTransforms( vrs.getViewRegistration(viewIdsB.iterator().next()), is2d, dsCorrectionT2 );

	final Pair< Translation, Double > result  = PairwiseStitching.getShift( img1, img2, t1.getB(), t2.getB(), params, service );

	if (result == null)
		return null;
	
	for (int i = 0; i< result.getA().numDimensions(); ++i)			
		result.getA().set( result.getA().get(i, result.getA().numDimensions()) * downsampleFactors[i], i ); 

	// TODO (?): Different translational part of downsample Transformations should be considered via TransformTools.getInitialTransforms
	// we probalbly do not have to correct for them ?

	// NB: as we will deal in global coordinates, not pixel coordinates in global optimization,
	// calculate global R' = VT^-1 * R * VT from pixel transformation R 
	ViewRegistration vrOld = vrs.getViewRegistration(viewIdsB.iterator().next());
	AffineTransform3D resTransform = new AffineTransform3D();
	resTransform.set( result.getA().getRowPackedCopy() );
	resTransform.concatenate( vrOld.getModel().inverse() );
	resTransform.preConcatenate( vrOld.getModel() );

	System.out.println("shift (pixel coordinates): " + Util.printCoordinates(result.getA().getTranslationCopy()));
	System.out.println("shift (global coordinates): " + Util.printCoordinates(resTransform.getRowPackedCopy()));
	System.out.print("cross-corr: " + result.getB());

	return new ValuePair<>( new ValuePair<>( resTransform, result.getB() ), bbOverlap );
}
 
示例29
public static < T extends RealType< T > > Pair<Pair< AffineGet, Double >, RealInterval> computeStitchingLucasKanade(
		final Group<? extends ViewId> viewIdsA,
		final Group<? extends ViewId> viewIdsB,
		final ViewRegistrations vrs,
		final LucasKanadeParameters params,
		final AbstractSequenceDescription< ?,? extends BasicViewDescription<?>, ? > sd,
		final GroupedViewAggregator gva,
		final long[] downsampleFactors,
		final ExecutorService service )
{
	
	// the transformation that maps the downsampled image coordinates back to the original input(!) image space
	final AffineTransform3D dsCorrectionT1 = new AffineTransform3D();
	final AffineTransform3D dsCorrectionT2 = new AffineTransform3D();

	// get Overlap Bounding Box
	final List<List<ViewId>> views = new ArrayList<>();
	views.add( new ArrayList<>(viewIdsA.getViews()) );
	views.add( new ArrayList<>(viewIdsB.getViews()) );
	BoundingBoxMaximalGroupOverlap< ViewId > bbDet = new BoundingBoxMaximalGroupOverlap<ViewId>( views, sd, vrs );
	BoundingBox bbOverlap = bbDet.estimate( "Max Overlap" );

	// this should be caught outside of this method already, but check nonetheless
	if (bbOverlap == null)
		return null;

	// get one image per group
	final RandomAccessibleInterval<T> img1 = gva.aggregate( viewIdsA, sd, downsampleFactors, dsCorrectionT1 );	
	final RandomAccessibleInterval<T> img2 = gva.aggregate( viewIdsB, sd, downsampleFactors, dsCorrectionT2 );

	if (img1 == null || img2 == null)
	{
		IOFunctions.println( "WARNING: Tried to open missing View when computing Stitching for " + viewIdsA + " and " + 
					viewIdsB + ". No link between those could be determined");
		return null;
	}

	// get translations
	// TODO: is the 2d check here meaningful?
	boolean is2d = img1.numDimensions() == 2;
	Pair< AffineGet, TranslationGet > t1 = TransformTools.getInitialTransforms( vrs.getViewRegistration(viewIdsA.iterator().next()), is2d, dsCorrectionT1 );
	Pair< AffineGet, TranslationGet > t2 = TransformTools.getInitialTransforms( vrs.getViewRegistration(viewIdsB.iterator().next()), is2d, dsCorrectionT2 );

	final Pair< AffineTransform, Double > result  = PairwiseStitching.getShiftLucasKanade(  img1, img2, t1.getB(), t2.getB(), params, service );

	if (result == null)
		return null;

	// TODO: is scaling just the translational part okay here?
	for (int i = 0; i< result.getA().numDimensions(); ++i)			
		result.getA().set( result.getA().get(i, result.getA().numDimensions()) * downsampleFactors[i], i, result.getA().numDimensions() ); 

	// TODO (?): Different translational part of downsample Transformations should be considered via TransformTools.getInitialTransforms
	// we probalbly do not have to correct for them ?

	// NB: as we will deal in global coordinates, not pixel coordinates in global optimization,
	// calculate global R' = VT^-1 * R * VT from pixel transformation R 
	ViewRegistration vrOld = vrs.getViewRegistration(viewIdsB.iterator().next());
	AffineTransform3D resTransform = new AffineTransform3D();
	resTransform.set( result.getA().getRowPackedCopy() );
	resTransform.concatenate( vrOld.getModel().inverse() );
	resTransform.preConcatenate( vrOld.getModel() );

	IOFunctions.println("resulting transformation (pixel coordinates): " + Util.printCoordinates(result.getA().getRowPackedCopy()));
	IOFunctions.println("resulting transformation (global coordinates): " + Util.printCoordinates(resTransform.getRowPackedCopy()));

	return new ValuePair<>( new ValuePair<>( resTransform, result.getB() ), bbOverlap );
}
 
示例30
@Override
public JuliaRealRandomAccess realRandomAccess( final RealInterval interval )
{
	return realRandomAccess();
}