net.imglib2.converter.Converters Java Examples

The following examples show how to use net.imglib2.converter.Converters. 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: MaskedSource.java    From paintera with GNU General Public License v2.0 6 votes vote down vote up
private void setAtMaskLevel(
		final RealRandomAccessible<UnsignedLongType> mask,
		final RealRandomAccessible<VolatileUnsignedLongType> vmask,
		final int maskLevel,
		final UnsignedLongType value,
		final Predicate<UnsignedLongType> isPaintedForeground)
{

	this.dMasks[maskLevel] = Converters.convert(
			mask,
			(input, output) -> output.set(isPaintedForeground.test(input) ? value : INVALID),
			new UnsignedLongType());

	this.tMasks[maskLevel] = Converters.convert(
			vmask,
			(input, output) -> {
				final boolean isValid = input.isValid();
				output.setValid(isValid);
				if (isValid)
				{
					output.get().set(input.get().get() > 0 ? value : INVALID);
				}
			},
			new VolatileUnsignedLongType());
}
 
Example #2
Source File: N5ChannelDataSource.java    From paintera with GNU General Public License v2.0 6 votes vote down vote up
private static <D extends NativeType<D> & RealType<D>, T extends RealType<T>> RealComposite<T>  createExtension(
		final D d,
		final T t,
		final Converter<D, T> converter,
		final long size,
		IntFunction<D> valueAtIndex
)
{
	LOG.debug("Creating extension with size {}", size);
	final ArrayImg<D, ?> img = new ArrayImgFactory<>(d).create(1, size);
	img.setLinkedType((D) d.getNativeTypeFactory().createLinkedType((NativeImg)img));
	final CompositeIntervalView<D, RealComposite<D>> collapsed = Views.collapseReal(img);
	RealComposite<D> extensionCopy = collapsed.randomAccess().get();
	for (int channel = 0; channel < size; ++channel)
		extensionCopy.get(channel).set(valueAtIndex.apply(channel));
	return Views.collapseReal(Converters.convert((RandomAccessibleInterval<D>)img, converter, t.createVariable())).randomAccess().get();
}
 
Example #3
Source File: CommitCanvasN5.java    From paintera with GNU General Public License v2.0 6 votes vote down vote up
private static <I extends IntegerType<I> & NativeType<I>> void writeBlocksLabelIntegerType(
		final RandomAccessibleInterval<UnsignedLongType> canvas,
		final long[] blocks,
		final DatasetSpec datasetSpec,
		final BlockSpec blockSpec,
		final TLongObjectHashMap<BlockDiff> blockDiff) throws IOException {
	final RandomAccessibleInterval<I> highestResolutionData = N5Utils.open(datasetSpec.container, datasetSpec.dataset);
	final I i = Util.getTypeFromInterval(highestResolutionData).createVariable();
	for (final long blockId : blocks) {
		blockSpec.fromLinearIndex(blockId);
		final RandomAccessibleInterval<Pair<I, UnsignedLongType>> backgroundWithCanvas = Views.interval(Views.pair(highestResolutionData, canvas), blockSpec.asInterval());
		final RandomAccessibleInterval<I> mergedData = Converters.convert(backgroundWithCanvas, (s, t) -> pickFirstIfSecondIsInvalid(s.getA(), s.getB(), t), i.createVariable());
		N5Utils.saveBlock(mergedData, datasetSpec.container, datasetSpec.dataset, datasetSpec.attributes, blockSpec.pos);
		blockDiff.put(blockId, createBlockDiffFromCanvasIntegerType(Views.iterable(backgroundWithCanvas)));
	}
}
 
Example #4
Source File: ShapeInterpolationMode.java    From paintera with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Flood-fills the mask using the background value to remove the object from the selection.
 *
 * @param x
 * @param y
 * @return the fill value of the deselected object
 */
private long runFloodFillToDeselect(final double x, final double y)
{
	// set the predicate to accept only the fill value at the clicked location to avoid deselecting adjacent objects.
	final long maskValue = getMaskValue(x, y).get();
	final RandomAccessibleInterval<BoolType> predicate = Converters.convert(
			mask.mask,
			(in, out) -> out.set(in.getIntegerLong() == maskValue),
			new BoolType()
		);
	final double fillDepth = determineFillDepth();
	LOG.debug("Flood-filling to deselect object: old value={}, depth={}", maskValue, fillDepth);
	FloodFill2D.fillMaskAt(x, y, activeViewer, mask, predicate, getMaskTransform(), Label.BACKGROUND, determineFillDepth());
	return maskValue;
}
 
Example #5
Source File: N5FragmentSegmentAssignmentInitialLut.java    From paintera with GNU General Public License v2.0 5 votes vote down vote up
private static <T extends IntegerType<T> & NativeType<T>> RandomAccessibleInterval<UnsignedLongType> openAnyIntegerTypeAsUnsignedLongType(
		final N5Reader reader,
		final String dataset
) throws IOException {
	final RandomAccessibleInterval<T> img = N5Utils.open(reader, dataset);
	return Converters.convert(img, (s, t) -> t.setInteger(s.getIntegerLong()), new UnsignedLongType());
}
 
Example #6
Source File: AbstractMeshCacheLoader.java    From paintera with GNU General Public License v2.0 5 votes vote down vote up
@Override
public Pair<float[], float[]> get(final ShapeKey<K> key) throws Exception
{

	//		if ( key.meshSimplificationIterations() > 0 )
	//		{
	// TODO deal with mesh simplification
	//		}

	LOG.debug("key={}, getMaskGenerator={}", key, getMaskGenerator);
	final RandomAccessibleInterval<BoolType> mask = Converters.convert(
			data.get(),
			getMaskGenerator.apply(key.shapeId(), key.minLabelRatio()),
			new BoolType(false)
		);

	final float[] mesh = new MarchingCubes<>(
			Views.extendZero(mask),
			key.interval(),
			transform).generateMesh();
	final float[] normals = new float[mesh.length];
	if (key.smoothingIterations() > 0)
	{
		final float[] smoothMesh = Smooth.smooth(mesh, key.smoothingLambda(), key.smoothingIterations());
		System.arraycopy(smoothMesh, 0, mesh, 0, mesh.length);
	}
	Normals.normals(mesh, normals);
	AverageNormals.averagedNormals(mesh, normals);

	for (int i = 0; i < normals.length; ++i)
		normals[i] *= -1;

	return new ValuePair<>(mesh, normals);
}
 
Example #7
Source File: MaskedSource.java    From paintera with GNU General Public License v2.0 5 votes vote down vote up
public RandomAccessibleInterval<D> getReadOnlyDataBackground(final int t, final int level)
{
	return Converters.convert(
			this.source.getDataSource(t, level),
			new TypeIdentity<>(),
			this.source.getDataType().createVariable()
	                         );
}
 
Example #8
Source File: MaskedSource.java    From paintera with GNU General Public License v2.0 5 votes vote down vote up
public RandomAccessibleInterval<UnsignedLongType> getReadOnlyDataCanvas(final int t, final int level)
{
	return Converters.convert(
			(RandomAccessibleInterval<UnsignedLongType>) this.dataCanvases[level],
			new TypeIdentity<>(),
			new UnsignedLongType()
	                         );
}
 
Example #9
Source File: FloodFill2D.java    From paintera with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Flood-fills the given mask starting at the specified 2D location in the viewer.
 * Returns the affected interval in source coordinates.
 *
 * @param x
 * @param y
 * @param viewer
 * @param mask
 * @param source
 * @param assignment
 * @param fillValue
 * @param fillDepth
 * @return affected interval
 */
public static <T extends IntegerType<T>> Interval fillMaskAt(
		final double x,
		final double y,
		final ViewerPanelFX viewer,
		final Mask<UnsignedLongType> mask,
		final MaskedSource<T, ?> source,
		final FragmentSegmentAssignment assignment,
		final long fillValue,
		final double fillDepth)
{
	final int time = mask.info.t;
	final int level = mask.info.level;

	final AffineTransform3D labelTransform = new AffineTransform3D();
	source.getSourceTransform(time, level, labelTransform);

	final RandomAccessibleInterval<T> background = source.getDataSource(time, level);
	final RandomAccess<T> access = background.randomAccess();
	final RealPoint pos = new RealPoint(access.numDimensions());
	viewer.displayToSourceCoordinates(x, y, labelTransform, pos);
	for (int d = 0; d < access.numDimensions(); ++d)
		access.setPosition(Math.round(pos.getDoublePosition(d)), d);
	final long seedLabel = assignment != null ? assignment.getSegment(access.get().getIntegerLong()) : access.get().getIntegerLong();
	LOG.debug("Got seed label {}", seedLabel);
	final RandomAccessibleInterval<BoolType> relevantBackground = Converters.convert(
			background,
			(src, tgt) -> tgt.set((assignment != null ? assignment.getSegment(src.getIntegerLong()) : src.getIntegerLong()) == seedLabel),
			new BoolType()
		);

	return fillMaskAt(x, y, viewer, mask, relevantBackground, labelTransform, fillValue, fillDepth);
}
 
Example #10
Source File: ShapeInterpolationMode.java    From paintera with GNU General Public License v2.0 5 votes vote down vote up
private static <R extends RealType<R>, T extends NativeType<T> & RealType<T>> RealRandomAccessible<T> getInterpolatedDistanceTransformMask(
		final RandomAccessibleInterval<R> dt1,
		final RandomAccessibleInterval<R> dt2,
		final double distance,
		final T targetValue,
		final AffineTransform3D transformToSource)
{
	final RandomAccessibleInterval<R> distanceTransformStack = Views.stack(dt1, dt2);

	final R extendValue = Util.getTypeFromInterval(distanceTransformStack).createVariable();
	extendValue.setReal(extendValue.getMaxValue());
	final RealRandomAccessible<R> interpolatedDistanceTransform = Views.interpolate(
			Views.extendValue(distanceTransformStack, extendValue),
			new NLinearInterpolatorFactory<>()
		);

	final RealRandomAccessible<R> scaledInterpolatedDistanceTransform = RealViews.affineReal(
			interpolatedDistanceTransform,
			new Scale3D(1, 1, -distance)
		);

	final T emptyValue = targetValue.createVariable();
	final RealRandomAccessible<T> interpolatedShape = Converters.convert(
			scaledInterpolatedDistanceTransform,
			(in, out) -> out.set(in.getRealDouble() <= 0 ? targetValue : emptyValue),
			emptyValue.createVariable()
		);

	return RealViews.affineReal(interpolatedShape, transformToSource);
}
 
Example #11
Source File: MaskedSource.java    From paintera with GNU General Public License v2.0 4 votes vote down vote up
public void applyMask(
		final Mask<UnsignedLongType> mask,
		final Interval paintedInterval,
		final Predicate<UnsignedLongType> acceptAsPainted)
{
	if (mask == null)
		return;
	new Thread(() -> {
		Thread.currentThread().setName("apply mask");
		synchronized (this)
		{
			final boolean maskCanBeApplied = !this.isCreatingMask && this.currentMask == mask && !this.isApplyingMask.get() && !this.isPersisting;
			if (!maskCanBeApplied)
			{
				LOG.debug("Did not pass valid mask {}, will not do anything", mask);
				return;
			}
			this.isApplyingMask.set(true);
		}

		LOG.debug("Applying mask: {}", mask, paintedInterval);
		final MaskInfo<UnsignedLongType> maskInfo = mask.info;
		final CachedCellImg<UnsignedLongType, ?> canvas = dataCanvases[maskInfo.level];
		final CellGrid                           grid   = canvas.getCellGrid();

		final int[] blockSize = new int[grid.numDimensions()];
		grid.cellDimensions(blockSize);

		final TLongSet affectedBlocks = affectedBlocks(mask.mask, canvas.getCellGrid(), paintedInterval);

		paintAffectedPixels(
				affectedBlocks,
				Converters.convert(
						Views.extendZero(mask.mask),
						(s, t) -> t.set(acceptAsPainted.test(s)),
						new BitType()),
				canvas,
				maskInfo.value,
				canvas.getCellGrid(),
				paintedInterval);

		final Mask<UnsignedLongType> currentMaskBeforePropagation = this.currentMask;
		synchronized (this)
		{
			this.currentMask = null;
		}

		final TLongSet paintedBlocksAtHighestResolution = this.scaleBlocksToLevel(
				affectedBlocks,
				maskInfo.level,
				0);

		this.affectedBlocksByLabel[maskInfo.level].computeIfAbsent(
				maskInfo.value.getIntegerLong(),
				key -> new TLongHashSet()
		                                                          ).addAll(affectedBlocks);
		LOG.debug("Added affected block: {}", affectedBlocksByLabel[maskInfo.level]);
		this.affectedBlocks.addAll(paintedBlocksAtHighestResolution);

		propagationExecutor.submit(() -> {
			try {
				propagateMask(
						mask.mask,
						affectedBlocks,
						maskInfo.level,
						maskInfo.value,
						paintedInterval,
						acceptAsPainted);
				setMasksConstant();
				synchronized (this) {
					LOG.debug("Done applying mask!");
					this.isApplyingMask.set(false);
				}
			} finally {
				// free resources
				if (currentMaskBeforePropagation != null) {
					if (currentMaskBeforePropagation.shutdown != null)
						currentMaskBeforePropagation.shutdown.run();
					if (currentMaskBeforePropagation.invalidate != null)
						currentMaskBeforePropagation.invalidate.invalidateAll();
					if (currentMaskBeforePropagation.invalidateVolatile != null)
						currentMaskBeforePropagation.invalidateVolatile.invalidateAll();
				}
			}
		});

	}).start();

}
 
Example #12
Source File: N5ChannelDataSource.java    From paintera with GNU General Public License v2.0 4 votes vote down vote up
@Override
public RealRandomAccessible<VolatileWithSet<RealComposite<T>>> getInterpolatedSource(int t, int level, Interpolation method) {
	final RealRandomAccessible<RealComposite<T>> interpolated = Views.interpolate(viewerData[level], viewerInterpolation.apply(method));
	return Converters.convert(interpolated, viewerConverter, new VolatileWithSet<>(null, true));
}
 
Example #13
Source File: N5ChannelDataSource.java    From paintera with GNU General Public License v2.0 4 votes vote down vote up
@Override
public RandomAccessibleInterval<VolatileWithSet<RealComposite<T>>> getSource(int t, int level) {
	VolatileWithSet<RealComposite<T>> var = new VolatileWithSet<>(null, true);
	return Converters.convert((RandomAccessibleInterval<RealComposite<T>>)Views.interval(viewerData[level], intervals[level]), viewerConverter, var);
}
 
Example #14
Source File: LabelSourceState.java    From paintera with GNU General Public License v2.0 4 votes vote down vote up
public static <D extends IntegerType<D> & NativeType<D>, T extends Volatile<D> & IntegerType<T>>
LabelSourceState<D, T> simpleSourceFromSingleRAI(
		final RandomAccessibleInterval<D> data,
		final double[] resolution,
		final double[] offset,
		final Invalidate<Long> invalidate,
		final long maxId,
		final String name,
		final LabelBlockLookup labelBlockLookup,
		final Group meshesGroup,
		final ObjectProperty<ViewFrustum> viewFrustumProperty,
		final ObjectProperty<AffineTransform3D> eyeToWorldTransformProperty,
		final ExecutorService meshManagerExecutors,
		final HashPriorityQueueBasedTaskExecutor<MeshWorkerPriority> meshWorkersExecutors) {

	if (!Views.isZeroMin(data))
	{
		return simpleSourceFromSingleRAI(
				Views.zeroMin(data),
				resolution,
				offset,
				invalidate,
				maxId,
				name,
				labelBlockLookup,
				meshesGroup,
				viewFrustumProperty,
				eyeToWorldTransformProperty,
				meshManagerExecutors,
				meshWorkersExecutors
			);
	}

	final AffineTransform3D mipmapTransform = new AffineTransform3D();
	mipmapTransform.set(
			resolution[0], 0, 0, offset[0],
			0, resolution[1], 0, offset[1],
			0, 0, resolution[2], offset[2]
	                   );

	final T vt = (T) VolatileTypeMatcher.getVolatileTypeForType(Util.getTypeFromInterval(data)).createVariable();
	vt.setValid(true);
	final RandomAccessibleInterval<T> vdata = Converters.convert(data, (s, t) -> t.get().set(s), vt);

	final RandomAccessibleIntervalDataSource<D, T> dataSource = new RandomAccessibleIntervalDataSource<>(
			data,
			vdata,
			mipmapTransform,
			invalidate,
			i -> new NearestNeighborInterpolatorFactory<>(),
			i -> new NearestNeighborInterpolatorFactory<>(),
			name);

	final SelectedIds                        selectedIds    = new SelectedIds();
	final FragmentSegmentAssignmentOnlyLocal assignment     = new FragmentSegmentAssignmentOnlyLocal(new FragmentSegmentAssignmentOnlyLocal.DoesNotPersist());
	final SelectedSegments selectedSegments = new SelectedSegments(selectedIds, assignment);
	final LockedSegmentsOnlyLocal            lockedSegments = new LockedSegmentsOnlyLocal(seg -> {});
	final ModalGoldenAngleSaturatedHighlightingARGBStream stream = new
			ModalGoldenAngleSaturatedHighlightingARGBStream(
			selectedSegments,
			lockedSegments);

	final MeshManagerWithAssignmentForSegments meshManager = MeshManagerWithAssignmentForSegments.fromBlockLookup(
			dataSource,
			selectedSegments,
			stream,
			viewFrustumProperty,
			eyeToWorldTransformProperty,
			labelBlockLookup,
			meshManagerExecutors,
			meshWorkersExecutors);

	return new LabelSourceState<>(
			dataSource,
			new HighlightingStreamConverterIntegerType<>(stream),
			new ARGBCompositeAlphaYCbCr(),
			name,
			assignment,
			lockedSegments,
			new LocalIdService(maxId),
			selectedIds,
			meshManager,
			labelBlockLookup
	);
}
 
Example #15
Source File: RawSourceState.java    From paintera with GNU General Public License v2.0 4 votes vote down vote up
public static <D extends RealType<D> & NativeType<D>, T extends AbstractVolatileNativeRealType<D, T>>
RawSourceState<D, T> simpleSourceFromSingleRAI(
		final RandomAccessibleInterval<D> data,
		final double[] resolution,
		final double[] offset,
		final Invalidate<Long> invalidate,
		final double min,
		final double max,
		final String name) {

	if (!Views.isZeroMin(data))
	{
		return simpleSourceFromSingleRAI(Views.zeroMin(data), resolution, offset, invalidate, min, max, name);
	}

	final AffineTransform3D mipmapTransform = new AffineTransform3D();
	mipmapTransform.set(
			resolution[0], 0, 0, offset[0],
			0, resolution[1], 0, offset[1],
			0, 0, resolution[2], offset[2]
	                   );

	@SuppressWarnings("unchecked") final T vt = (T) VolatileTypeMatcher.getVolatileTypeForType(Util
			.getTypeFromInterval(
			data)).createVariable();
	vt.setValid(true);
	final RandomAccessibleInterval<T> vdata = Converters.convert(data, (s, t) -> t.get().set(s), vt);

	final RandomAccessibleIntervalDataSource<D, T> dataSource = new RandomAccessibleIntervalDataSource<>(
			data,
			vdata,
			mipmapTransform,
			invalidate,
			i -> new NearestNeighborInterpolatorFactory<>(),
			i -> new NearestNeighborInterpolatorFactory<>(),
			name
	);

	return new RawSourceState<>(
			dataSource,
			new ARGBColorConverter.InvertingImp0<>(min, max),
			new CompositeCopy<>(),
			name
	);

}
 
Example #16
Source File: HistogramOfOrientedGradients2D.java    From imagej-ops with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@SuppressWarnings("unchecked")
@Override
public void compute(RandomAccessibleInterval<T> in, RandomAccessibleInterval<T> out) {
	final RandomAccessible<FloatType> convertedIn = Converters.convert(Views.extendMirrorDouble(in),
			converterToFloat, new FloatType());

	// compute partial derivative for each dimension
	RandomAccessibleInterval<FloatType> derivative0 = createImgOp.calculate();
	RandomAccessibleInterval<FloatType> derivative1 = createImgOp.calculate();

	// case of grayscale image
	if (in.numDimensions() == 2) {
		PartialDerivative.gradientCentralDifference(convertedIn, derivative0, 0);
		PartialDerivative.gradientCentralDifference(convertedIn, derivative1, 1);
	}
	// case of color image
	else {
		List<RandomAccessibleInterval<FloatType>> listDerivs0 = new ArrayList<>();
		List<RandomAccessibleInterval<FloatType>> listDerivs1 = new ArrayList<>();
		for (int i = 0; i < in.dimension(2); i++) {
			final RandomAccessibleInterval<FloatType> deriv0 = createImgOp.calculate();
			final RandomAccessibleInterval<FloatType> deriv1 = createImgOp.calculate();
			PartialDerivative.gradientCentralDifference(
					Views.interval(convertedIn, new long[] { 0, 0, i }, new long[] { in.max(0), in.max(1), i }),
					deriv0, 0);
			PartialDerivative.gradientCentralDifference(
					Views.interval(convertedIn, new long[] { 0, 0, i }, new long[] { in.max(0), in.max(1), i }),
					deriv1, 1);
			listDerivs0.add(deriv0);
			listDerivs1.add(deriv1);
		}
		derivative0 = Converters.convert(Views.collapse(Views.stack(listDerivs0)), converterGetMax,
				new FloatType());
		derivative1 = Converters.convert(Views.collapse(Views.stack(listDerivs1)), converterGetMax,
				new FloatType());
	}
	final RandomAccessibleInterval<FloatType> finalderivative0 = derivative0;
	final RandomAccessibleInterval<FloatType> finalderivative1 = derivative1;

	// compute angles and magnitudes
	final RandomAccessibleInterval<FloatType> angles = createImgOp.calculate();
	final RandomAccessibleInterval<FloatType> magnitudes = createImgOp.calculate();

	final CursorBasedChunk chunkable = new CursorBasedChunk() {

		@Override
		public void execute(long startIndex, long stepSize, long numSteps) {
			final Cursor<FloatType> cursorAngles = Views.flatIterable(angles).localizingCursor();
			final Cursor<FloatType> cursorMagnitudes = Views.flatIterable(magnitudes).localizingCursor();
			final Cursor<FloatType> cursorDerivative0 = Views.flatIterable(finalderivative0).localizingCursor();
			final Cursor<FloatType> cursorDerivative1 = Views.flatIterable(finalderivative1).localizingCursor();

			setToStart(cursorAngles, startIndex);
			setToStart(cursorMagnitudes, startIndex);
			setToStart(cursorDerivative0, startIndex);
			setToStart(cursorDerivative1, startIndex);

			for (long i = 0; i < numSteps; i++) {
				final float x = cursorDerivative0.get().getRealFloat();
				final float y = cursorDerivative1.get().getRealFloat();
				cursorAngles.get().setReal(getAngle(x, y));
				cursorMagnitudes.get().setReal(getMagnitude(x, y));

				cursorAngles.jumpFwd(stepSize);
				cursorMagnitudes.jumpFwd(stepSize);
				cursorDerivative0.jumpFwd(stepSize);
				cursorDerivative1.jumpFwd(stepSize);
			}
		}
	};

	ops().thread().chunker(chunkable, Views.flatIterable(magnitudes).size());

	// stores each Thread to execute
	final List<Callable<Void>> listCallables = new ArrayList<>();

	// compute descriptor (default 3x3, i.e. 9 channels: one channel for
	// each bin)
	final RectangleShape shape = new RectangleShape(spanOfNeighborhood, false);
	final NeighborhoodsAccessible<FloatType> neighborHood = shape.neighborhoodsRandomAccessible(angles);

	for (int i = 0; i < in.dimension(0); i++) {
		listCallables.add(new ComputeDescriptor(Views.interval(convertedIn, in), i, angles.randomAccess(),
				magnitudes.randomAccess(), (RandomAccess<FloatType>) out.randomAccess(),
				neighborHood.randomAccess()));
	}

	try {
		es.invokeAll(listCallables);
	} catch (final InterruptedException e) {
		throw new RuntimeException(e);
	}

	listCallables.clear();
}
 
Example #17
Source File: MandersColocalizationTest.java    From Colocalisation_Analysis with GNU General Public License v3.0 4 votes vote down vote up
/**
 * This method tests real experimental noisy but 
 * biologically perfectly colocalized test images, 
 * using previously calculated autothresholds (.above mode)
 * Amongst other things, hopefully it is sensitive to
 * choosing the wrong channel to test for above threshold
 */
@Test
public void mandersRealNoisyImagesTest() throws MissingPreconditionException {
	
	MandersColocalization<UnsignedByteType> mrnc = 
			new MandersColocalization<UnsignedByteType>();

	// test biologically perfect but noisy image coloc combination
	// this cast is bad, so use Views.iterable instead. 
	//Cursor<BitType> mask = Converters.convert((IterableInterval<UnsignedByteType>) positiveCorrelationMaskImage,
	Cursor<BitType> mask = Converters.convert(Views.iterable(positiveCorrelationMaskImage),
               new Converter<UnsignedByteType, BitType>() {

                   @Override
                   public void convert(UnsignedByteType arg0, BitType arg1) {
                       arg1.set(arg0.get() > 0);
                   }
               }, new BitType()).cursor();
	
	TwinCursor<UnsignedByteType> twinCursor;
	MandersResults r;
	// Manually set the thresholds for ch1 and ch2 with the results from a
	// Costes Autothreshold using bisection implementation of regression, of the images used
	UnsignedByteType thresholdCh1 = new UnsignedByteType();
	thresholdCh1.setInteger(70);
	UnsignedByteType thresholdCh2 = new UnsignedByteType();
	thresholdCh2.setInteger(53);
	//Set the threshold mode
	ThresholdMode tMode;
	tMode = ThresholdMode.Above;
	// Set the TwinCursor to have the mask image channel, and 2 images.
	twinCursor = new TwinCursor<UnsignedByteType>(
			positiveCorrelationImageCh1.randomAccess(),
			positiveCorrelationImageCh2.randomAccess(),
			mask);

	// Use the constructor that takes ch1 and ch2 autothresholds and threshold mode.
	r = mrnc.calculateMandersCorrelation(twinCursor, thresholdCh1, thresholdCh2, tMode);

	assertEquals(0.705665d, r.m1, 0.000001);
	assertEquals(0.724752d, r.m2, 0.000001);
}