/** * Estimate the bounds of the output image. If there are more models than images, we assume that * this encodes for more timepoints. E.g. 2 Images and 10 models would mean 5 timepoints. The * arrangement of the models should be as follows: * * <p>image1 timepoint1 image2 timepoint1 image1 timepoint2 ... image2 timepoint5 * * @param offset - the offset, will be computed * @param size - the size, will be computed * @param images - all imageplus in a list * @param models - all models * @param dimensionality - which dimensionality (2 or 3) */ public static void estimateBounds( final float[] offset, final int[] size, final List<ImagePlus> images, final ArrayList<InvertibleBoundable> models, final int dimensionality) { final int[][] imgSizes = new int[images.size()][dimensionality]; for (int i = 0; i < images.size(); ++i) { imgSizes[i][0] = images.get(i).getWidth(); imgSizes[i][1] = images.get(i).getHeight(); if (dimensionality == 3) imgSizes[i][2] = images.get(i).getNSlices(); } estimateBounds(offset, size, imgSizes, models, dimensionality); }
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; } }