def nd2_reader(path: str) -> List[LayerData]: ndx = ND2Reader(path) sizes = ndx.sizes if 't' not in sizes: sizes['t'] = 1 if 'z' not in sizes: sizes['z'] = 1 if 'c' not in sizes: sizes['c'] = 1 ndx.bundle_axes = 'zcyx' ndx.iter_axes = 't' n = len(ndx) shape = (sizes['t'], sizes['z'], sizes['c'], sizes['y'], sizes['x']) image = np.zeros(shape, dtype=np.float32) for i in range(n): image[i] = ndx.get_frame(i) params = { "channel_axis": 2, "name": "My ND2 image", } return [(image, params)]
def nd2_info_to_df(data_path): nd2_infos = [] nd2_files = get_nd2_files(data_path) for file in nd2_files: with ND2Reader(file) as nd2_data: nd2_infos.append(get_nd2_info(nd2_data)) return pd.DataFrame(nd2_infos)
def single_nd2_to_tif(file, mag='10X', zproject=False, file_pattern=None): if file_pattern is None: file_pattern = [(r'(?P<cycle>c[0-9]+)?/?' '(?P<dataset>.*)?/?' 'Well(?P<well>[0-6]*)_' '(Point[A-H][0-9]*_(?P<site>[0-9]*)_)?' 'Channel((?P<channel_1>[^_,]+)(_[^,]*)?)?,?' '((?P<channel_2>[^_,]+)(_[^,]*)?)?,?' '((?P<channel_3>[^_,]+)(_[^,]*)?)?,?' '((?P<channel_4>[^_,]+)(_[^,]*)?)?,?' '((?P<channel_5>[^_,]+)(_[^_]*)?)?' '_Seq([0-9]+).nd2')] description = ops.filenames.parse_filename(file, custom_patterns=file_pattern) description['ext'] = 'tif' description['mag'] = mag try: description['subdir'] = 'preprocess/' + description['cycle'] except: description['subdir'] = 'preprocess' description['dataset'] = None with ND2Reader(file) as image: image.iter_axes = 'c' image.bundle_axes = 'xy' filename = ops.filenames.name_file(description) if zproject: output = np.array([np.max(im, axis=0) for im in image]) else: output = np.array([im for im in image]) save_stack(filename, output)
def load_nd2(path): """Read in an .nd2-formatted file. **NOTE**: This function is optimized to work with Bassik lab Nikon scope data, and therefore may not work as desired with data from other sources. It requires the metadata attribute of the file to contain 'fields_of_view', 'z_levels', 'width', 'height', and 'channels' variables. Arguments: path (str): Path to the .nd2-formatted file. Returns a tuple consisting of two components: - a 5D NumPy array with shape [IMG,C,Z,Y,X] - a tuple of length C with integers representing the excitation wavelengths for each channel, in the same order as in the numpy array C axis. For example, (405, 488, 561) """ im = ND2Reader(path) n_fields = len(im.metadata['fields_of_view']) z_slices = len(im.metadata['z_levels']) height = im.metadata['height'] width = im.metadata['width'] channels = tuple(int(c[0:3]) for c in im.metadata['channels']) n_channels = len(channels) im_arr = np.empty((n_fields, n_channels, z_slices, height, width)) for f in range(0, n_fields): for c in range(0, n_channels): for z in range(0, z_slices): im_arr[f, c, z, :, :] = im.get_frame_2D(v=f, c=c, z=z) return (im_arr, channels)
def get_nd2reader_nd2_vol(path, c, frame): with ND2Reader(path) as nd2_data: nd2_data.default_coords['c'] = c nd2_data.bundle_axes = ('z', 'y', 'x') v = nd2_data.get_frame(frame) v = np.array(v) return v
def nd2_read(fn): '''Reads raw .nd2 file with full bit depth for pixel intensity extraction. Reads the conversion for pixels to microns for the image from metadata.''' img = ND2Reader(fn) pix_micron = img.metadata['pixel_microns'] img = np.array(img[0]) return img, pix_micron
def __init__(self, file_name, start_iter=0, stop_iter=None): self.file_name = file_name if '.nd2' in file_name: self.ext = 'nd2' self.reader = ND2Reader(file_name) elif ('.tif' in file_name) or ('.tiff' in file_name): self.ext = 'tif' self.reader = tifffile.TiffFile(file_name) elif ('.czi' in file_name): self.ext = 'czi' self.reader = CziFile(file_name) else: raise RuntimeError("Image format %s " \ "not recognized" % \ os.path.splitext(file_name)[1]) # Record the shape of the movie self.n_frames, self.height, self.width = \ self.get_shape() # Set the defaults for iterating over this # object self.start_iter = start_iter self.stop_iter = stop_iter if self.stop_iter is None: self.stop_iter = self.n_frames
def extract_all_files(self): nd2_files = self.extract_all_meta() meta_handle = pandas_hdf5_handler(self.headpath + "/metadata.hdf5") meta_df = meta_handle.read_df("data", read_metadata=True) channels = meta_df.metadata["channels"] y_dim = meta_df.metadata["height"] x_dim = meta_df.metadata["width"] ttl_indices = len(meta_df) chunk_shape = (1, meta_df.metadata['height'], meta_df.metadata['width']) chunk_bytes = (2 * np.multiply.accumulate(np.array(chunk_shape))[-1]) chunk_cache_mem_size = 2 * chunk_bytes with h5py_cache.File( self.hdf5path + "/extracted.hdf5", "w", chunk_cache_mem_size=chunk_cache_mem_size) as h5pyfile: for c, channel in enumerate(channels): hdf5_dataset = h5pyfile.create_dataset( str(channel), (ttl_indices, y_dim, x_dim), chunks=chunk_shape, dtype='uint16') for file_idx in meta_df["file_idx"].unique(): nd2path = self.headpath + "/" + nd2_files[file_idx] with ND2Reader(nd2path) as nd2file: file_df = meta_df[meta_df["file_idx"] == file_idx] for idx, item in file_df.iterrows(): t = item["timepoint"] v = item["fov"] nd2_image = nd2file.get_frame_2D(c=c, t=t, v=v) hdf5_dataset[idx, :, :] = nd2_image
def extract_nd2(self): # check disk if self._disk_capacity_check() == False: raise SystemError("No enough disk capacity!") folder, file = os.path.split(self.file) name, ext = os.path.splitext(file) saveDir = os.path.join(folder, name, 'raw') saveDir8 = os.path.join(folder, name, '8-bit') if os.path.exists(saveDir) == False: os.makedirs(saveDir) if os.path.exists(saveDir8) == False: os.makedirs(saveDir8) # with open(os.path.join(saveDir, 'log.txt'), 'w') as f: # f.write('nd2Dir = ' + str(nd2Dir) + '\n') # with open(os.path.join(saveDir8, 'log.txt'), 'w') as f: # f.write('nd2Dir = ' + str(nd2Dir) + '\n') with ND2Reader(self.file) as images: for num, image in enumerate(images): # img8 = (image/2**3).astype('uint8') # 8-bit image now are only used for visualization, i.e. convert to videos # therefore, they are autocontrasted on each frame. io.imsave(os.path.join(saveDir8, '{:05d}.tif'.format(num)), to8bit(image)) # if image.mean() > threshold and remove == True: # corrected = illumination_correction(image, avg) # else: # corrected = image io.imsave(os.path.join(saveDir, '%05d.tif' % num), image, check_contrast=False)
def visualize_locs( nd2_file, frame_idx, window_size, error_rate, psf_scale, pixel_size_um, wavelength, na ): ''' Visualize localizations to check that the localization algorithm is working correctly. ''' f = ND2Reader(nd2_file) image_2d = f.get_frame_2D(t = frame_idx) locs, detection_parameters = localize( image_2d, window_size = window_size, error_rate = error_rate, psf_scale = psf_scale, pixel_size_um = pixel_size_um, wavelength = wavelength, NA = na, plot = True )
def __init__(self, path, start=None, stop=None, **subregion): assert os.path.isfile(path), "ImageReader.__init__: " \ "path %s does not exist" % path self.path = path if '.nd2' in path: self.ext = '.nd2' self._reader = ND2Reader(path) elif ('.tif' in path) or ('.tiff' in path): self.ext = '.tif' self._reader = tifffile.TiffFile(path) #elif ('.czi' in path): # self.ext = '.czi' # self._reader = CziFile(path) else: raise RuntimeError("Image format %s not recognized" % \ os.path.splitext(path)[1]) # Record movie shape self.n_frames, self.height, self.width = self.shape # Set defaults for iteration if start is None: start = 0 if stop is None: stop = self.n_frames self.start = start self.stop = stop
def read(direct, value): """ Reads the images from nd2 file and saves the dataframe Parameters: -------------------------- direct : string for the directory name value : string for the nd2 file name """ with ND2Reader(direct + "/" + value) as images: print(colors.yellow|"directory " + direct) #iterations of the images in the nd2 file # ERRORE QUI############################################################# images.iter_axes = "vt" fields = images.sizes["v"] rframes = images.sizes["t"] print(fields) for field in range(fields): for frame in range(100): #making the image of type uint8 im = images[frame + rframes*field] plt.imsave("im.png",im) im_gray = cv2.imread("im.png") im_gray = cv2.cvtColor(im_gray, cv2.COLOR_BGR2GRAY) im_gray = cl.adaptive_contrast_enhancement(im_gray) Faster.to_dataframe(direct, im_gray,frame, field) #status bar print("field " + str(field) +": ["+"#"*int(frame/100*20)+"-"*int(20-int(frame/100*20))+"] "+str(int(frame/100*100))+"% ", end="\r") print("field " + str(field) +": ["+"#"*20+"] 100%")
def open_nd2(): nikon_nd2 = easygui.fileopenbox() def nothing(x): pass with ND2Reader(nikon_nd2) as images: nikon_file = images z, x, y = np.max(images.metadata['frames']), np.max( images.metadata['width']), np.max(images.metadata['height']) cv2.namedWindow('ImageStack') cv2.namedWindow('ImageStack', cv2.WINDOW_NORMAL) cv2.createTrackbar('Slice', 'ImageStack', 0, z, nothing) while (1): slice = cv2.getTrackbarPos('Slice', 'ImageStack') img = nikon_file[slice - 1] if (np.max(img) - np.min(img)) != 0: img = (img - np.min(img)) / (np.max(img) - np.min(img)) img = cv2.resize(img, (500, 500)) cv2.imshow('ImageStack', img) cv2.namedWindow('ImageStack', cv2.WINDOW_NORMAL) cv2.resizeWindow('ImageStack', 500, 500) k = cv2.waitKey(1) & 0xFF if k == 27: cv2.destroyAllWindows() quit(1)
def nd2_reader(path): """Take a path or list of paths and return a list of LayerData tuples. Readers are expected to return data as a list of tuples, where each tuple is (data, [add_kwargs, [layer_type]]), "add_kwargs" and "layer_type" are both optional. Parameters ---------- path : str or list of str Path to file, or list of paths. Returns ------- layer_data : list of tuples A list of LayerData tuples where each tuple in the list contains (data, metadata, layer_type), where data is a numpy array, metadata is a dict of keyword arguments for the corresponding viewer.add_* method in napari, and layer_type is a lower-case string naming the type of layer. Both "meta", and "layer_type" are optional. napari will default to layer_type=="image" if not provided """ with ND2Reader(path) as nd2_data: channels = nd2_data.metadata['channels'] n_timepoints = nd2_data.sizes['t'] z_depth = nd2_data.sizes['z'] frame_shape = (z_depth, *nd2_data.frame_shape) frame_dtype = nd2_data._dtype nd2vol = tz.curry(get_nd2reader_nd2_vol) layer_list = get_layer_list(channels, nd2vol, path, frame_shape, frame_dtype, n_timepoints) return layer_list
def get_metadata(path): with ND2Reader(path) as image: meta = image.metadata raw_meta = image.parser._raw_metadata.image_metadata raw_meta_seq = image.parser._raw_metadata.image_metadata_sequence # Scale try: z_scale = (raw_meta[b'SLxExperiment'][b'ppNextLevelEx'][b''] [b'uLoopPars'][b'dZStep']) except KeyError: z_scale = 4 # TODO(jni): not a good default in general, but needed x_scale = y_scale = meta['pixel_microns'] # sampling interval is in ms, we convert to s t_scale = meta['experiment']['loops'][0]['sampling_interval'] / 1e3 scale = [1, z_scale, -y_scale, -x_scale] # Translation centre_x = raw_meta_seq[b'SLxPictureMetadata'][b'dXPos'] centre_y = raw_meta_seq[b'SLxPictureMetadata'][b'dYPos'] # z appears to be interpreted as the origin by Imaris... # not sure this is correct... origin_z = raw_meta_seq[b'SLxPictureMetadata'][b'dZPos'] size_x = image.sizes['x'] size_y = image.sizes['y'] origin_t = 0 # TODO(jni): find a good way to set timepoint offset origin = ( origin_t, origin_z, centre_y + size_y / 2 * y_scale, centre_x + size_x / 2 * x_scale, ) return {'scale': scale, 'translate': origin}
def convert_nd2_to_ome_tiff(path, outpath): """ Convert an nd2 file to an .ome.tif by saving each tile under a separate series. Uses the BigTIFF format to write the new .ome.tiff file. """ path_to_nd2 = str(path) omexml = get_editable_omexml(path_to_nd2) limit = omexml.image_count xml_dict = tifffile.xml2dict(omexml.to_xml()) with ND2Reader(path_to_nd2) as images: print(images.sizes) images.iter_axes = 'v' images.bundle_axes = "zcyx" with tifffile.TiffWriter(outpath, bigtiff=True) as tif: for series, tile in enumerate(images): # TODO: seems like, for some weird reason, the tiles are rotated incorrectly? Why? # Maybe it has to do with the order of the bundle axes rotated_tile = np.rot90(tile, k=1, axes=(2, 3)) series_metadata = xml_dict["OME"]["Image"][series] tif.save(rotated_tile.astype(np.uint16), contiguous=False, metadata=series_metadata)
def get_metadata(self, manual_num_frames=None, manual_num_fovs=None): # Manual numbers are for broken .nd2 files (from when Elements crashes) nd2file = ND2Reader(self.nd2filename) exp_metadata = copy.copy(nd2file.metadata) wanted_keys = [ 'height', 'width', 'date', 'fields_of_view', 'frames', 'z_levels', 'total_images_per_channel', 'channels', 'pixel_microns', 'num_frames', 'experiment' ] exp_metadata = dict([(k, exp_metadata[k]) for k in wanted_keys if k in exp_metadata]) exp_metadata["failed_file"] = False if manual_num_frames is not None: exp_metadata["frames"] = list(range(manual_num_frames)) exp_metadata["num_frames"] = len(exp_metadata["frames"]) exp_metadata["failed_file"] = True if manual_num_fovs is not None: exp_metadata["fields_of_view"] = list(range(manual_num_fovs)) exp_metadata["failed_file"] = True exp_metadata["num_fovs"] = len(exp_metadata['fields_of_view']) exp_metadata["settings"] = self.get_imaging_settings(nd2file) if not self.ignore_fovmetadata: fov_metadata = self.make_fov_df(nd2file, exp_metadata) nd2file.close() return exp_metadata, fov_metadata else: nd2file.close() return exp_metadata
def writehdf5(fovnum, num_entries, timepoint_list, file_idx, num_fovs): with ND2Reader(self.nd2filename) as nd2file: y_dim = self.metadata['height'] x_dim = self.metadata['width'] with h5py_cache.File( self.hdf5path + "/hdf5_" + str(file_idx) + ".hdf5", "w", chunk_cache_mem_size=self.chunk_cache_mem_size ) as h5pyfile: for i, channel in enumerate(self.metadata["channels"]): hdf5_dataset = h5pyfile.create_dataset(str(channel),\ (num_entries,y_dim,x_dim), chunks=self.chunk_shape, dtype='uint16') # If Elements crashed nd2reader does not index into the file correctly, this is a hard fix if self.metadata["failed_file"]: for j in range(len(timepoint_list)): frame = timepoint_list[j] nd2_image = nd2file.get_frame_2D( c=i, t=0, v=fovnum + frame * num_fovs) hdf5_dataset[j, :, :] = nd2_image else: for j in range(len(timepoint_list)): frame = timepoint_list[j] nd2_image = nd2file.get_frame_2D(c=i, t=frame, v=fovnum) hdf5_dataset[j, :, :] = nd2_image return "Done."
def __read_raw_image(self): if self.input_path.suffix == '.nd2': images = ND2Reader(str(self.input_path.absolute())) self.shape[:2] = images.frame_shape self.shape[2] = images.sizes['z'] self.positions[2] = np.array(images.metadata['z_coordinates']) self.positions[2] += - min(self.positions[2]) for n in (0, 1): self.positions[n] = np.linspace(0, images.metadata['pixel_microns']*self.shape[n], num=self.shape[n], endpoint=False) if 'c' in images.default_coords: if type(self.channel) == int: images.default_coords['c'] = self.channel else: images.default_coords['c'] = images.metadata['channels'].index(self.channel) self.z_spacing = np.average(np.diff(self.positions[2])) self.xy_spacing = images.metadata['pixel_microns'] else: images = pims.open(str(self.input_path.absolute())) self.shape[:2] = images.frame_shape self.shape[2] = len(images) for n in range(3): self.positions[n] = np.linspace(0, self.voxel_size[n]*self.shape[n], num=self.shape[n], endpoint=False) self.z_spacing = self.voxel_size[2] self.xy_spacing = self.voxel_size[0] # scale all images from 0 to 1 and store it at the selected resolution raw_image = np.zeros((self.shape[2], self.shape[0], self.shape[1]), dtype=self.dtype) raw_image[:] = (images - np.min(images))/(np.max(images)-np.min(images)) images.close() return raw_image
def nd2_to_tif(input_filename, meta=True): # add parse_filename function to get info from nd2 name and convert to tif filename info = ops.filenames.parse_filename(input_filename) file_description = {} for k, v in sorted(info.items()): file_description[k] = v file_description['ext'] = 'tif' # file_description['subdir']=file_description['plate']+'_tif/'+file_description['mag']+'_'+file_description['cycle'] # file_description['subdir']=file_description['plate']+file_description['mag']+'_'+file_description['cycle'] file_description['subdir'] = 'preprocess/' + file_description[ 'mag'] + '_' + file_description['cycle'] with ND2Reader(input_filename) as images: images.iter_axes = 'v' axes = 'xy' if 'c' in images.axes: axes = 'c' + axes if 'z' in images.axes: axes = 'z' + axes images.bundle_axes = axes if 'z' in images.axes: for site, image in zip(images.metadata['fields_of_view'], images): image = image.max(axis=0) output_filename = ops.filenames.name_file(file_description, site=str(site)) save(output_filename, image[:]) else: for site, image in zip(images.metadata['fields_of_view'], images): output_filename = ops.filenames.name_file(file_description, site=str(site)) save(output_filename, image[:]) # METADATA EXTRACTION if meta == True: file_description['subdir'] = 'metadata/' well_metadata = [{ 'filename': ops.filenames.name_file(file_description, site=str(site)), 'field_of_view': site, 'x': images.metadata['x_data'][site], 'y': images.metadata['y_data'][site], 'z': images.metadata['z_data'][site], 'pfs_offset': images.metadata['pfs_offset'][0], 'pixel_size': images.metadata['pixel_microns'] } for site in images.metadata['fields_of_view']] metadata_filename = ops.filenames.name_file(file_description, tag='metadata', ext='pkl') pd.DataFrame(well_metadata).to_pickle(metadata_filename)
def get_nd2reader_nd2_vol(path, c, frame): with ND2Reader(path) as nd2_data: if 'c' in nd2_data.axes: nd2_data.default_coords['c'] = c nd2_data.bundle_axes = [ax for ax in 'zyx' if ax in nd2_data.axes] v = nd2_data.get_frame(frame) v = np.array(v, ndmin=4) return v
def __init__(self, nd2_filename): self._file = ND2Reader(nd2_filename) self._micron_per_pixel = self._file.metadata["pixel_microns"] self.background_roi = self._get_roi('background') self.reference_roi = self._get_roi('reference') self.stimulation_roi = self._get_roi('stimulation') self.bleach_time_index = self._get_bleach_time_index() self.timesteps = self._get_timesteps()
def get_image(file_path, channel): with ND2Reader(file_path) as images: images.bundle_axes = 'zyx' images.default_coords['c'] = channel - 1 images.iter_axes = 'v' for i, fov in enumerate(images): yield i, fov
def get_metadata(self): nd2file = ND2Reader(self.nd2filename) exp_metadata = copy.copy(nd2file.metadata) exp_metadata["num_fovs"] = len(exp_metadata['fields_of_view']) exp_metadata["settings"] = self.get_imaging_settings(nd2file) fov_metadata = self.make_fov_df(nd2file) nd2file.close() return exp_metadata, fov_metadata
def nd2_to_hdf(file, mag='20X', zproject=True, fov_axes='czxy'): nd2_file_pattern = [(r'(?P<dataset>.*)/' 'Well(?P<well>[A-H][0-9]*)_' 'Channel((?P<channel_1>[^_,]+)(_[^,]*)?)?,?' '((?P<channel_2>[^_,]+)(_[^,]*)?)?,?' '((?P<channel_3>[^_,]+)(_[^,]*)?)?,?' '((?P<channel_4>[^_,]+)(_[^,]*)?)?,?' '((?P<channel_5>[^_,]+)(_[^_]*)?)?' '_Seq([0-9]+).nd2')] description = ops.filenames.parse_filename( file, custom_patterns=nd2_file_pattern) description['ext'] = 'hdf' description['mag'] = mag description['subdir'] = 'preprocess' description['dataset'] = None channels = [ ch for key, ch in description.items() if key.startswith('channel') ] if len(channels) == 1: ## this is not great: find if c in fov_axes, etc... fov_axes = fov_axes[1:] with ND2Reader(file) as images: images.iter_axes = 'v' images.bundle_axes = fov_axes well_metadata = [] for site, image in zip(images.metadata['fields_of_view'], images): if zproject: z_axis = fov_axes.find('z') image = image.max(axis=z_axis) filename = ops.filenames.name_file(description, site=str(site)) save_hdf_image(filename, image[:]) well_metadata = [{ 'filename': ops.filenames.name_file(description, site=str(site)), 'field_of_view': site, 'x': images.metadata['x_data'][site], 'y': images.metadata['y_data'][site], 'z': images.metadata['z_data'][site], 'pfs_offset': images.metadata['pfs_offset'][0], 'pixel_size': images.metadata['pixel_microns'] } for site in images.metadata['fields_of_view']] metadata_filename = ops.filenames.name_file(description, tag='metadata', ext='pkl') pd.DataFrame(well_metadata).to_pickle(metadata_filename)
def motion_correction(filename_list=None, save_filename=None, save_foldername='motion_corrected', as_group = True, save_format='tif', **kwargs): if filename_list is None: root = tk.Tk() root.withdraw() filename_list = tk.filedialog.askopenfilenames() filename_list = list(filename_list) if len(filename_list)==1: print("\033[1;32;40mProcessing %s\033[0m" % filename_list[0]) else: current_foldername = os.path.dirname(filename_list[0]) print("\033[1;32;40mProcessing files in %s\033[0m" % current_foldername) for filename in tqdm(filename_list, desc='Files'): [_, file_extension] = os.path.splitext(filename) if file_extension=='.tif': images = load_tif_tifffile(filename) elif file_extension=='.nd2': images = ND2Reader(filename) else: print("Incorrect file format.") break if as_group: try: [image_shift, _] = calculate_shift(images, ref_image=ref_image, **kwargs) except: [image_shift, ref_image] = calculate_shift(images, **kwargs) else: [image_shift, _] = calculate_shift(images, **kwargs) shifted_images = apply_shift(images, image_shift) current_foldername = os.path.dirname(filename) if save_filename is None: current_filename = os.path.basename(filename) current_save_filename = '/hdd2/test'+'/'+save_foldername+'/m_'+current_filename else: current_save_filename = '/hdd2/test'+'/'+save_foldername+'/'+save_filename [current_save_filename, _] = os.path.splitext(current_save_filename) current_save_filename = current_save_filename+'.'+save_format if os.path.isdir(current_foldername + '/' + save_foldername) is False: os.makedirs(current_foldername + '/' + save_foldername) if save_format=='npy': np.save(current_save_filename, shifted_images, allow_pickle=False) elif save_format == 'hdf5': opened_save_file = h5py.File(current_save_filename, "w") opened_save_file.create_dataset('image_data', data=shifted_images, chunks=True); opened_save_file.close() else: save_tif_pil(shifted_images, current_save_filename)
def main(argv): nd2Filename = '' outputFolder = os.getcwd() zSlice = 0 fov = 0 try: opts, args = getopt.getopt(argv, "hi:o:z:f:") except getopt.GetoptError: print 'extract_images.py -i <nd2Filename> -o <outputFolder> -z <zSlice> -f <fov>' sys.exit(2) for opt, arg in opts: if opt == '-h': print 'extract_images.py -i <nd2Filename> -o <outputFolder> -z <zSlice> -f <fov>' sys.exit() elif opt in ("-i"): nd2Filename = arg elif opt in ("-o"): outputFolder = arg elif opt in ("-z"): zSlice = int(arg) elif opt in ("-f"): fov = int(arg) from nd2reader import ND2Reader from PIL import Image reader = ND2Reader(nd2Filename) parser = reader.parser # Get information about file frames = reader.metadata['frames'] height = reader.metadata['height'] width = reader.metadata['width'] channels = reader.metadata['channels'][0] if not os.path.exists(outputFolder): os.makedirs(outputFolder) # Generate pngs if outputFolder[-1] not in ('/', '\\'): outputFolder = outputFolder + '/' for frame in frames: image_array = parser.get_image_by_attributes(frame, fov - 1, channels, zSlice - 1, height, width) export_filename = "%002d" % frame + ".tif" image_array = image_array.astype(numpy.uint16) image = Image.fromarray(image_array) image.save(outputFolder + export_filename)
def extract_fov(self, fovnum): nd2file = ND2Reader(self.nd2filename) metadata = nd2file.metadata for i, channel in enumerate(nd2file.metadata["channels"]): t_dim = len(nd2file.metadata['frames']) dirpath = self.tiffpath + "/fov_" + str( fovnum) + "/" + channel + "/" self.writedir(dirpath, overwrite=True) for frame in nd2file.metadata['frames']: filepath = dirpath + "t_" + str(frame) + ".tif" nd2_image = nd2file.get_frame_2D(c=i, t=frame, v=fovnum) imsave(filepath, nd2_image) nd2file.close()
def nd2_to_npy(nd2_file: str) -> dict: """Function that returns a dictionary that includes the images for each channel of the .nd2 file and the meta-information""" with ND2Reader(nd2_file) as reader: metadata = reader.metadata width, height, depth = reader.sizes["x"], reader.sizes["y"], reader.sizes["z"] channels = metadata["channels"] image = np.zeros([depth, height, width, depth], dtype=np.float64) for idx, channel in enumerate(channels): reader.default_coords["c"] = idx for i in range(depth): image[i, :, :, idx] = reader[i] data_dict = {"channels": channels, "image": image, "metadata": metadata} return data_dict
def LoadOneImage(self, currentT, currentfov): """This method returns from the nd2 file, the picture requested by the main program as an array. It fixes the fov index and iterates over the time index. """ if not (currentT < self.sizet and currentfov < self.Npos): return None if self.isnd2: with ND2Reader(self.nd2path) as images: try: images.default_coords['v'] = currentfov except ValueError: pass try: images.default_coords['c'] = self.default_channel except ValueError: pass images.iter_axes = 't' im = images[currentT] elif self.issingle: # with pytiff.Tiff(self.nd2path) as handle: # handle.set_page(currentT) # im = handle[:] full = skimage.io.imread(self.nd2path) if full.ndim == 2: im = full elif full.ndim == 3: # num pages should be smaller than x or y dimension, very unlikely not to be the case if full.shape[2] < full.shape[0] and full.shape[ 2] < full.shape[1]: full = np.moveaxis(full, -1, 0) # move last axis to first im = full[currentT] elif self.isfolder: filelist = sorted(os.listdir(self.nd2path)) for f in filelist: if f.startswith('.'): filelist.remove(f) im = skimage.io.imread(self.nd2path + '/' + filelist[currentT]) im = np.pad( im, ((0, self.sizey - im.shape[0]), (0, self.sizex - im.shape[1])), constant_values=0 ) # pad with zeros so all images in the same folder have same size outputarray = np.array(im, dtype=np.uint16) return outputarray