def makeImg(filepaths, pixelType, loadImg, img_dimensions, matrices, cropInterval, preload): dims = Intervals.dimensionsAsLongArray(cropInterval) voldims = [dims[0], dims[1], len(filepaths)] cell_dimensions = [dims[0], dims[1], 1] grid = CellGrid(voldims, cell_dimensions) cellGet = TranslatedSectionGet(filepaths, loadImg, matrices, img_dimensions, cell_dimensions, cropInterval, preload=preload) return LazyCellImg(grid, pixelType(), cellGet), cellGet
def lazyCachedCellImg(loader, volume_dimensions, cell_dimensions, pixelType, primitiveType): """ Create a lazy CachedCellImg, backed by a SoftRefLoaderCache, which can be used to e.g. create the equivalent of ij.VirtualStack but with ImgLib2, with the added benefit of a cache based on SoftReference (i.e. no need to manage memory). loader: a CacheLoader that returns a single Cell for each index (like the Z index in a VirtualStack). volume_dimensions: a list of int or long numbers, with the last dimension being the number of Cell instances (i.e. the number of file paths). cell_dimensions: a list of int or long numbers, whose last dimension is 1. pixelType: e.g. UnsignedByteType primitiveType: e.g. BYTE Returns a CachedCellImg. """ return CachedCellImg(CellGrid(volume_dimensions, cell_dimensions), pixelType(), SoftRefLoaderCache().withLoader(loader), ArrayDataAccessFactory.get(primitiveType, AccessFlags.setOf(AccessFlags.VOLATILE)))
os.path.join(folderpath, filename) for filename in sorted(os.listdir(folderpath)) ] # Desired dimensions for reading in chunks of a single section #cell_width, cell_height = 1024, 1024 # one megabyte cell_width, cell_height = 256, 256 # Each Cell is a chunk of a single section, hence 3rd dimension is 1 cell_dimensions = [cell_width, cell_height, 1] # Volume dimensions dimensions = [section_width, section_height, len(filepaths)] # The grid of the CellImg grid = CellGrid(dimensions, cell_dimensions) def createAccess(bytes, bytesPerPixel): """ Return a new volatile access instance for the appropriate pixel type. Supports byte, short, float and long. """ if 1 == bytesPerPixel: # BYTE return VolatileByteArray(bytes, True) # Transform bytes into another type bb = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN) if 2 == bytesPerPixel: # SHORT pixels = zeros(len(bytes) / 2, 's') bb.asShortBuffer().get(pixels) return VolatileShortArray(pixels, True) if 4 == bytesPerPixel: # FLOAT pixels = zeros(len(bytes) / 4, 'f')
filepaths = [ os.path.join(folderpath, filename) for filename in sorted(os.listdir(folderpath)) ] # Desired dimensions for reaching chunks of a single section cell_width, cell_height = 1024, 1024 # one megabyte # Each Cell is a chunk of a single section, hence 3rd dimension is 1 cell_dimensions = [cell_width, cell_height, 1] # Volume dimensions dimensions = [section_width, section_height, len(filepaths)] # The grid of the CellImg grid = CellGrid(dimensions, cell_dimensions) nX, nY, nZ = grid.getGridDimensions() cells_per_section = nX * nY def createAccess(bytes, bytesPerPixel): """ Return a new access instance for the appropriate pixel type. Supports byte, short, float and long. """ if 1 == bytesPerPixel: # BYTE return ByteArray(bytes) # Transform bytes into another type bb = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN) if 2 == bytesPerPixel: # SHORT pixels = zeros(len(bytes) / 2, 's') bb.asShortBuffer().get(pixels) return ShortArray(pixels)
img.dimension(0), img.dimension(1), img.dimension(2), 1 ] return Cell(self.cell_dimensions, [0, 0, 0, index], extractDataAccess(img, self.cell_dimensions)) first = getStack(timepoint_paths[0]) # One cell per time point dimensions = [ 1 * first.dimension(0), 1 * first.dimension(1), 1 * first.dimension(2), len(timepoint_paths) ] grid = CellGrid(dimensions, dimensions[0:3] + [1]) vol4d = LazyCellImg(grid, first.randomAccess().get().createVariable(), TimePointGet(timepoint_paths)) print dimensions # Visualization option 2: # Create a 4D VirtualStack manually # Need a fast way to copy pixel-wise w = Weaver.method( """ static public final void copy(final Cursor src, final Cursor tgt) { while (src.hasNext()) {
img.dimension(d) - 1 + self.cell_padding for d in xrange(img.numDimensions()) ] imgP = Views.interval(imgE, minC, maxC) return Cell(cell_dimensions, [x0, y0], ProxyByteAccess(imgP, self.grid)) n_cols = 10 n_rows = 12 cell_padding = 5 # pixels, effective cell dimensions are 5+width+5, 5+height+5 cell_width = imp.getWidth() + cell_padding * 2 cell_height = imp.getHeight() + cell_padding * 2 grid = CellGrid([n_cols * cell_width, n_rows * cell_height], [cell_width, cell_height]) print grid # shows: CellGrid( dims = (1572, 1640), cellDims = (131, 164) ) print "numDim:", grid.numDimensions() print "gridDim:", grid.getGridDimensions() print "x, y", grid.gridDimension(0), grid.gridDimension(1) print "imgDim:", grid.getImgDimensions() print "cellDim", grid.cellDimension(0), grid.cellDimension(1) cellMin = zeros(2, 'l') cellDims = zeros(2, 'i') grid.getCellDimensions(0, cellMin, cellDims) print "cellDim 0", cellMin, cellDims grid.getCellDimensions(5, cellMin, cellDims) print "cellDim 5", cellMin, cellDims grid.getCellDimensions(10, cellMin, cellDims) print "cellDim 10", cellMin, cellDims
slices = TIFFSlices(filepath) for IFD in slices.IFDs: print IFD firstIFD = slices.IFDs[0] print firstIFD width, height = firstIFD["width"], firstIFD["height"] bitDepth = firstIFD["bitDepth"] pixel_type = { 8: UnsignedByteType, 16: UnsignedShortType, 32: FloatType }[bitDepth] grid = CellGrid([width, height, len(slices.IFDs)], [width, height, 1]) # The whole TIFF file as one Cell per slice, independently loadable imgTIFF = LazyCellImg(grid, pixel_type(), slices) # The whole file #imp = IL.wrap(imgTIFF, os.path.basename(filepath)) #imp.show() # Pick only from slices 3 to 6 view_3_to_6 = Views.interval(imgTIFF, [0, 0, 0], [width - 1, height - 1, 5]) imp_3_to_6 = IL.wrap(view_3_to_6, "3 to 6") imp_3_to_6.show() # Pick only every 3rd slice #view_every_3 = Views.subsample(imgTIFF, [1, 1, 3])
cache_loader = SoftRefLoaderCache().withLoader(loader) # SoftReference # Load the first image via the loader so that it's cached # and read the dimensions first = cache_loader.get( 0 ) # a Cell that wraps the ShortArray for the image pixels of the slice at index 0 width = first.dimension(0) height = first.dimension(1) depth = len( filepaths) # assumption: all files have the same dimensions and pixel type volume_dimensions = [width, height, depth] cell_dimensions = [width, height, 1] # just one image, one stack slice # The layout of cells: in this case, each Cell is a stack slice grid = CellGrid(volume_dimensions, cell_dimensions) img = CachedCellImg( grid, # the data layout UnsignedShortType( ), # for 16-bit images, each with a short[] native arrays cache_loader, # the loader, with a SoftReference cache ArrayDataAccessFactory.get(PrimitiveType.SHORT, AccessFlags.setOf(AccessFlags.VOLATILE))) IL.show( img, "Virtual stack: lazy-loading cached CellImg of a whole directory of images" )
def makeCell(self, index): n_cols = self.grid.imgDimension(0) / self.grid.cellDimension(0) x0 = (index % n_cols) * self.grid.cellDimension(0) y0 = (index / n_cols) * self.grid.cellDimension(1) index += 1 # 1-based slice indices in ij.ImageStack if index < 1 or index > self.imp.getStack().size(): # Return blank image: a ByteAccess that always returns 255 return Cell( self.cell_dimensions, [x0, y0], type('ConstantValue', (ByteAccess, ), { 'getValue': lambda self, index: 255 })()) else: return Cell( self.cell_dimensions, [x0, y0], ByteArray(self.imp.getStack().getProcessor(index).getPixels())) n_cols = 12 n_rows = 10 cell_width = imp.getWidth() cell_height = imp.getHeight() grid = CellGrid([n_cols * cell_width, n_rows * cell_height], [cell_width, cell_height]) montage = LazyCellImg(grid, img.cursor().next().createVariable(), SliceGet(imp, grid)) IL.show(montage, "Montage")