def write_color_annotation(filename, annotation_file=None): """Creates a rgb image from the atlas color data. Arguments --------- filename : str The name of the color palette file. annotation_file : str File name of the atals annotation. Returns ------- filename : str The name of the file to which the color atlas was written. """ #load atlas and convert to order if annotation_file is None: annotation_file = annotation.annotation_file atlas = np.array(io.read(annotation_file), dtype=int) atlas = convert_label(atlas, key='id', value='order', method='map') #apply color map cm = color_map(alpha=False, as_int=True) atlas = cm[atlas] return io.write(filename, atlas)
def overlayLabel(dataSource, labelSource, sink=None, alpha=False, labelColorMap='jet', x=all, y=all, z=all): """Overlay a gray scale image with colored labeled image Arguments: dataSouce (str or array): volumetric image data labelSource (str or array): labeled image to be overlayed on the image data sink (str or None): destination for the overlayed image alpha (float or False): transparency labelColorMap (str or object): color map for the labels x, y, z (all or tuple): sub-range specification Returns: (array or str): figure handle See Also: :func:`overlayPoints` """ label = io.readData(labelSource, x=x, y=y, z=z) image = io.readData(dataSource, x=x, y=y, z=z) lmax = labelSource.max() if lmax <= 1: carray = np.array([[1, 0, 0, 1]]) else: cm = mpl.cm.get_cmap(labelColorMap) cNorm = mpl.colors.Normalize(vmin=1, vmax=int(lmax)) carray = mpl.cm.ScalarMappable(norm=cNorm, cmap=cm) carray = carray.to_rgba(np.arange(1, int(lmax + 1))) if alpha == False: carray = np.concatenate(([[0, 0, 0, 1]], carray), axis=0) else: carray = np.concatenate(([[1, 1, 1, 1]], carray), axis=0) cm = mpl.colors.ListedColormap(carray) carray = cm(label) carray = carray.take([0, 1, 2], axis=-1) if alpha == False: cimage = (label == 0) * image cimage = np.repeat(cimage, 3) cimage = cimage.reshape(image.shape + (3, )) cimage = cimage.astype(carray.dtype) cimage += carray else: cimage = np.repeat(image, 3) cimage = cimage.reshape(image.shape + (3, )) cimage = cimage.astype(carray.dtype) cimage *= carray return io.writeData(sink, cimage)
def filter_cells(source, sink, thresholds): """Filter a array of detected cells according to the thresholds. Arguments --------- source : str, array or Source The source for the cell data. sink : str, array or Source The sink for the results. thresholds : dict Dictionary of the form {name : threshold} where name refers to the column in the cell data and threshold can be None, a float indicating a minimal threshold or a tuple (min,max) where min,max can be None or a minimal and maximal threshold value. Returns ------- sink : str, array or Source The thresholded cell data. """ source = io.as_source(source) ids = np.ones(source.shape[0], dtype=bool) for k, t in thresholds.items(): if t: if not isinstance(t, (tuple, list)): t = (t, None) if t[0] is not None: ids = np.logical_and(ids, t[0] <= source[k]) if t[1] is not None: ids = np.logical_and(ids, t[1] > source[k]) cells_filtered = source[ids] return io.write(sink, cells_filtered)
def deformation_distance(deformation_field, sink = None, scale = None): """Compute the distance field from a deformation vector field. Arguments --------- deformation_field : str or array Source of the deformation field determined by :func:`deformation_field`. sink : str or None Image sink to save the deformation field to. scale : tuple or None Scale factor for each dimension, if None = (1,1,1). Returns ------- deformation_distannce : array or st Array or file name of the deformation distance data. """ deformation_field = io.read(deformation_field); df = np.square(deformation_field); if not scale is None: for i in range(3): df[:,:,:,i] = df[:,:,:,i] * (scale[i] * scale[i]); df = np.sqrt(np.sum(df, axis = 3)); return io.write(sink, df);
def setSource(self, source, index = all): #initialize sources and axis settings if index is all: if isinstance(source, tuple): source = list(source); if not isinstance(source, list): source = [source]; if self.nsources != len(source): raise RuntimeError('Number of sources does not match!'); source = [io.as_source(s) for s in source]; index = range(self.nsources); else: s = self.sources; s[index] = io.as_source(source); source = s; index = [index]; for i in index: s = source[i]; if s.shape != self.source_shape: raise RuntimeError('Shape of sources does not match!'); if s.dtype == bool: self.sources[i] = s.view('uint8'); if s.ndim == 2: s.shape = s.shape + (1,); if s.ndim != 3: raise RuntimeError('Sources dont have dimensions 2 or 3 but %d in source %d!' % (s.ndim, i)); self.image_items[i].updateImage(s[self.source_slice[:s.ndims]]); self.sources = source;
def _test(): """Tests.""" import numpy as np import ClearMap.Visualization.Plot3d as p3d import ClearMap.Tests.Files as tsf import ClearMap.ImageProcessing.Experts.Vasculature as vasc source = np.array(tsf.source('vls')[:300,:300,80:120]); source[:,:,[0,-1]] = 0; source[:,[0,-1],:] = 0; source[[0,-1],:,:] = 0; bpar = vasc.default_binarization_parameter.copy(); bpar['clip']['clip_range'] = (150, 7000) bpar['as_memory'] = True #bpar['binary_status'] = 'binary_status.npy' ppar = vasc.default_processing_parameter.copy(); ppar['processes'] = 10; ppar['size_max'] = 10; sink='binary.npy' #sink=None; binary = vasc.binarize(source, sink=sink, binarization_parameter=bpar, processing_parameter = ppar) p3d.plot([source, binary]) import ClearMap.IO.IO as io io.delete_file(sink) pppar = vasc.default_postprocessing_parameter.copy(); pppar['smooth']['iterations'] = 3; smoothed = vasc.postprocess(binary, postprocessing_parameter=pppar) p3d.plot([binary, smoothed])
def moveTeraStitcherStackToFileList(source, sink, deleteDirectory = True, verbose = True): """Moves image files from TeraSticher file structure to a list of files Arguments: source (str): base directory of the TeraStitcher files sink (str): regular expression of the files to copy to verbose (bool): show progress Returns: str: sink regular expression """ fns = glob.glob(os.path.join(source, '*/*/*')); fns = natsort.natsorted(fns); io.createDirectory(sink); for i,f in enumerate(fns): fn = filelist.fileExpressionToFileName(sink, i); if verbose: print '%s -> %s' % (f,fn) shutil.move(f, fn); if deleteDirectory: p,_ = os.path.split(fns[0]); p = p.split(os.path.sep); p = p[:-2]; p = os.path.sep.join(p); shutil.rmtree(p); return sink;
def create(self, ftype, dtype = None, shape = None, order = None, file_type_to_name = None, directory = None, expression = None, values = None, prefix = None, extension = None, debug = None, **kwargs): filename = self.filename(ftype=ftype, file_type_to_name=file_type_to_name, directory=directory, expression=expression, values=values, prefix=prefix, debug=debug, **kwargs) io.create(filename, shape=shape, dtype=dtype, order=order) return filename
def create_debug(self, ftype, slicing, debug = None, **kwargs): if debug is None: debug = self.debug; if debug is None: debug = 'debug'; self.debug = None; source = io.as_source(self.filename(ftype, **kwargs)); self.debug = debug; return io.write(self.filename(ftype, **kwargs), np.asarray(source[slicing], order='F'));
def find_intensity(source, label, max_label=None, method='sum', verbose=False): """Find integrated intensity given object shapes as labled image. Arguments --------- source : array, str, or Source Source to measure intensities from. label : array, str, or Source Labeled image with a separate label for each object. max_label : int or None Maximal label to include. If None use all. method : {'sum', 'mean', 'max', 'min'} Method to use to measure the intensities in each object's area. verbose : bool If True, print progress information. Returns ------- intensities : array Measured intensities. """ if verbose: timer = tmr.Timer() hdict.pprint(head='Intensity detection:', max_label=max_label, method=method) source = io.as_source(source).array label = io.as_source(label) if max_label is None: max_label = label.max() if method.lower() == 'sum': measure = scipy.ndimage.measurements.sum elif method.lower() == 'mean': measure = scipy.ndimage.measurements.mean elif method.lower() == 'max': measure = scipy.ndimage.measurements.maximum elif method.lower() == 'min': measure = scipy.ndimage.measurements.minimum else: raise RuntimeError('Unkown method %r!' % (method, )) intensities = measure(label, labels=label, index=np.arange(1, max_label + 1)) if verbose: timer.print_elapsed_time(head='Intensity detection') return intensities
def _test(): """Tests""" import ClearMap.Settings as settings import ClearMap.IO.IO as io import ClearMap.Visualization.Plot3d as p3d; import ClearMap.Alignment.Resampling as res from importlib import reload reload(res) r = res.resample_shape(source_shape=(100,200,300), sink_shape=(50,50,30)); print('resampled source_shape=%r, sink_shape=%r, source_resolution=%r, sink_resolution=%r' % r) r = res.resample_shape(source_shape=(100,200,300), source_resolution=(2,2,2), sink_resolution=(10,2,1)) print('resampled source_shape=%r, sink_shape=%r, source_resolution=%r, sink_resolution=%r' % r) source = io.join(settings.test_data_path, 'Resampling/test.tif') sink = io.join(settings.test_data_path, "Resampling/resampled.npy") source = io.join(settings.test_data_path, 'Tif/sequence/sequence<Z,4>.tif') sink = io.join(settings.test_data_path, "Resampling/resampled_sequence.tif") source_shape, sink_shape, source_res, sink_res = res.resample_shape(source_shape=io.shape(source), source_resolution=(1.,1.,1.), sink_resolution=(1.6,1.6,2)) axes_order = res._axes_order(None, source_shape, sink_shape); print(axes_order) resampled = res.resample(source, sink, source_resolution=(1.,1.,1.), sink_resolution = (1.6,1.6,2), orientation=None, processes=None); p3d.plot(resampled) p3d.plot(source) inverse = res.resample_inverse(resampled, sink=None, resample_source=source, source_resolution=(1,1,1), sink_resolution = (10,10,2), orientation=None, processes='serial') p3d.plot([source, inverse]) resampled = res.resample(source, sink, source_resolution=(1,1,1), sink_resolution = (10,10,2), orientation=(2,-1,3), processes=None); p3d.plot(resampled) inverse = res.resample_inverse(resampled, sink=None, resample_source=source, source_resolution=(1,1,1), sink_resolution = (10,10,2), orientation=(2,-1,3), processes=None) p3d.plot([source, inverse]) resampled = res.resample(source, sink=None, source_resolution=(1.6,1.6,2), sink_shape=(10,20,30), orientation=None, processes=None) p3d.plot(resampled) # ponints points = res.np.array([[0,0,0], [1,1,1], [1,2,3]], dtype=float); resampled_points = res.resample_points(points, resample_source=source , resample_sink=sink, orientation=None) print(resampled_points) inverse_points = res.resample_points_inverse(resampled_points, resample_source=source , resample_sink=sink, orientation=None) print(inverse_points) print(res.np.allclose(points, inverse_points))
def overlayPoints(dataSource, pointSource, sink=None, pointColor=[1, 0, 0], x=all, y=all, z=all): """Overlay points on 3D data and return as color image Arguments: dataSouce (str or array): volumetric image data pointSource (str or array): point data to be overlayed on the image data pointColor (array): RGB color for the overlayed points x, y, z (all or tuple): sub-range specification Returns: (str or array): image overlayed with points See Also: :func:`overlayLabel` """ data = io.readData(dataSource, x=x, y=y, z=z) points = io.readPoints(pointSource, x=x, y=y, z=z, shift=True) #print data.shape if not pointColor is None: dmax = data.max() dmin = data.min() if dmin == dmax: dmax = dmin + 1 cimage = np.repeat((data - dmin) / (dmax - dmin), 3) cimage = cimage.reshape(data.shape + (3, )) if data.ndim == 2: for p in points: # faster version using voxelize ? cimage[p[0], p[1], :] = pointColor elif data.ndim == 3: for p in points: # faster version using voxelize ? cimage[p[0], p[1], p[2], :] = pointColor else: raise RuntimeError( 'overlayPoints: data dimension %d not suported' % data.ndim) else: cimage = vox.voxelize(points, data.shape, method='Pixel') cimage = cimage.astype(data.dtype) * data.max() data.shape = data.shape + (1, ) cimage.shape = cimage.shape + (1, ) cimage = np.concatenate((data, cimage), axis=3) #print cimage.shape return io.writeData(sink, cimage)
def resampleXY(source, dataSizeSink, sink=None, interpolation='linear', out=sys.stdout, verbose=True): """Resample a 2d image slice This routine is used for resampling a large stack in parallel in xy or xz direction. Arguments: source (str or array): 2d image source dataSizeSink (tuple): size of the resmapled image sink (str or None): location for the resmapled image interpolation (str): interpolation method to use: 'linear' or None (nearest pixel) out (stdout): where to write progress information vebose (bool): write progress info if true Returns: array or str: resampled data or file name """ #out.write("Input: %s Output: " % (inputFile, soutputFile)) data = io.readData(source) dataSize = data.shape #print dataSize, dataSizeSink if data.ndim != 2: raise RuntimeError('resampleXY: expects 2d image source, found %dd' % data.ndim) #print sagittalImageSize; #dataSizeSink = tuple([int(math.ceil(dataSize[i] * resolutionSource[i]/resolutionSink[i])) for i in range(2)]); if verbose: out.write(("resampleData: Imagesize: %d, %d " % (dataSize[0], dataSize[1])) + ("Resampled Imagesize: %d, %d" % (dataSizeSink[0], dataSizeSink[1]))) #out.write(("resampleData: Imagesize: %d, %d " % dataSize) + ("Resampled Imagesize: %d, %d" % (outputSize[1], outputSize[0]))) # note: cv2.resize reverses x-Y axes interpolation = fixInterpolation(interpolation) sinkData = cv2.resize(data, (dataSizeSink[1], dataSizeSink[0]), interpolation=interpolation) #sinkData = cv2.resize(data, outputSize); #sinkData = scipy.misc.imresize(sagittalImage, outputImageSize, interp = 'bilinear'); #normalizes images -> not usefull for stacks ! #out.write("resampleData: resized Image size: %d, %d " % sinkData.shape) return io.writeData(sink, sinkData)
def test(): import numpy as np import ClearMap.IO.IO as io import ClearMap.Analysis.Measurements.MeasureRadius as mr data = 10 - np.abs(10 - np.arange(0, 21)) search = mr.search_indices_sphere(radius=[10, 10, 10]) print(search) points = np.array([10]) d, i = mr.measure_radius(data, points, fraction=0.75, max_radius=10, scale=2, verbose=True, processes=4, return_indices=True) data = np.random.rand(*(30, 40, 50)) io.write('data.npy', data) points = np.array([np.random.randint(0, s, size=10) for s in data.shape]).T d, i = mr.measure_radius(data, points, value=0.5, max_radius=10, scale=2, verbose=True, processes=4, return_indices=True) data = np.zeros((30, 40, 50), dtype=int) data[10:20, 15:25, 10:20] = 1 data[15, 20, 15] = 2 import ClearMap.Visualization.Plot3d as p3d p3d.plot(data) points = np.array([[15, 20, 15], [4, 4, 4]]) d, i = mr.measure_radius(data, points, value=0.0, max_radius=10, scale=None, verbose=True, processes=None, return_indices=True)
def write(filename, source, header=None, **kwargs): """Write data into to raw/mhd file pair Arguments --------- filename : str The file name of the raw/mhd file. source : source specification The source to write as mhd/raw file. Returns ------- filename : str The filename of the mhd file. """ import ClearMap.IO.IO as io fext = io.file_extension(filename) if fext == "raw": header_name = filename[:-3] + 'mhd' raw_name = filename elif fext == 'mhd': header_name = filename raw_name = filename[:-3] + 'raw' else: header_name = filename + '.mhd' raw_name = filename + '.raw' hdm_header = header_from_source(source, header=header) write_header(header_name, hdm_header) write_raw(raw_name, source) return header_name
def write_header_from_source(source, filename=None, header=None): """Create a mhd header file for a source file. Arguments --------- source : Source specification Source file or class to create a mhd header file for. filename : str or None Filename of the mhd file. If None, the source location with extension 'mhd' is used. header : dict or None Optional additional entries for the header file. Returns ------- filename : str The filename of the mhd header. """ import ClearMap.IO.IO as io source = io.as_source(source) mhd_header = header_from_source(source, header=header) if filename is None: filename = source.location + '.mhd' return write_header(filename, mhd_header)
def flatfield_from_line(line, shape, axis = 0, dtype = float): """Creates a 2d flat field image from a 1d line of estimated intensities. Arguments --------- line : array Array of intensities along the specified axis. shape : tuple Shape of the resulting image. axis : int Axis of the flat field line estimate. Returns ------- flatfield : array Full 2d flat field. """ line = io.as_source(line); if isinstance(shape, int): shape = (line.shape[0], shape) if axis == 0 else (shape, line.shape[0]); if shape[axis] != line.shape[0]: raise ValueError('Line shape %d does not match image shape %d!' % (line.shape[0], shape[axis])); shape = shape[axis]; flatfield = np.array([line.array] * shape, dtype=dtype) if axis == 1: flatfield = flatfield.T; return flatfield;
def border_indices(source): """Returns the flat indices of the border pixels in source""" ndim = source.ndim shape = source.shape strides = io.element_strides(source) border = [] for d in range(ndim): offsets = tuple(0 if i > d else 1 for i in range(ndim)) for c in [0, shape[d] - 1]: sl = tuple( slice(o, None if o == 0 else -o) if i != d else c for i, o in enumerate(offsets)) where = np.where(np.logical_not(source[sl])) n = len(where[0]) if n > 0: indices = np.zeros(n, dtype=int) l = 0 for k in range(ndim): if k == d: indices += strides[k] * c else: indices += strides[k] * (where[l] + offsets[k]) l += 1 border.append(indices) return np.concatenate(border)
def read_group(sources, combine=True, **args): """Turn a list of sources for data into a numpy stack. Arguments --------- sources : list of str or sources The sources to combine. combine : bool If true combine the sources to ndarray, oterhwise return a list. Returns ------- group : array or list The gorup data. """ #check if stack already: if isinstance(sources, np.ndarray): return sources #read the individual files group = [] for f in sources: data = io.as_source(f, **args).array data = np.reshape(data, (1, ) + data.shape) group.append(data) if combine: return np.vstack(group) else: return group
def write_color_palette(filename=None): """Creates a pal or lut file for imaris or imagej based on label colors of atlas. Arguments --------- filename : str The name of the color palette file. Returns ------- filename : str The name of the file to which the color palette was written. """ cm = color_map(alpha=False, as_int=True) fext = io.file_extension(filename) if fext == 'pal': col.write_PAL(filename, cm) elif fext == 'lut': col.write_LUT(filename, cm) else: raise RuntimeError('color pallete format: %s not lut or pal' % fext) return filename
def voxelizeOrientations(points, orientations, dataSize=None, sink=None, size=(5, 5, 5), weights=None): """Converts a list of points into an volumetric image array Arguments: points (array): point data array orientations (array): point data array dataSize (tuple): size of final image sink (str, array or None): the location to write or return the resulting voxelization image, if None return array Returns: (array): volumetric data of orientation statistics """ if dataSize is None: dataSize = tuple( int(math.ceil(points[:, i].max())) for i in range(points.shape[1])) elif isinstance(dataSize, str): dataSize = io.dataSize(dataSize) if weights is not None: orts = (orientations.T * weights).T else: orts = orientations data = orc.voxelizeOrientations(points, orts, dataSize[0], dataSize[1], dataSize[2], size[0], size[1], size[2]) return data
def as_memory_block(self): source = io.as_source(self.as_memory()) return Block(source=source, slicing=slice(None), valid_slicing=self.valid.slicing, index=self.index, neighbours=self.neighbours)
def find_size(label, max_label=None, verbose=False): """Find size given object shapes as a labled image Arguments --------- label : array, str or Source Labeled image in which each object has its own label. max_label : int or None Maximal label to include, if None use all label. verbose : bool Print progress info. Returns ------- sizes : array Measured intensities """ if verbose: timer = tmr.Timer() hdict.pprint(head='Size detection:', max_label=max_label) label = io.as_source(label) if max_label is None: max_label = int(label.max()) sizes = scipy.ndimage.measurements.sum(np.ones(label.shape, dtype=bool), labels=label, index=np.arange(1, max_label + 1)) if verbose: timer.print_elapsed_time(head='Size detection') return sizes
def block_axes(source, axes=None): """Determine the axes for block processing from source order. Arguments --------- source : array or Source The source on which the block processing is used. axes : list or None The axes over which to split the block processing. Returns ------- axes : list or None The axes over which to split the block processing. """ if axes is all: axes = [d for d in range(source.ndim)] if axes is not None: if np.max(axes) >= source.ndim or np.min(axes) < 0: raise ValueError( 'Axes specification %r for source with dimnesion %d not valid!' % (axes, source.ndim)) return axes source = io.as_source(source) if source.order == 'F': axes = [source.ndim - 1] else: axes = [0] return axes
def detect_shape(source, seeds, threshold=None, verbose=False): """Detect object shapes by generatng a labeled image from seeds. Arguments --------- source : array, str or Source Source image. seeds : array, str or Source Cell centers as point coordinates. threshold : float or None Threshold to determine mask for watershed, pixel below this are treated as background. If None, the seeds are expanded indefinately. verbose :bool If True, print progress info. Returns ------- shapes : array Labeled image, where each label indicates a object. """ if verbose: timer = tmr.Timer() hdict.pprint(head='Shape detection', threshold=threshold) source = io.as_source(source).array seeds = io.as_source(seeds) if threshold is None: mask = None else: mask = source > threshold peaks = vox.voxelize(seeds, shape=source.shape, weights=np.arange(1, seeds.shape[0] + 1)).array shapes = skimage.morphology.watershed(-source, peaks, mask=mask) #shapes = watershed_ift(-source.astype('uint16'), peaks); #shapes[numpy.logical_not(mask)] = 0; if verbose: timer.print_elapsed_time('Shape detection') return shapes
def label_points(points, annotation_file=None, invalid=0, key='order', level=None): """Label points according to the annotation in the labeled image file. Arguments --------- points : array Array of nxdim point coordinates to be labeled. annotation_file : str File name of the atals annotation. invalid : int Label for invalid points. key : str The key of the label, by default the order of the labels. Returns ------- label : array Label of the points corresponding to the given key. """ n_points = points.shape[0] n_dim = points.shape[1] if annotation_file is None: annotation_file = annotation.annotation_file atlas = io.read(annotation_file) atlas = np.array(atlas, dtype=int) atlas_shape = atlas.shape label = np.full(n_points, invalid, dtype=int) points_int = np.asarray(points, dtype=int) for d in range(n_dim): if d == 0: valid = np.logical_and(points_int[:, d] >= 0, points_int[:, d] < atlas_shape[d]) else: valid = np.logical_and( valid, np.logical_and(points_int[:, d] >= 0, points_int[:, d] < atlas_shape[d])) indices = [points_int[valid, d] for d in range(n_dim)] label[valid] = atlas[indices] if key != 'id' or level is not None: label[valid] = convert_label(label[valid], key='id', value=key, level=level) return label
def initializeSources(self, source, scale=None, axis=None, update=True): #initialize sources and axis settings if isinstance(source, tuple): source = list(source) if not isinstance(source, list): source = [source] self.nsources = len(source) self.sources = [io.as_source(s) for s in source] # avoid bools for i, s in enumerate(self.sources): if s.dtype == bool: self.sources[i] = s.view('uint8') # # ensure 3d images # for i,s in enumerate(self.sources): # if s.ndim == 2: # s = s.view(); # s.shape = s.shape + (1,); # self.sources[i] = s; # if s.ndim != 3: # raise RuntimeError('Sources dont have dimensions 2 or 3 but %d in source %d!' % (s.ndim, i)); # source shapes self.source_shape = self.shape3d(self.sources[0].shape) for s in self.sources: if s.ndim > 3: raise RuntimeError('Source has %d > 3 dimensions: %r!' % (s.ndim, s)) if self.shape3d(s.shape) != self.source_shape: raise RuntimeError('Sources shape %r vs %r in source %r!' % (self.source_shape, s.shape, s)) self.source_shape2 = np.array( np.array(self.source_shape, dtype=float) / 2, dtype=int) # for i,s in enumerate(self.sources): # # slicing if axis is None: axis = 2 self.source_axis = axis self.source_index = self.source_shape2 # scaling if scale is None: scale = np.ones(3) else: scale = np.array(scale) scale = np.hstack([scale, [1] * 3])[:3] self.source_scale = scale #print(self.source_shape, self.source_scale) self.updateSourceRange() self.updateSourceSlice()
def plot_3d(source, colormap=None, view=None, title=None, center_view=True, **kwargs): """Plot 3d volume. Arguments --------- source : array The 3d volume. title : str or None Window title. view : view or None Add plot to this view. if given. Returns ------- view : view The view of the plot. """ #visual #VolumePlot3D = vispy.scene.visuals.create_visual_node(vispy.visuals.VolumeVisual) VolumePlot3D = vispy.scene.visuals.create_visual_node(vvi.VolumeVisual) #view title = title if title is not None else 'plot_3d' #center = (np.array(source.shape) // 2); view = initialize_view(view, title=title, fov=0, depth_value=10**8) #, center=center) #style style = dict(cmap=grays_alpha(), method='translucent', relative_step_size=0.5) style.update(**kwargs) #source source = io.as_source(source)[:] if source.dtype == bool: source = source.view(dtype='uint8') #orient source = source.transpose([2, 1, 0]) #plot p = VolumePlot3D(source, parent=view.scene, **style) #view.camera.set_range(); if center_view: _center_view(view) return p
def _initialize_source(source, as_source = False, as_1d = False, return_shape = False, return_strides = False): """Initialize a source for parallel array processing. Arguments --------- source : source specification The source to initialize. as_source : bool If True, return source as Source class. If false, a buffer compatible with cython memory views is returned. return_shape : bool If True, also return shape of the source. return_strides : bool If True, also return the element strides of the source. Returns ------- source : Source or buffer The intialized source. shape : tuple of int Shape of the source. return_Strides : tuple of int Element strides of the source. """ source = io.as_source(source) if return_shape: shape = source.shape; if return_strides: strides = source.element_strides; if not as_source: #make sure the source is a buffer compatible with cython memoryviews source = source.as_buffer(); if source.dtype == bool: source = source.view('uint8'); if as_1d: source = source.reshape(-1, order = 'A'); result = (source,); if return_shape: result += (shape,); if return_strides: result += (strides,); if len(result) == 1: return result[0]; else: return result;
def resampleXY(source, dataSizeSink, sink = None, interpolation = 'linear', out = sys.stdout, verbose = True): """Resample a 2d image slice This routine is used for resampling a large stack in parallel in xy or xz direction. Arguments: source (str or array): 2d image source dataSizeSink (tuple): size of the resmapled image sink (str or None): location for the resmapled image interpolation (str): interpolation method to use: 'linear' or None (nearest pixel) out (stdout): where to write progress information vebose (bool): write progress info if true Returns: array or str: resampled data or file name """ #out.write("Input: %s Output: " % (inputFile, soutputFile)) data = io.readData(source); dataSize = data.shape; #print dataSize, dataSizeSink if data.ndim != 2: raise RuntimeError('resampleXY: expects 2d image source, found %dd' % data.ndim) #print sagittalImageSize; #dataSizeSink = tuple([int(math.ceil(dataSize[i] * resolutionSource[i]/resolutionSink[i])) for i in range(2)]); if verbose: out.write(("resampleData: Imagesize: %d, %d " % (dataSize[0], dataSize[1])) + ("Resampled Imagesize: %d, %d" % (dataSizeSink[0], dataSizeSink[1]))) #out.write(("resampleData: Imagesize: %d, %d " % dataSize) + ("Resampled Imagesize: %d, %d" % (outputSize[1], outputSize[0]))) # note: cv2.resize reverses x-Y axes interpolation = fixInterpolation(interpolation) sinkData = cv2.resize(data, (dataSizeSink[1], dataSizeSink[0]), interpolation = interpolation); #sinkData = cv2.resize(data, outputSize); #sinkData = scipy.misc.imresize(sagittalImage, outputImageSize, interp = 'bilinear'); #normalizes images -> not usefull for stacks ! #out.write("resampleData: resized Image size: %d, %d " % sinkData.shape) return io.writeData(sink, sinkData);
def _test(): """Tests for the Resampling Module""" import ClearMap.Alignment.Resampling as self reload(self) from ClearMap.Settings import ClearMapPath as basedir import iDISCO.IO.IO as io import os, numpy fn = os.path.join( basedir, 'Test/Data/OME/16-17-27_0_8X-s3-20HF_UltraII_C00_xyz-Table Z\d{4}.ome.tif' ) outfn = os.path.join(basedir, "Test/Data/Resampling/test.mhd") print "Making resampled stack " + outfn print "source datasize %s" % str(io.dataSize(fn)) data = self.resampleData(fn, sink=None, resolutionSource=(1, 1, 1), orientation=(1, 2, 3), resolutionSink=(10, 10, 2)) print data.shape io.writeData(outfn, data) data = self.resampleData(fn, sink=None, dataSizeSink=(50, 70, 10), orientation=(1, 2, 3)) print data.shape io.writeData(outfn, data) dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = self.resampleDataSize( dataSizeSource=(100, 200, 303), dataSizeSink=None, resolutionSource=(1, 1, 1), resolutionSink=(5, 5, 5), orientation=(1, 2, 3)) print dataSizeSource, dataSizeSink, resolutionSource, resolutionSink points = numpy.array([[0, 0, 0], [1, 1, 1], io.dataSize(fn)]) points = points.astype('float') pr = self.resamplePoints(points, dataSizeSource=fn, dataSizeSink=(50, 70, 10), orientation=(1, 2, 3)) print pr pri = self.resamplePointsInverse(pr, dataSizeSource=fn, dataSizeSink=(50, 70, 10), orientation=(-1, 2, 3)) print pri result = self.resampleDataInverse( outfn, os.path.join(basedir, 'Test/Data/OME/resample_\d{4}.ome.tif'), dataSizeSource=fn) print result
def sagittalToCoronalData(source, sink = None): """Change from saggital to coronal orientation Arguments: source (str or array): source data to be reoriented sink (str or None): destination for reoriented image Returns: str or array: reoriented data """ source = io.readData(source); d = source.ndim; if d < 3: raise RuntimeError('sagittalToCoronalData: 3d image required!'); tp = range(d); tp[0:3] = [2,0,1]; source = source.transpose(tp); source = source[::-1]; #source = source[::-1,:,:]; return io.writeData(sink, source);
def _resampleXYParallel(arg): """Resampling helper function to use for parallel resampling of image slices""" fileSource = arg[0]; fileSink = arg[1]; dataSizeSink = arg[2]; interpolation = arg[3]; ii = arg[4]; nn = arg[5]; verbose = arg[6]; pw = ProcessWriter(ii); if verbose: pw.write("resampleData: resampling in XY: image %d / %d" % (ii, nn)) data = numpy.squeeze(io.readData(fileSource, z = ii)); resampleXY(data, sink = fileSink, dataSizeSink = dataSizeSink, interpolation = interpolation, out = pw, verbose = verbose);
def _test(): """Tests for the Resampling Module""" import ClearMap.Alignment.Resampling as self reload(self) from ClearMap.Settings import ClearMapPath as basedir import iDISCO.IO.IO as io import os, numpy fn = os.path.join(basedir, 'Test/Data/OME/16-17-27_0_8X-s3-20HF_UltraII_C00_xyz-Table Z\d{4}.ome.tif'); outfn = os.path.join(basedir, "Test/Data/Resampling/test.mhd") print "Making resampled stack " + outfn print "source datasize %s" % str(io.dataSize(fn)); data = self.resampleData(fn, sink = None, resolutionSource = (1,1,1), orientation = (1,2,3), resolutionSink = (10,10,2)); print data.shape io.writeData(outfn, data) data = self.resampleData(fn, sink = None, dataSizeSink = (50,70,10), orientation = (1,2,3)); print data.shape io.writeData(outfn, data) dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = self.resampleDataSize(dataSizeSource = (100,200, 303), dataSizeSink = None, resolutionSource = (1,1,1), resolutionSink = (5,5,5), orientation = (1,2,3)); print dataSizeSource, dataSizeSink, resolutionSource, resolutionSink points = numpy.array([[0,0,0], [1,1,1], io.dataSize(fn)]); points = points.astype('float') pr = self.resamplePoints(points, dataSizeSource = fn, dataSizeSink = (50,70,10), orientation = (1,2,3)) print pr pri = self.resamplePointsInverse(pr, dataSizeSource = fn, dataSizeSink = (50,70,10), orientation = (-1,2,3)) print pri result = self.resampleDataInverse(outfn, os.path.join(basedir, 'Test/Data/OME/resample_\d{4}.ome.tif'), dataSizeSource = fn); print result
def resamplePointsInverse(pointSource, pointSink = None, dataSizeSource = None, dataSizeSink = None, orientation = None, resolutionSource = (4.0625, 4.0625, 3), resolutionSink = (25, 25, 25), **args): """Resample points from the coordinates of the resampled image to the original data The resampling of points here corresponds to he resampling of an image in :func:`resampleDataInverse` Arguments: pointSource (str or array): image to be resampled pointSink (str or None): destination of resampled image orientation (tuple): orientation specified by permuation and change in sign of (1,2,3) dataSizeSource (str, tuple or None): size of the data source dataSizeSink (str, tuple or None): target size of the resampled image resolutionSource (tuple): resolution of the source image (in length per pixel) resolutionSink (tuple): resolution of the resampled image (in length per pixel) Returns: (array or str): data or file name of inversely resampled points Notes: * resolutions are assumed to be given for the axes of the intrinsic orientation of the data and reference as when viewed by matplotlib or ImageJ * orientation: permuation of 1,2,3 with potential sign, indicating which axes map onto the reference axes, a negative sign indicates reversal of that particular axes * only a minimal set of information to detremine the resampling parameter has to be given, e.g. dataSizeSource and dataSizeSink """ orientation = fixOrientation(orientation); #datasize of data source if isinstance(dataSizeSource, basestring): dataSizeSource = io.dataSize(dataSizeSource); dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = resampleDataSize(dataSizeSource = dataSizeSource, dataSizeSink = dataSizeSink, resolutionSource = resolutionSource, resolutionSink = resolutionSink, orientation = orientation); points = io.readPoints(pointSource); dataSizeSinkI = orientDataSizeInverse(dataSizeSink, orientation); #resolutionSinkI = orientResolutionInverse(resolutionSink, orientation); #scaling factors scale = [float(dataSizeSource[i]) / float(dataSizeSinkI[i]) for i in range(3)]; #print scale rpoints = points.copy(); #invert axis inversion and permutations if not orientation is None: #invert permuation iorientation = inverseOrientation(orientation); per = orientationToPermuation(iorientation); rpoints = rpoints[:,per]; for i in range(3): if iorientation[i] < 0: rpoints[:,i] = dataSizeSinkI[i] - rpoints[:,i]; #scale points for i in range(3): rpoints[:,i] = rpoints[:,i] * scale[i]; return io.writePoints(pointSink, rpoints);
def resampleData(source, sink = None, orientation = None, dataSizeSink = None, resolutionSource = (4.0625, 4.0625, 3), resolutionSink = (25, 25, 25), processingDirectory = None, processes = 1, cleanup = True, verbose = True, interpolation = 'linear', **args): """Resample data of source in resolution and orientation Arguments: source (str or array): image to be resampled sink (str or None): destination of resampled image orientation (tuple): orientation specified by permuation and change in sign of (1,2,3) dataSizeSink (tuple or None): target size of the resampled image resolutionSource (tuple): resolution of the source image (in length per pixel) resolutionSink (tuple): resolution of the resampled image (in length per pixel) processingDirectory (str or None): directory in which to perform resmapling in parallel, None a temporary directry will be created processes (int): number of processes to use for parallel resampling cleanup (bool): remove temporary files verbose (bool): display progress information interpolation (str): method to use for interpolating to the resmapled image Returns: (array or str): data or file name of resampled image Notes: * resolutions are assumed to be given for the axes of the intrinsic orientation of the data and reference as when viewed by matplotlib or ImageJ * orientation: permuation of 1,2,3 with potential sign, indicating which axes map onto the reference axes, a negative sign indicates reversal of that particular axes * only a minimal set of information to detremine the resampling parameter has to be given, e.g. dataSizeSource and dataSizeSink """ orientation = fixOrientation(orientation); if isinstance(dataSizeSink, basestring): dataSizeSink = io.dataSize(dataSizeSink); #orient actual resolutions onto reference resolution dataSizeSource = io.dataSize(source); dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = resampleDataSize(dataSizeSource = dataSizeSource, dataSizeSink = dataSizeSink, resolutionSource = resolutionSource, resolutionSink = resolutionSink, orientation = orientation); dataSizeSinkI = orientDataSizeInverse(dataSizeSink, orientation); #print dataSizeSource, dataSizeSink, resolutionSource, resolutionSink, dataSizeSinkI #rescale in x y in parallel if processingDirectory == None: processingDirectory = tempfile.mkdtemp(); interpolation = fixInterpolation(interpolation); nZ = dataSizeSource[2]; pool = multiprocessing.Pool(processes=processes); argdata = []; for i in range(nZ): argdata.append( (source, os.path.join(processingDirectory, 'resample_%04d.tif' % i), dataSizeSinkI, interpolation, i, nZ, verbose) ); #print argdata[i] pool.map(_resampleXYParallel, argdata); #rescale in z fn = os.path.join(processingDirectory, 'resample_%04d.tif' % 0); data = io.readData(fn); zImage = numpy.zeros((dataSizeSinkI[0], dataSizeSinkI[1], nZ), dtype = data.dtype); for i in range(nZ): if verbose and i % 10 == 0: print "resampleData; reading %d/%d" % (i, nZ); fn = os.path.join(processingDirectory, 'resample_%04d.tif' % i); zImage[:,:, i] = io.readData(fn); resampledData = numpy.zeros(dataSizeSinkI, dtype = zImage.dtype); for i in range(dataSizeSinkI[0]): if verbose and i % 25 == 0: print "resampleData: processing %d/%d" % (i, dataSizeSinkI[0]) #resampledImage[:, iImage ,:] = scipy.misc.imresize(zImage[:,iImage,:], [resizedZAxisSize, sagittalImageSize[1]] , interp = 'bilinear'); #cv2.resize takes reverse order of sizes ! resampledData[i ,:, :] = cv2.resize(zImage[i,:,:], (dataSizeSinkI[2], dataSizeSinkI[1]), interpolation = interpolation); #resampledData[i ,:, :] = cv2.resize(zImage[i,:, :], (dataSize[1], resizedZSize)); #account for using (z,y,x) array representation -> (y,x,z) #resampledData = resampledData.transpose([1,2,0]); #resampledData = resampledData.transpose([2,1,0]); if cleanup: shutil.rmtree(processingDirectory); if not orientation is None: #reorient per = orientationToPermuation(orientation); resampledData = resampledData.transpose(per); #reverse orientation after permuting e.g. (-2,1) brings axis 2 to first axis and we can reorder there if orientation[0] < 0: resampledData = resampledData[::-1, :, :]; if orientation[1] < 0: resampledData = resampledData[:, ::-1, :]; if orientation[2] < 0: resampledData = resampledData[:, :, ::-1]; #bring back from y,x,z to z,y,x #resampledImage = resampledImage.transpose([2,0,1]); if verbose: print "resampleData: resampled data size: " + str(resampledData.shape) if sink == []: if io.isFileExpression(source): sink = os.path.split(source); sink = os.path.join(sink[0], 'resample_\d{4}.tif'); elif isinstance(source, basestring): sink = source + '_resample.tif'; else: raise RuntimeError('resampleData: automatic sink naming not supported for non string source!'); return io.writeData(sink, resampledData);
g1 = stat.readDataGroup(group1); g2 = stat.readDataGroup(group2); #Generated average and standard deviation maps ############################################## g1a = numpy.mean(g1,axis = 0); g1s = numpy.std(g1,axis = 0); g2a = numpy.mean(g2,axis = 0); g2s = numpy.std(g2,axis = 0); io.writeData(os.path.join(baseDirectory, 'group1_mean.raw'), rsp.sagittalToCoronalData(g1a)); io.writeData(os.path.join(baseDirectory, 'group1_std.raw'), rsp.sagittalToCoronalData(g1s)); io.writeData(os.path.join(baseDirectory, 'group2_fast_mean.raw'), rsp.sagittalToCoronalData(g2a)); io.writeData(os.path.join(baseDirectory, 'group2_fast_std.raw'), rsp.sagittalToCoronalData(g2s)); #Generate the p-values map ########################## #pcutoff: only display pixels below this level of significance pvals, psign = stat.tTestVoxelization(g1.astype('float'), g2.astype('float'), signed = True, pcutoff = 0.05); #color the p-values according to their sign (defined by the sign of the difference of the means between the 2 groups)
def resampleDataInverse(sink, source = None, dataSizeSource = None, orientation = None, resolutionSource = (4.0625, 4.0625, 3), resolutionSink = (25, 25, 25), processingDirectory = None, processes = 1, cleanup = True, verbose = True, interpolation = 'linear', **args): """Resample data inversely to :func:`resampleData` routine Arguments: sink (str or None): image to be inversly resampled (=sink in :func:`resampleData`) source (str or array): destination for inversly resmapled image (=source in :func:`resampleData`) dataSizeSource (tuple or None): target size of the resampled image orientation (tuple): orientation specified by permuation and change in sign of (1,2,3) resolutionSource (tuple): resolution of the source image (in length per pixel) resolutionSink (tuple): resolution of the resampled image (in length per pixel) processingDirectory (str or None): directory in which to perform resmapling in parallel, None a temporary directry will be created processes (int): number of processes to use for parallel resampling cleanup (bool): remove temporary files verbose (bool): display progress information interpolation (str): method to use for interpolating to the resmapled image Returns: (array or str): data or file name of resampled image Notes: * resolutions are assumed to be given for the axes of the intrinsic orientation of the data and reference as when viewed by matplotlib or ImageJ * orientation: permuation of 1,2,3 with potential sign, indicating which axes map onto the reference axes, a negative sign indicates reversal of that particular axes * only a minimal set of information to detremine the resampling parameter has to be given, e.g. dataSizeSource and dataSizeSink """ #orientation orientation = fixOrientation(orientation); #assume we can read data fully into memory resampledData = io.readData(sink); dataSizeSink = resampledData.shape; if isinstance(dataSizeSource, basestring): dataSizeSource = io.dataSize(dataSizeSource); dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = resampleDataSize(dataSizeSource = dataSizeSource, dataSizeSink = dataSizeSink, resolutionSource = resolutionSource, resolutionSink = resolutionSink, orientation = orientation); #print (dataSizeSource, dataSizeSink, resolutionSource, resolutionSink ) dataSizeSinkI = orientDataSizeInverse(dataSizeSink, orientation); #flip axes back and permute inversely if not orientation is None: if orientation[0] < 0: resampledData = resampledData[::-1, :, :]; if orientation[1] < 0: resampledData = resampledData[:, ::-1, :]; if orientation[2] < 0: resampledData = resampledData[:, :, ::-1]; #reorient peri = inverseOrientation(orientation); peri = orientationToPermuation(peri); resampledData = resampledData.transpose(peri); # upscale in z interpolation = fixInterpolation(interpolation); resampledDataXY = numpy.zeros((dataSizeSinkI[0], dataSizeSinkI[1], dataSizeSource[2]), dtype = resampledData.dtype); for i in range(dataSizeSinkI[0]): if verbose and i % 25 == 0: print "resampleDataInverse: processing %d/%d" % (i, dataSizeSinkI[0]) #cv2.resize takes reverse order of sizes ! resampledDataXY[i ,:, :] = cv2.resize(resampledData[i,:,:], (dataSizeSource[2], dataSizeSinkI[1]), interpolation = interpolation); # upscale x, y in parallel if io.isFileExpression(source): files = source; else: if processingDirectory == None: processingDirectory = tempfile.mkdtemp(); files = os.path.join(sink[0], 'resample_\d{4}.tif'); io.writeData(files, resampledDataXY); nZ = dataSizeSource[2]; pool = multiprocessing.Pool(processes=processes); argdata = []; for i in range(nZ): argdata.append( (source, fl.fileExpressionToFileName(files, i), dataSizeSource, interpolation, i, nZ) ); pool.map(_resampleXYParallel, argdata); if io.isFileExpression(source): return source; else: data = io.convertData(files, source); if cleanup: shutil.rmtree(processingDirectory); return data;