/** Obtains planar access instance backing the given image, if any. */ @SuppressWarnings("unchecked") public static PlanarAccess<ArrayDataAccess<?>> getPlanarAccess(Image<?> im) { PlanarAccess<ArrayDataAccess<?>> planarAccess = null; final Container<?> container = im.getContainer(); if (container instanceof PlanarAccess<?>) { planarAccess = (PlanarAccess<ArrayDataAccess<?>>) container; } return planarAccess; }
@Override public boolean process() { final long startTime = System.currentTimeMillis(); final long imageSize = image.getNumPixels(); final AtomicInteger ai = new AtomicInteger(0); final Thread[] threads = SimpleMultiThreading.newThreads(getNumThreads()); final Vector<Chunk> threadChunks = SimpleMultiThreading.divideIntoChunks(imageSize, numThreads); final boolean isCompatible = image.getContainer().compareStorageContainerCompatibility(output.getContainer()); for (int ithread = 0; ithread < threads.length; ++ithread) threads[ithread] = new Thread( new Runnable() { public void run() { // Thread ID final int myNumber = ai.getAndIncrement(); // get chunk of pixels to process final Chunk myChunk = threadChunks.get(myNumber); // check if all container types are comparable so that we can use simple iterators // we assume transivity here if (isCompatible) { // we can simply use iterators computeSimple(myChunk.getStartPosition(), myChunk.getLoopSize()); } else { // we need a combination of Localizable and LocalizableByDim computeAdvanced(myChunk.getStartPosition(), myChunk.getLoopSize()); } } }); SimpleMultiThreading.startAndJoin(threads); processingTime = System.currentTimeMillis() - startTime; return true; }
@Override public boolean checkInput() { if (errorMessage.length() > 0) { return false; } else if (image == null) { errorMessage = "ImageCalculator: [Image<S> image1] is null."; return false; } else if (output == null) { errorMessage = "ImageCalculator: [Image<T> output] is null."; return false; } else if (converter == null) { errorMessage = "ImageCalculator: [Converter<S,T>] is null."; return false; } else if (!image.getContainer().compareStorageContainerDimensions(output.getContainer())) { errorMessage = "ImageCalculator: Images have different dimensions, not supported:" + " Image: " + Util.printCoordinates(image.getDimensions()) + " Output: " + Util.printCoordinates(output.getDimensions()); return false; } else return true; }
public SortedGrayLevelIteratorFactory(Image<T> image) { isArrayContainer = Array.class.isInstance(image.getContainer()); }
@Override public Container<T> getStorageContainer() { return image.getContainer(); }
public static <T extends RealType<T>> CompositeImage createOverlay( final T targetType, final ArrayList<ImagePlus> images, final ArrayList<InvertibleBoundable> models, final int dimensionality, final int timepoint, final InterpolatorFactory<FloatType> factory) { final int numImages = images.size(); // the size of the new image final int[] size = new int[dimensionality]; // the offset relative to the output image which starts with its local coordinates (0,0,0) final float[] offset = new float[dimensionality]; // estimate the boundaries of the output image and the offset for fusion (negative coordinates // after transform have to be shifted to 0,0,0) estimateBounds(offset, size, images, models, dimensionality); // for output final ImageFactory<T> f = new ImageFactory<T>(targetType, new ImagePlusContainerFactory()); // the composite final ImageStack stack = new ImageStack(size[0], size[1]); int numChannels = 0; // loop over all images for (int i = 0; i < images.size(); ++i) { final ImagePlus imp = images.get(i); // loop over all channels for (int c = 1; c <= imp.getNChannels(); ++c) { final Image<T> out = f.createImage(size); fuseChannel( out, ImageJFunctions.convertFloat(Hyperstack_rearranger.getImageChunk(imp, c, timepoint)), offset, models.get(i + (timepoint - 1) * numImages), factory); try { final ImagePlus outImp = ((ImagePlusContainer<?, ?>) out.getContainer()).getImagePlus(); for (int z = 1; z <= out.getDimension(2); ++z) stack.addSlice(imp.getTitle(), outImp.getStack().getProcessor(z)); } catch (ImgLibException e) { IJ.log("Output image has no ImageJ type: " + e); } // count all channels ++numChannels; } } // convertXYZCT ... ImagePlus result = new ImagePlus( "overlay " + images.get(0).getTitle() + " ... " + images.get(numImages - 1).getTitle(), stack); // numchannels, z-slices, timepoints (but right now the order is still XYZCT) if (dimensionality == 3) { result.setDimensions(size[2], numChannels, 1); result = OverlayFusion.switchZCinXYCZT(result); } else { result.setDimensions(numChannels, 1, 1); } return new CompositeImage(result, CompositeImage.COMPOSITE); }
public static <T extends RealType<T>> ImagePlus createReRegisteredSeries( final T targetType, final ImagePlus imp, final ArrayList<InvertibleBoundable> models, final int dimensionality, final String directory) { final int numImages = imp.getNFrames(); // the size of the new image final int[] size = new int[dimensionality]; // the offset relative to the output image which starts with its local coordinates (0,0,0) final float[] offset = new float[dimensionality]; final int[][] imgSizes = new int[numImages][dimensionality]; for (int i = 0; i < numImages; ++i) { imgSizes[i][0] = imp.getWidth(); imgSizes[i][1] = imp.getHeight(); if (dimensionality == 3) imgSizes[i][2] = imp.getNSlices(); } // estimate the boundaries of the output image and the offset for fusion (negative coordinates // after transform have to be shifted to 0,0,0) estimateBounds(offset, size, imgSizes, models, dimensionality); // use the same size as the first image, this is a little bit ad-hoc if (useSizeOfFirstImage) { for (int d = 0; d < dimensionality; ++d) { size[d] = imgSizes[0][d]; offset[d] = 0; } } // for output final ImageFactory<T> f = new ImageFactory<T>(targetType, new ImagePlusContainerFactory()); // the composite final ImageStack stack = new ImageStack(size[0], size[1]); for (int t = 1; t <= numImages; ++t) { for (int c = 1; c <= imp.getNChannels(); ++c) { final Image<T> out = f.createImage(size); if (useNearestNeighborInterpolation) fuseChannel( out, ImageJFunctions.convertFloat(Hyperstack_rearranger.getImageChunk(imp, c, t)), offset, models.get(t - 1), new NearestNeighborInterpolatorFactory<FloatType>( new OutOfBoundsStrategyValueFactory<FloatType>())); else fuseChannel( out, ImageJFunctions.convertFloat(Hyperstack_rearranger.getImageChunk(imp, c, t)), offset, models.get(t - 1), new LinearInterpolatorFactory<FloatType>( new OutOfBoundsStrategyValueFactory<FloatType>())); try { final ImagePlus outImp = ((ImagePlusContainer<?, ?>) out.getContainer()).getImagePlus(); if (directory == null) { // fuse for (int z = 1; z <= out.getDimension(2); ++z) stack.addSlice(imp.getTitle(), outImp.getStack().getProcessor(z)); } else { // write to disk for (int z = 1; z <= out.getDimension(2); ++z) { final ImagePlus tmp = new ImagePlus( "img_t" + lz(t, numImages) + "_z" + lz(z, out.getDimension(2)) + "_c" + lz(c, imp.getNChannels()), outImp.getStack().getProcessor(z)); final FileSaver fs = new FileSaver(tmp); fs.saveAsTiff(new File(directory, tmp.getTitle()).getAbsolutePath()); tmp.close(); } out.close(); outImp.close(); } } catch (ImgLibException e) { IJ.log("Output image has no ImageJ type: " + e); } } } if (directory != null) return null; // convertXYZCT ... ImagePlus result = new ImagePlus("registered " + imp.getTitle(), stack); // numchannels, z-slices, timepoints (but right now the order is still XYZCT) if (dimensionality == 3) { result.setDimensions(size[2], imp.getNChannels(), imp.getNFrames()); result = OverlayFusion.switchZCinXYCZT(result); return new CompositeImage(result, CompositeImage.COMPOSITE); } else { // IJ.log( "ch: " + imp.getNChannels() ); // IJ.log( "slices: " + imp.getNSlices() ); // IJ.log( "frames: " + imp.getNFrames() ); result.setDimensions(imp.getNChannels(), 1, imp.getNFrames()); if (imp.getNChannels() > 1) return new CompositeImage(result, CompositeImage.COMPOSITE); else return result; } }