def open_path(self, path): if os.path.isfile(path): # remove exitings layers from napari viewer.layers.select_all() viewer.layers.remove_selected() # get the metadata md, addmd = imf.get_metadata(path) # add the metadata and adapt the table display mdbrowser.update_metadata(md) mdbrowser.update_style() use_dask = checkbox.cbox.isChecked() print('Use Dask : ', use_dask) # get AICSImageIO object img = AICSImage(path) if use_dask: stack = img.dask_data if not use_dask: stack = img.get_image_data() # add the image stack to the napari viewer show_image_napari(stack, md, blending='additive', gamma=0.85, rename_sliders=True)
def open_path(self, path): if os.path.isfile(path): # remove exiting layers from napari viewer.layers.select_all() viewer.layers.remove_selected() # get the metadata md, addmd = imf.get_metadata(path) # get AICSImageIO object img = AICSImage(path) stack = img.get_image_data() add_napari(stack, md, blending='additive', gamma=0.85, rename_sliders=True)
def __getitem__(self, idx): img_path = self.img_paths_list[idx] image = skimage.io.imread(img_path) if self.metadata_path is not None: tree = ET.parse(self.metadata_path) root = tree.getroot() omexml = ET.tostring(root, encoding=None, method="xml") omemd = omexmlClass.OMEXML(omexml) md = get_metadata_ometiff(img_path, omemd) elif self.metadata_path is None: # get metadata from image if no metadata file found md, additional_mdczi = get_metadata(img_path) # FUTURE IMPLEMENTATION if not .ome.tiff or .czi, check if metadata file in folder # if md == None: # # parent_folder = os.path.dirname(img_path) # for fname in os.listdir(parent_folder): # if fname.endswith('.xml'): # xml_path = os.path.join(parent_folder,fname) # tree = ET.parse(xml_path) # root = tree.getroot() # omexml = ET.tostring(root, encoding=None, method='xml') # omemd = omexmlClass.OMEXML(omexml) # md = get_metadata_ometiff(img_path, omemd) # break if md is not None: return img_path, image, md elif md is None: raise ValueError("No metadata found.")
from lxml import etree #from aicspylibczi import CziFile #filename = r"testdata\WP96_4Pos_B4-10_DAPI.czi" filename = r'testdata\WP96_2Pos_B2+B4_S=2_T=2_Z=4_C=3_X=512_Y=256.czi' savename = filename.split('.')[0] + '.ome.tiff' #czi = CziFile(filename) # Get the shape of the data, the coordinate pairs are (start index, size) # print(czi.dims_shape()) # print(czi.dims) # print(czi.size) # get the metadata md, additional_mdczi = imf.get_metadata(filename) # remove the S dimension from the dimstring ometiff_dimstring = md['Axes_aics'].replace('S', '') # get AICSImageIO object using the python wrapper for libCZI img = AICSImage(filename) with tifffile.TiffWriter(savename, append=False) as tif: for s in progressbar.progressbar(range(img.shape[0]), redirect_stdout=True): # get the 5d image stack image5d = img.get_image_data("TZCYX", S=s) # write scene as OME-TIFF series
dims = ['R', 'I', 'M', 'H', 'V', 'B', 'S', 'T', 'C', 'Z', 'Y', 'X', '0'] dims_dict = {} for d in dims: dims_dict[d] = dimstring.find(d) dimindex_list.append(dimstring.find(d)) numvalid_dims = sum(i > 0 for i in dimindex_list) return dims_dict, dimindex_list, numvalid_dims filename = r"C:\Temp\input\DTScan_ID4.czi" md, addmd = imf.get_metadata(filename) czi = CziFile(filename) # Get the shape of the data, the coordinate pairs are (start index, size) dimensions = czi.dims_shape() print(dimensions) print(czi.dims) print(czi.size) print(czi.is_mosaic()) # True # Mosaic files ignore the S dimension and use an internal mIndex to reconstruct, the scale factor allows one to generate a manageable image mosaic_data = czi.read_mosaic(C=0, scale_factor=1) print('CZI Mosaic Data Shape : ', mosaic_data.shape) md = {} md['SizeS'] = 1
def execute(imagefile, chindex_nucleus=0, sd_modelbasedir='stardist_models', sd_modelfolder='2D_versatile_fluo', prob_th=0.5, ov_th=0.3, minsize_nuc=20, maxsize_nuc=5000, norm=True, norm_pmin=1, norm_pmax=99.8, norm_clip=False, correct_ome=True): """Main function to run the stardist object segmentation and measure the object parameters. :param imagefile: filename of the current image :type imagefile: str :param chindex_nucleus: channel index with nucleus, defaults to 1 :type chindex_nucleus: int, optional :param sd_modelbasedir: stardist model basedirectory, defaults to 'stardist_models' :type sd_modelbasedir: str, optional :param sd_modelfolder: stardist model folder inside basedirectory, defaults to '2D_versatile_fluo' :type sd_modelfolder: str, optional :param prob_th: probability threshold, defaults to 0.5 :type prob_th: float, optional :param ov_th: overlap threshold, defaults to 0.3 :type ov_th: float, optional :param minsize_nuc: minimum size of objects [pixel], defaults to 20 :type minsize_nuc: int, optional :param maxsize_nuc: maximum size of objects [pixel], defaults to 5000 :type maxsize_nuc: int, optional :param norm: normalize images, defaults to True :type norm: bool, optional :param norm_pmin: minimum percentile for normalization, defaults to 1 :type norm_pmin: int, optional :param norm_pmax: maximum percentile for normalization, defaults to 99.8 :type norm_pmax: float, optional :param norm_clip: clipping for normalization, defaults to False :type norm_clip: bool, optional file :return: (obj_csv, objparams_csv, label_stacks) - filenames for data tables and label5d stack :rtype: tuple """ # show current image path print('Current Image: ', imagefile) # check if file exits print('File : ', imagefile, ' exists: ', os.path.exists(imagefile)) # get the metadata md, additional_mdczi = imf.get_metadata(imagefile, omeseries=0) # check the channel number for the nucleus if chindex_nucleus + 1 > md['SizeC']: print('Selected Channel for nucleus does not exit. Use channel = 1.') chindex_nucleus = 0 # get AICSImageIO object using the python wrapper for libCZI img = AICSImage(imagefile) # define columns names for dataframe cols = ['S', 'T', 'Z', 'C', 'Number'] objects = pd.DataFrame(columns=cols) results = pd.DataFrame() label_stacks = [] # load the stardist model from web # sd_model = sgt.load_stardistmodel(modeltype=sd_modelname) # define basefolder for StarDist models sd_model = sgt.stardistmodel_from_folder(sd_modelbasedir, mdname=sd_modelfolder) dims_dict, dimindex_list, numvalid_dims = imf.get_dimorder(md['Axes_aics']) shape_labelstack = list(md['Shape_aics']) shape_labelstack.pop(dims_dict['S']) # set channel dimension = 1 because we are only interested in the nuclei shape_labelstack[dims_dict['C'] - 1] = 1 # create labelstack for the current scene label5d = np.zeros(shape_labelstack, dtype=np.int16) for s in progressbar.progressbar(range(md['SizeS']), redirect_stdout=False): # for s in range(md['SizeS']): for t in range(md['SizeT']): for z in range(md['SizeZ']): values = { 'S': s, 'T': t, 'Z': z, 'C': chindex_nucleus, 'Number': 0 } # read a single 2d image image2d = img.get_image_data("YX", S=s, T=t, Z=z, C=chindex_nucleus) # get the segmented image using StarDist 2D mask = sgt.segment_nuclei_stardist(image2d, sd_model, prob_thresh=prob_th, overlap_thresh=ov_th, norm=norm, norm_pmin=norm_pmin, norm_pmax=norm_pmax, norm_clip=norm_clip) # clear border objects mask = segmentation.clear_border(mask) # add mask to the label5d stack label5d[t, z, 0, :, :] = mask # measure region properties to_measure = ('label', 'area', 'centroid', 'max_intensity', 'mean_intensity', 'min_intensity', 'bbox') # measure the specified parameters store in dataframe props = pd.DataFrame( measure.regionprops_table( mask, intensity_image=image2d, properties=to_measure)).set_index('label') # filter objects by size props = props[(props['area'] >= minsize_nuc) & (props['area'] <= maxsize_nuc)] # add well information for CZI metadata try: props['WellId'] = md['Well_ArrayNames'][s] props['Well_ColId'] = md['Well_ColId'][s] props['Well_RowId'] = md['Well_RowId'][s] except (IndexError, KeyError) as error: print('Error:', error) print('Well Information not found. Using S-Index.') props['WellId'] = s props['Well_ColId'] = s props['Well_RowId'] = s show_heatmap = False # add plane indices props['S'] = s props['T'] = t props['Z'] = z props['C'] = chindex_nucleus # count the number of objects values['Number'] = props.shape[0] # values['Number'] = len(regions) - 1 if verbose: print('Well:', props['WellId'].iloc[0], ' Objects: ', values['Number']) # update dataframe containing the number of objects objects = objects.append(pd.DataFrame(values, index=[0]), ignore_index=True) results = results.append(props, ignore_index=True) # save stack for every scene sid = imf.addzeros(s) # keep in mind to use the "pure" filename because inside the container # writing to /input/... is forbidden name_scene = os.path.basename(imagefile).split('.')[0] + \ '_S' + sid + '.' + 'ome.tiff' label_stacks.append(name_scene) if save_resultstack: # save file as OME-TIFF fs = ott.write_ometiff_aicsimageio(name_scene, label5d, md, reader='aicsimageio', overwrite=True) if correct_ome: old = ("2012-03", "2013-06", r"ome/2016-06") new = ("2016-06", "2016-06", r"OME/2016-06") ott.correct_omeheader(name_scene, old, new) # reorder dataframe with single objects new_order = list(results.columns[-7:]) + list(results.columns[:-7]) results = results.reindex(columns=new_order) # close the AICSImage object at the end img.close() # save the results # get filename without extension basename_woext = os.path.basename(imagefile).split('.')[0] # define name for CSV tables obj_csv = basename_woext + '_obj.csv' objparams_csv = basename_woext + '_objparams.csv' # save the DataFrames as CSV tables objects.to_csv(obj_csv, index=False, header=True, decimal='.', sep=',') print('Saved Object Table as CSV :', obj_csv) results.to_csv(objparams_csv, index=False, header=True, decimal='.', sep=',') print('Saved Object Parameters Table as CSV :', objparams_csv) return (obj_csv, objparams_csv, label_stacks)
def get_czi_planetable(czifile): # get the czi object using pylibczi czi = aicspylibczi.CziFile(czifile) # get the czi metadata md, add = imf.get_metadata(czifile) # initialize the plane table df_czi = define_czi_planetable() # define subblock counter sbcount = -1 # create progressbar #total = md['SizeS'] * md['SizeM'] * md['SizeT'] * md['SizeZ'] * md['SizeC'] #pbar = tqdm(total=total) #pbar = progressbar.ProgressBar(max_value=total) # in case the CZI has the M-Dimension if md['czi_isMosaic']: for s, m, t, z, c in product(range(md['SizeS']), range(md['SizeM']), range(md['SizeT']), range(md['SizeZ']), range(md['SizeC'])): sbcount += 1 # print(s, m, t, z, c) info = czi.read_subblock_rect(S=s, M=m, T=t, Z=z, C=c) # read information from subblock sb = czi.read_subblock_metadata(unified_xml=True, B=0, S=s, M=m, T=t, Z=z, C=c) try: time = sb.xpath('//AcquisitionTime')[0].text timestamp = dt.parse(time).timestamp() except IndexError as e: timestamp = 0.0 try: xpos = np.double(sb.xpath('//StageXPosition')[0].text) except IndexError as e: xpos = 0.0 try: ypos = np.double(sb.xpath('//StageYPosition')[0].text) except IndexError as e: ypos = 0.0 try: zpos = np.double(sb.xpath('//FocusPosition')[0].text) except IndexError as e: zpos = 0.0 df_czi = df_czi.append( { 'Subblock': sbcount, 'Scene': s, 'Tile': m, 'T': t, 'Z': z, 'C': c, 'X [micron]': xpos, 'Y [micron]': ypos, 'Z [micron]': zpos, 'Time [s]': timestamp, 'xstart': info[0], 'ystart': info[1], 'xwidth': info[2], 'ywidth': info[3] }, ignore_index=True) if not md['czi_isMosaic']: """ for s, t, z, c in it.product(range(md['SizeS']), range(md['SizeT']), range(md['SizeZ']), range(md['SizeC'])): """ for s, t, z, c in product(range(md['SizeS']), range(md['SizeT']), range(md['SizeZ']), range(md['SizeC'])): sbcount += 1 info = czi.read_subblock_rect(S=s, T=t, Z=z, C=c) # read information from subblocks sb = czi.read_subblock_metadata(unified_xml=True, B=0, S=s, T=t, Z=z, C=c) try: time = sb.xpath('//AcquisitionTime')[0].text timestamp = dt.parse(time).timestamp() except IndexError as e: timestamp = 0.0 try: xpos = np.double(sb.xpath('//StageXPosition')[0].text) except IndexError as e: xpos = 0.0 try: ypos = np.double(sb.xpath('//StageYPosition')[0].text) except IndexError as e: ypos = 0.0 try: zpos = np.double(sb.xpath('//FocusPosition')[0].text) except IndexError as e: zpos = 0.0 df_czi = df_czi.append( { 'Subblock': sbcount, 'Scene': s, 'Tile': 0, 'T': t, 'Z': z, 'C': c, 'X [micron]': xpos, 'Y [micron]': ypos, 'Z [micron]': zpos, 'Time [s]': timestamp, 'xstart': info[0], 'ystart': info[1], 'xwidth': info[2], 'ywidth': info[3] }, ignore_index=True) # normalize timestamps df_czi = imf.norm_columns(df_czi, colname='Time [s]', mode='min') # cast data types df_czi = df_czi.astype( { 'Subblock': 'int32', 'Scene': 'int32', 'Tile': 'int32', 'T': 'int32', 'Z': 'int32', 'C': 'int16', 'xstart': 'int32', 'xstart': 'int32', 'ystart': 'int32', 'xwidth': 'int32', 'ywidth': 'int32' }, copy=False, errors='ignore') return df_czi
"""Add scaling factors to the metadata dictionary :param metadata: dictionary with CZI or OME-TIFF metadata :type metadata: dict :return: dictionary with additional keys for scling factors :rtype: dict """ # set default scale factore to 1 scalefactors = {'xy': 1.0, 'zx': 1.0} try: # get the factor between XY scaling scalefactors['xy'] = metadata['XScale'] / metadata['YScale'] # get the scalefactor between XZ scaling scalefactors['zx'] = metadata['ZScale'] / metadata['YScale'] except KeyError as e: print('Key not found: ', e) return scalefactors #filename_czi = r"C:\Users\m1srh\Documents\GitHub\ipy_notebooks\Read_OMETIFF_CZI\testdata\CellDivision_T=10_Z=15_CH=2_DCV_small.czi" filename_czi = r'E:\tuxedo\testpictures\Testdata_Zeiss\celldivision\CellDivision_T=10_Z=15_CH=2_DCV_small.czi' print('---------- CZI ----------') md_czi, addmd_czi = imf.get_metadata(filename_czi) sf_czi = get_scalefactor(md_czi) print(md_czi['ChannelColors'])