def importImage(img, ppm=None): if ppm: with tiff.TiffFile(img) as tif: images = tif.asarray().astype(float) return images, ppm else: with tiff.TiffFile(img) as tif: images = tif.asarray().astype(float) metadata = tif[0].tags pixel_per_micron = metadata['x_resolution'].value[0] / metadata[ 'x_resolution'].value[1] return images, pixel_per_micron
def load_image(path, type=None, mode=None): """Read image from the passed path and return it in numpy array form. Automatically performs channel mode conversions of the loaded image. Args: path (str): Path to image file. type (str): Value type to return the image as. See image_convtype() for documentation of accepted values. mode (str): Channel mode to return the image as. See image_convmode() for documentation of accepted values. Returns: numpy.ndarray: Image data. """ if not os.path.isfile(path): return None _, ext = os.path.splitext(path.lower()) # Image read if ext == '.tif' or ext == '.tiff': with tifffile.TiffFile(path) as tif: out = tif.asarray() elif ext == '.png': out = imageio.imread(path) else: return None if out is None: raise RuntimeError('File could not be loaded: {0}'.format(path)) out = image_convmode(out, mode) out = image_convtype(out, type) return out
def flat_field(self, ff_image, channel, affix='_FF'): """Flat-Field correction. Parameters ---------- ff_image : str, NumPy array Flat-field image file or NumPy array. channel : str Channel to apply flat-field correction. affix : str Affix for channel name to be appended. Defaults to '_FF' """ if isinstance(ff_image, string_types): flat_field = tff.TiffFile(ff_image).asarray() else: flat_field = ff_image flat_field = flat_field / flat_field.max() # Normalize Flat-Field if isinstance(self._dataframe, dict): ff_dict_df = {} for key in self._dataframe.keys(): ff_df = self._dataframe[key].loc[:, [channel]] ff_dict_df[key] = ff_df / flat_field ff_dict_df[key] = self._rename_coord(ff_dict_df[key], 'c', channel, "%s%s" % (channel, affix)) self.combine(ff_dict_df)
def preprocess(input_dir, output_dir, bfchannel, meta_export, register, png_export): """Run preprocessing on OME-TIFF images in the given directory.""" print("Running on {}".format(input_dir)) # bfchannel = int(bfchannel) if not os.path.exists(output_dir): os.makedirs(output_dir) for file in os.listdir(input_dir): if file.endswith(".ome.tif"): print("Opening: ", os.path.join(input_dir, file)) # Open ome-tiff file with tifffile.TiffFile with tfile.TiffFile(os.path.join(input_dir, file), is_ome=False) as tif: print(tif.series[0].shape) imagej_hyperstack = tif.asarray() #tfile.imshow(imagej_hyperstack[:,bfchannel,:,:]) #plt.show() print(imagej_hyperstack.shape) #imagej_metadata = tif.imagej_metadata #micromanager_metadata = tif.micromanager_metadata #ome_metadata = tif.ome_metadata nbchannels = 1 if register: registration(imagej_hyperstack, bfchannel, nbchannels, file, output_dir) if png_export: io.imsave(os.path.join(output_dir,file)+'.png',imagej_hyperstack[bfchannel,:,:])
def readOmeTiff(input_path): with tifffile.TiffFile(input_path) as tif: array = tif.asarray() omexmlString = tif[0].image_description.decode("utf-8") # Turn Ome XML String to an Bioformats object for parsing metadata = omexmlClass.OMEXML(omexmlString) # Parse pixel sizes pixels = metadata.image(0).Pixels SizeC = pixels.SizeC SizeT = pixels.SizeT SizeZ = pixels.SizeZ SizeX = pixels.SizeX SizeY = pixels.SizeY pixels.DimensionOrder # Expand image array to 5D of order (T, Z, C, X, Y) if SizeC == 1: array = np.expand_dims(array, axis=-3) if SizeZ == 1: array = np.expand_dims(array, axis=-4) if SizeT == 1: array = np.expand_dims(array, axis=-5) return (array, omexmlString)
def load_tiff(path): _, img_name = os.path.split(path) with tf.TiffFile(path) as tif: if tif.is_imagej is not None: metadata = tif.pages[0].imagej_tags dt = metadata['finterval'] if 'finterval' in metadata else 1 # asuming square pixels xr = tif.pages[0].tags['x_resolution'].value res = float(xr[0]) / float(xr[1]) # pixels per um if metadata['unit'] == 'centimeter': res = res / 1e4 images = None if len(tif.pages) == 1: if ('slices' in metadata and metadata['slices'] > 1) or ( 'frames' in metadata and metadata['frames'] > 1): images = tif.pages[0].asarray() else: images = [tif.pages[0].asarray()] elif len(tif.pages) > 1: images = list() for i, page in enumerate(tif.pages): images.append(page.asarray()) return images, res, dt, metadata['frames'], metadata[ 'channels'] if 'channels' in metadata else 1
def iter_mask(): for key in param_dict.keys(): if key.startswith('mask_'): with tifffile.TiffFile(param_dict[key]['filepath']) as infile: mask = infile.series[0].pages[0].asarray(memmap=True) outline = segmentation.find_boundaries(mask > 0, mode='inner') yield outline
def register(tiff_path, trans_mat, out_tiff_path, highres = True, compress = 1, pad = True): ''' tiff_path: tiff file name trans_mat: translation matrix, can be obtained by roi2mat() highres: optional, if set to True, will multiply the trans_mat by compress (which is set to 3 by default) compress: as above pad: whehther or not pad the periphery to zeros. If false, will crop the tiff This function returns a dict of metadata, and writes the tiff to current working directory ''' with tifffile.TiffFile(tiff_path) as tif: # read tiff im_in = tif.asarray() # read metadata as tif_tags (dict) tif_tags = tif.pages[0].tags.values() # register using trans_mat im_out = translate(im_in,trans_mat,hi_res=highres,compression=compress,padzeros=pad) im_out = im_out.astype('uint16') # save registered tiff, no compression with tifffile.TiffWriter(out_tiff_path, bigtiff = highres) as tif: for i in range(im_out.shape[0]): tif.save(im_out[i]) return tif_tags
def _load_image(path, obj): """Load an image from disk into a data object. Args: path (str): Path to image. obj (io.DisplotData): Data object to populate with the data. Returns: io.DisplotData: Displot data object. """ if not os.path.exists(path): raise FileNotFoundError(path) if os.path.isdir(path): raise IsADirectoryError(path) if not os.access(path, os.R_OK): raise PermissionError(path) ext = os.path.splitext(path)[1].lower() obj.image_path = path if ext == '.tiff' or ext == '.tif': with tifffile.TiffFile(path) as tif: obj.image = tif.asarray() obj.image_meta = {} for f in tif.flags: obj.image_meta[f] = getattr(tif, f + '_metadata') else: raise RuntimeError(path) return obj
def dna_corrcoef(image_filepath, marker_list, output_filepath): # parse markers dna_pattern = [ 'DNA\d+', # 'DNA' followed by one or more digits 'DNA_\d+', # 'DNA' followed by one or more digits ] def is_dna(n): for p in dna_pattern: if re.fullmatch(pattern=p, string=n) is not None: return True return False dna_index = [i for i, name in enumerate(marker_list) if is_dna(name)] # calculate record = [] ref_channel = 0 with tifffile.TiffFile(image_filepath) as tif: ref_array = tif.series[0].pages[ref_channel]\ .asarray(memmap=True)\ .flatten() for cycle, channel in enumerate(dna_index): test_array = tif.series[0].pages[channel]\ .asarray(memmap=True)\ .flatten() cc = np.corrcoef(ref_array, test_array)[0, 1] record.append([cycle + 1, channel + 1, ref_channel + 1, cc]) # write output file df = pd.DataFrame.from_records( record, columns=['cycle', 'channel', 'reference_channel', 'corrcoef']) df.to_csv(output_filepath, index=False, na_rep='nan')
def load(self, file_path): self.file_path = file_path with tifffile.TiffFile(file_path) as tif: self.data = tif.asarray() self.metadata = tif.info() self.features.set_image_data(self.data)
def getarray(idx_buffer_filename): idx, buf, fname = idx_buffer_filename fbuf = BytesIO(buf) tfh = tifffile.TiffFile(fbuf) ary = tfh.asarray() pageCount = ary.shape[0] if nplanes is not None: extra = pageCount % nplanes if extra: if discard_extra: pageCount = pageCount - extra logging.getLogger('thunder').warn( 'Ignored %d pages in file %s' % (extra, fname)) else: raise ValueError( "nplanes '%d' does not evenly divide '%d'" % (nplanes, pageCount)) values = [ ary[i:(i + nplanes)] for i in range(0, pageCount, nplanes) ] else: values = [ary] tfh.close() if ary.ndim == 3: values = [val.squeeze() for val in values] nvals = len(values) keys = [(idx * nvals + timepoint, ) for timepoint in range(nvals)] return zip(keys, values)
def read_ometiff(input_path): with tifffile.TiffFile(input_path) as tif: array = tif.asarray() omexml_string = tif[0].image_description.decode("utf-8") # Turn Ome XML String to an Bioformats object for parsing metadata = omexmlClass.OMEXML(omexml_string) # Parse pixel sizes pixels = metadata.image(0).Pixels size_c = pixels.SizeC size_t = pixels.SizeT size_z = pixels.SizeZ size_x = pixels.SizeX size_y = pixels.SizeY # Expand image array to 5D of order (T, Z, C, X, Y) if size_c == 1: array = np.expand_dims(array, axis=-3) if size_z == 1: array = np.expand_dims(array, axis=-4) if size_t == 1: array = np.expand_dims(array, axis=-5) return array, omexml_string
def execute(image_path): image_name = os.path.basename(image_path) print(image_name) with tifffile.TiffFile(image_path) as tif: array6D = [] # Turn Ome XML String to a Bioformats object for parsing omexml = tif[0].image_description.decode("utf-8") metadata = omexmlClass.OMEXML(omexml) # Parse pixel sizes size_c = metadata.image(0).Pixels.SizeC size_z = metadata.image(0).Pixels.SizeZ size_t = metadata.image(0).Pixels.SizeT # Read each series, get the 5d array -> process it -> append to array6D for i in range(len(tif.series)): # Returned value is a 5D array of order (T, Z, C, X, Y) array5D = read_serie(tif.series[i], size_c, size_z, size_t) # Apply inversion operation result5d = apply_2d_transfo_to_serie(_invert, array5D, False) array6D.append(result5d) # Save the inverted image write_ometiff(image_name, array6D, omexml) print("INVERTION DONE") return {'output_image': image_name}
def __init__(self, t_file_names, b_verbose=False): super().__init__(t_file_names) # to be turned into tuples at the end of this constructor l_vid_files = [] l_vid_streams = [] for idx in range(len(self.t_file_names)): self.df_info.loc[idx, 'file_name'] = self.t_file_names[idx] oc_tiff_record = tifffile.TiffFile(self.t_file_names[idx]) if hasattr(oc_tiff_record, 'pages'): oc_tiff = oc_tiff_record.pages else: oc_tiff = oc_tiff_record['pages'] oc_tmp_frame = oc_tiff[0] # TODO we can use this later: print(oc_tmp_frame.tags) self.df_info.loc[idx, 'duration'] = len(oc_tiff) self.df_info.loc[idx, 'frames'] = len(oc_tiff) # frame rate is not available in TIFFs: self.df_info.loc[idx, 'frame_rate'] = self.df_info.loc[idx, 'width'] = int( oc_tmp_frame.shape[1]) # this is correct self.df_info.loc[idx, 'height'] = int(oc_tmp_frame.shape[0]) self.df_info.loc[idx, 'format'] = oc_tmp_frame.dtype l_vid_files.append(oc_tiff) l_vid_streams.append(oc_tiff) # check if all video files have the same frame width and height if self.df_info['width'].sum() != \ self.df_info['width'][0] * len(self.df_info['width']): raise ValueError( "Frame width is not consistent across input video files") if self.df_info['height'].sum() != \ self.df_info['height'][0] * len(self.df_info['height']): raise ValueError( "Frame height is not consistent across input video files") self.df_info['start'] = self.df_info['duration'].cumsum( ) - self.df_info['duration'] self.df_info['end'] = self.df_info['duration'].cumsum() # self.df_info = self.df_info.set_index(['file_name'], append = True) # freeze lists into tuples self.t_vid_files = tuple(l_vid_files) self.t_vid_streams = tuple(l_vid_streams) # [1000, 2000, 3000, 4000, 4963], read only! self.na_ends = np.array(self.df_info['end'], dtype=np.int32) self.shape = (int(self.df_info['height'][0]), int(self.df_info['width'][0]), int(self.df_info['duration'].cumsum().sum())) self.t_frame_hw = (int(self.df_info['height'][0]), int(self.df_info['width'][0])) self.i_nframes = int(self.df_info['duration'].cumsum().sum()) if b_verbose: print(self.df_info)
def work(self): # get the parameters from gui p = self.p # check if GPU if p['useGPU']: device = mx.gpu() else: device = mx.cpu() # load files self.status_signal.emit('Loading images...') files = self.filepaths nimgs = len(files) imgs = [tifffile.TiffFile(f, multifile=True).asarray() for f in files] # imgs = [plt.imread(f) for f in files] # adjust the dimensions of the images if needed # if z-stack, reorder the stack to be x,y,z: if nimgs==1: if len(imgs[0].shape) > 2 and imgs[0].shape[0] < imgs[0].shape[1] and imgs[0].shape[0] < imgs[0].shape[2]: imgs_new = [] for z in range(imgs[0].shape[0]): imgs_new.append(imgs[0][z,:,:].squeeze()) imgs = imgs_new nimgs = len(imgs) # assuming single channel grayscale image, reshape into 3d array: for f in range(nimgs): if len(imgs[f].shape) < 3: imgs[f] = imgs[f].reshape(512,512,1) # assuming 512x512! # run cellpose self.status_signal.emit('Running segmentation...') cell_diam_px = p['cellSize'] rescale = 30 / cell_diam_px model = models.Cellpose(device, model_type=p['modelType']) masks, flows, styles, diams = model.eval(imgs, rescale=rescale, channels=[0,0], threshold=p['threshold']) # save the results to MAT file self.status_signal.emit('Saving to MAT file...') base = os.path.splitext(files[0])[0] sio.savemat(base + '_CELLPOSE.mat', {'software': 'cellpose', 'files': files, 'model': p['modelType'], 'cellsize': p['cellSize'], 'threshold': p['threshold'], 'styles': styles, 'masks': masks, 'img': imgs, 'filename': base, 'flows': flows, 'diams': diams}) self.status_signal.emit('Done') self.finished_signal.emit()
def load_image(path): """Read image from the passed path and return it in numpy array form. Args: path (str): Path to image file. Returns: numpy.ndarray: Image data. """ with tifffile.TiffFile(path) as tif: return tif.asarray()
def _getStamps(myData): from skimage.external import tifffile filename = myData[0] nPlanes = myData[1] tfh = tifffile.TiffFile(filename) nPages = len(tfh.pages) if nPages % nPlanes != 0: print('error: incomplete volume') # return None customHeaders = np.zeros((nPlanes, 4)) out = [] for page in range(0, nPages): k = (page + 1) % nPlanes if k == 0: k = nPlanes desStr = tfh.pages[page].tags[ 'image_description'].value.decode('utf-8') desStr = " ".join(desStr.split()).replace('\\', ' ') desStr = desStr.replace(')', '') desStr = desStr.replace('(', '') try: customHeaders[k - 1, 0] = re.search( '(?<=Frame\sNumber\s=\s)[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?', desStr).group(0) customHeaders[k - 1, 1] = re.search( '(?<=Frame\sTimestamps\s=\s)[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?', desStr).group(0) customHeaders[k - 1, 2] = re.search( '(?<=Acq\sTrigger\sTimestamps\s=\s)[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?', desStr).group(0) customHeaders[k - 1, 3] = re.search( '(?<=Next\sFile\sMarker\sTimestamps\s=\s)[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?', desStr).group(0) except AttributeError: #SI2016 customHeaders[k - 1, 0] = re.search( '(?<=frameNumbers\s=\s)[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?', desStr).group(0) customHeaders[k - 1, 1] = re.search( '(?<=frameTimestamps_sec\s=\s)[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?', desStr).group(0) customHeaders[k - 1, 2] = re.search( '(?<=acqTriggerTimestamps_sec\s=\s)[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?', desStr).group(0) customHeaders[k - 1, 3] = re.search( '(?<=nextFileMarkerTimestamps_sec\s=\s)[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?', desStr).group(0) if k == nPlanes: out.append(copy.deepcopy(customHeaders)) return out
def get_background_vector(cellmask_filepath, img_filepath): cellmask = io.imread(cellmask_filepath) background_index = np.argwhere(cellmask == 0) with tifffile.TiffFile(img_filepath) as tif: img = tif.series[0].asarray() # axis order: CXY img = img[:-1, ...] # last channel is ROI mask background = img[:, background_index[:, 0], background_index[:, 1]] background = background.T # axis order: NC background = background.astype( float) + 1e-12 # for numerical stability of log background = np.log10( background) # usually more gaussian-like in log space return np.median(background, axis=0)
def open(self, file_name=None): if file_name is not None: self.file_name = file_name if os.path.isdir(self.file_name): self.glob_mode = True flist = [] flist += glob.glob(os.path.join(self.file_name, '*.tif*')) flist += glob.glob(os.path.join(self.file_name, '*.TIF*')) flist = sorted(flist) fname = flist[0] self.flist = flist else: self.glob_mode = False fname = self.file_name self.tfile = tiff.TiffFile(fname) setattr(self, 'close', getattr(self.tfile, 'close'))
def s3_to_array(f, cci): """ Read a tif file straight from an S3 bucket (provided as a cottoncandy interface) into a numpy array Parameters ---------- f : str The name of the file in the bucket cci : cottoncandy interface """ o = cci.download_object(f) b = BytesIO(o) t = tif.TiffFile(b) a = t.asarray() return a
def find_tiff_dims(src): '''Find dimensions of a tifffile without having to load Inputs -------- src: file path Returns -------- pages: number of pages in tiff, for LVBT this is the number of horizontal foci y,x: pixel dims ''' from skimage.external import tifffile with tifffile.TiffFile(os.path.join(src)) as tif: pages = len(tif.pages) #number of horizontal foci y, x = tif.pages[0].shape tif.close() return pages, y, x
def load(cls, file_path, series=0): """Load image files into data structures. Class method. Can be used without instantiating. Parameters ---------- file_path : string/list [string, string, ...] File path as string, e.g. 'C:/folder/file.tif', or as list of file paths, e.g. ['C:/folder/file.tif', 'C:/folder/file.tif']. series : int, optional Sets the series number if file has multiple series (or positions). Use series='all' for loading all series. Defaults to 0. Examples -------- >>> ImageSetRead.load('C:/folder/file.tif') >>> image_files = ['C:/folder/file.tif', 'C:/folder/file.tif'] >>> ImageSetRead.load(image_files) """ if isinstance(file_path, str): file_path = [file_path] with tff.TiffSequence(file_path, pattern='XYCZT') as ts, \ tff.TiffFile(file_path[0]) as tf: files = ts.files image_metadata = cls._get_metadata(tf) if len(tf.series) > 1 and series == 'all': data = [] for idx, _ in enumerate(tf.series): data.append(ts.asarray(series=idx)) panel_data = np.array(data) else: panel_data = ts.asarray(series=series) if len(file_path) == 1 and series != 'all': panel_data = np.vstack(panel_data) image_data = cls._convert_to_xd( panel_data, image_metadata, file_path, series) return image_data, image_metadata, files
def _load_dpfile(path, obj): """Load a displot data file from disk into a data object. Args: path (str): Path to image. obj (io.DisplotData): Data object to populate with the data. Returns: io.DisplotData: Displot data object. """ a = tarfile.open(path, 'r') objjson_f = a.extractfile('dp.json') objjson = json.loads(str(objjson_f.read(), 'ascii')) obj.fromDict(objjson) image_f = a.extractfile(os.path.basename(objjson['image_path'])) with tifffile.TiffFile(image_f) as tif: obj.image = tif.asarray() return obj
def generate_cell(image_filepath, mask_filepath, channel_list, tile_shape, outline=False): mask = io.imread(mask_filepath) with tifffile.TiffFile(image_filepath) as infile: img_shape = infile.series[0].pages[0].shape for region in measure.regionprops(mask): # calculate tile coordinate c = region.centroids txl = int(np.round(c[0] - tile_shape[0] / 2)) tyl = int(np.round(c[1] - tile_shape[1] / 2)) txu, tyu = txl + tile_shape[0], tyl + tile_shape[1] # skip cells too close to image edge checklist = [ txl >= 0, txu < img_shape[0], tyl >= 0, tyu < img_shape[1] ] if not all(checklist): continue # compose cell = np.zeros(tile_shape + (len(channel_list), )) for channel in channel_list: img = infile.series[0].pages[channel].asarray(memmap=True) cell_img = img[txl:txu, tyl:tyu, channel] cell[..., channel] = img_as_float(cell_img) # add outline if outline: cm = mask[txl:txu, tyl:tyu].copy() co = segmentation.find_boundaries(cm, mode='inner')\ .astype(float) for ch in range(cell.shape[2]): cell[..., ch] = np.maximum(cell[..., ch], co) yield cell
def getarray(idxAndBuf): idx, buf = idxAndBuf fbuf = BytesIO(buf) tfh = tifffile.TiffFile(fbuf) ary = tfh.asarray() pageCount = ary.shape[0] if nplanes is not None: values = [ ary[i:(i + nplanes)] for i in range(0, ary.shape[0], nplanes) ] else: values = [ary] tfh.close() if ary.ndim == 3: values = [val.squeeze() for val in values] if nplanes and (pageCount % nplanes): raise ValueError("nplanes '%d' does not evenly divide '%d'" % (nplanes, pageCount)) nvals = len(values) keys = [(idx * nvals + timepoint, ) for timepoint in range(nvals)] return zip(keys, values)
def load(self): if self.ext == "tif": #self.data = skimage_io.imread(self.file_name,plugin="tifffile") with tff.TiffFile(self.path) as tiff: for tiff_page in tiff: pass #print(tiff_page.page_name) self.data = tiff.asarray() self.metadata = tiff[0].image_description self.info = tiff[0].info() #logging.debug(self.info) self.axes = self.data.shape logging.debug("---Image data: Shape - " + str(self.data.shape)) return
def get_lsm_ch(image_dir, color): """ Getting the channel based on the color """ full_image = tf.TiffFile(image_dir) is_lsm = full_image.is_lsm assert (is_lsm), "File is not lsm" all_pages = full_image.pages page_1 = all_pages[0] lsm_info = page_1.cz_lsm_scan_info channels = lsm_info.tracks channels_dict = {} for n in range(0, len(channels)): channels_dict[n] = channels[n].data_channels[0] table = df(channels_dict) colors = {} colors['blue'] = 16711680 colors['red'] = 255 colors['green'] = 65280 colors['dark_green'] = 48896 channel = table.ix['acquire', :][table.ix['color', :] == colors[color]] if len(channel) == 0: channel = table.ix['acquire', :][table.ix['color', :] == colors['dark_green']] if len(channel) == 0: print "Error: No Color\n" return None else: return channel.index[0] else: return channel.index[0]
import os import numpy as np from scipy import io from jaratoolbox import loadbehavior from matplotlib import pyplot as plt from skimage.external import tifffile dataDir = '/home/nick/data/imag002_20181201/' session = '000_002' Fn = 'imag002_20181201_{}.tif'.format(session) #Read in data file (nFrames, m, n) fullFile = os.path.join(dataDir, Fn) im0 = tifffile.TiffFile(fullFile, pages=[0]) # im = tifffile.imread(fullFile) #Read the events file rtMat = os.path.join(dataDir, 'imag002_20181201_{}_realtime.mat'.format(session)) rtData = io.loadmat(rtMat) #Get onset frame numbers ttl = rtData['ttl_log'] ttl = ttl.ravel().astype(int) #uint8 making things strange for diff onsets = np.flatnonzero( np.diff(ttl.astype(int)) == 2) + 1 #Should catch the leading edges #How many samples before and after onset to average samplesBefore = 0 samplesAfter = 20 traceLen = samplesBefore + samplesAfter
import numpy as np import skimage.external.tifffile as tiff from skimage.filters import threshold_otsu, gaussian, sobel from skimage.morphology import watershed from skimage import measure, draw from scipy import ndimage as ndi from scipy import optimize import matplotlib.pyplot as plt from intersection import calcIntersections testfile = "img/test_3balls.tif" with tiff.TiffFile(testfile) as tif: img = tif.asarray() markers = np.zeros_like(img) markers[img < 100] = 1 markers[img > 100] = 2 elevation_map = sobel(img) segmentation = watershed(elevation_map, markers) segmentation = ndi.binary_fill_holes(segmentation - 1) labeled_nuclei, _ = ndi.label(segmentation) regions = measure.regionprops(labeled_nuclei) r = 30 fig, ax = plt.subplots() perim = np.zeros((labeled_nuclei.shape[0], labeled_nuclei.shape[1])) processed_regions = [] for props in regions: y0, x0 = props.centroid processed_regions.append(props.centroid)