def convert_single_file( in_file_name, out_path, format_string, dataset_key='exported_data', **kwargs): is_bigtiff = kwargs.get('is_bigtiff', True) try: current_file = h5py.File(in_file_name, 'r') dataset = current_file[dataset_key] if len(dataset.shape) != 3: raise ValueError("Data needs to have 3 dimensions: cyx!") if dataset.shape[0] > 20: raise ValueError("Will not convert data with more than 20 channels") logger.debug(f"{in_file_name} to {out_path}") file_only = os.path.split(in_file_name)[1] for slice_index, c_slice in enumerate(dataset): new_file_name = format_string.format( original_filename=file_only, exported_channel=slice_index ) new_file_name = f"{new_file_name}.tiff" new_file_name = os.path.join(out_path, new_file_name) tiff = pytiff.Tiff(new_file_name, file_mode='w', bigtiff=is_bigtiff) tiff.write(c_slice) tiff.close() except (KeyError, ValueError) as e: logger.warning(f'encountered the following error in {in_file_name}', e) finally: current_file.close()
def __init__(self, filename, spacing=1, mode=READONLY, maxintensity=None): """Initialize TiffImage. TiffImage assumes that the pyramids are calculated with scales that are powers of two! E.g. 0.5, 0.25, etc. Args: filename (string): path to hdf5 file. spacing (number, optional): the spacing of the image. Default is 1. mode (string): open the file for reading or for writing? maxintensity (int): maxintensity of the image (e.g. 127). If not specified, is set to max value of the image dtype. """ f = pytiff.Tiff(filename, mode) # get scales and levels array shapes = [] pages = [] levels = [] for i in range(f.number_of_pages): f.set_page(i) if f.shape not in shapes: shapes.append(f.shape) pages.append(i) else: ind = shapes.index(f.shape) if f.is_tiled(): # prefer to use the tiled page pages[ind] = i f.set_page(0) for page in pages: img = pytiff.Tiff(filename, mode) img.set_page(page) levels.append(img) scales = [shape[0] / float(shapes[0][0]) for shape in shapes] #log.debug("TiffImage - Scales before rounding: %s", scales) scales = [1 / 2**round(math.log(1 / scale, 2)) for scale in scales] #log.debug("TiffImage - Scales after rounding: %s", scales) if maxintensity is None: maxintensity = dtype_limits(f.dtype)[1] size = shapes[0][:2] if spacing is None: spacing = 1 super(TiffImage, self).__init__(spacing, size, scales, maxintensity) self._file_handle = f self._mode = mode self._pages = pages self._levels = levels
def _writeImage(img, path, f_ident, ind): """""" with pytiff.Tiff(os.path.join(path, f_ident.format(ind)), 'w') as w_handle: w_handle.write(img, method = "scanline") #w_handle.write(img) del w_handle
def multi_tiff_to_numpy(filename): import pytiff with pytiff.Tiff(filename) as handle: arr = np.ndarray(shape=(handle.number_of_pages, handle.shape[0], handle.shape[1]), dtype=handle.dtype) for i, page in enumerate(handle.pages): arr[i] = page return arr
def load_hot_pixel_mask(self, s): print('Loading hot pixel mask ...') if self.mask_file is not None: with pytiff.Tiff(self.mask_file) as handle: im = np.array(handle) mask = 1 - im / 255 else: mask = np.ones((s[1], s[2])) return mask
def setUpClass(cls): """Generate some example data, write data as bigtiff using pytiff""" cls.tmp_data_folder = tempfile.mkdtemp() cls.test_file_name = f"{cls.tmp_data_folder}/bigtiff_testfile.tif" cls.data = numpy.random.randint(0, 255, (800, 1200)).astype("uint8") try: t = pytiff.Tiff(cls.test_file_name, file_mode="w", bigtiff=True) t.write(cls.data) finally: t.close()
def writePSFStack(psf_array, path, f_ident): img_count = psf_array.shape[0] t_img = np.zeros((psf_array.shape[1], psf_array.shape[2]), dtype='uint16') factor = int(65535. / psf_array.max()) for i in range(img_count): with pytiff.Tiff(os.path.join(path, f_ident.format(i)), 'w') as w_handle: t_img[:, :] = factor * psf_array[i, :, :] w_handle.write(t_img)
def load_binary_position_mask(self): if self.binary_mask_file is not None: print('Loading binary position mask ...') with pytiff.Tiff(self.binary_mask_file) as handle: im = np.array(handle) * -1 # io.plot(im,'positions') bin_mask_positions = im.astype(np.bool) else: bin_mask_positions = np.ones( (self.stepy, self.stepx)).astype(np.bool) return bin_mask_positions
def readPSFstack(path, f_ident, nmin, nmax): img_stack = [] for i in range(nmin, nmax + 1): t_f_path = os.path.join(path, f_ident.format(i)) with pytiff.Tiff(t_f_path, 'r') as handle: t_img = handle[:, :] print("Dtype: {} max: {} min: {}".format(t_img.dtype, t_img.max(), t_img.min())) img_stack.append(t_img) return np.array(img_stack, dtype='uint16')
def get_level(self, spacing): """Return pytiff.Tiff image opened at the specified spacing. If this spacing does not exists, returns None Args: spacing (number): the spacing of the wanted level. """ scale = self.spacing_to_scale(spacing) if scale in self.scales: lvl = pytiff.Tiff(self._file_handle.filename, READONLY) lvl.set_page(self._pages[list(self.scales).index(scale)]) return lvl return None
def _readImage(path, f_ident, ind): """""" #print("Path: {}; f_ident:{}, ind:{}".format(path, f_ident, ind)) with pytiff.Tiff(os.path.join(path, f_ident.format(ind))) as r_handle: if r_handle.number_of_pages > 1: r_handle.set_page(0) #tags = r_handle.read_tags() array_w = r_handle[:,:] del r_handle return array_w
def readBigtifFile(fname, dimensions=None): with pytiff.Tiff(fname) as handle: tags = handle.read_tags() offset = tags['strip_offsets'][0] nframes = int(tags['image_description'].split()[1][7:]) width, height = (tags['image_width'][0], tags['image_length'][0]) if dimensions is None: dimensions = (nframes, height, width) with open(fname, "rb") as file: file.seek(offset) temp = fromfile(file, dtype=">u2") #print(temp.shape) return (temp.reshape(dimensions))
def image(self): image_file = self.image_file try: image = Image.open(image_file.name) except (IOError, OSError) as pillow_exception: try: import numpy import pytiff image = pytiff.Tiff(image_file.name) image = Image.fromarray(numpy.array(image)) except (IOError, OSError) as pytiff_exception: raise image_file.close() return image
def setupOutputs(self): filepath = self.Filepath.value if not pytiff.utils.is_bigtiff(filepath): raise OpBigTiffReader.NotBigTiffError(filepath) bigtiff = pytiff.Tiff(filepath) if bigtiff.number_of_pages != 1: raise RuntimeError("Multipage BigTiff not supported yet.") self.Output.meta.dtype = bigtiff.dtype if bigtiff.samples_per_pixel > 1: self.Output.meta.shape = bigtiff.shape + (bigtiff.samples_per_pixel,) self.Output.meta.axistags = vigra.defaultAxistags("yxc") else: self.Output.meta.shape = bigtiff.shape self.Output.meta.axistags = vigra.defaultAxistags("yx") self._bigtiff = bigtiff
def computeHistogram(in_path, label, bins, bitmask): try: import PIL.Image PIL.Image.MAX_IMAGE_PIXELS = 10000000000 image = PIL.Image.open(in_path) print 'use pil' except (ImportError, IOError, OSError): import pytiff image = pytiff.Tiff(in_path) print 'use pytiff' else: if image.mode not in ('1', 'L', 'P', 'I', 'F'): raise ValueError('invalid image type for histogram: %s' % image.mode) array = numpy.array(image) if label: array = array[numpy.nonzero(array)] # TODO: integer histogram optimizations ''' if array.dtype == numpy.uint8 and bins == 256: _bins = range(bins + 1) else: _bins = bins ''' if array.dtype == numpy.uint8: _bins = numpy.arange(numpy.min(array), numpy.max(array) + 2) if bitmask: hist = numpy.zeros(array.dtype.itemsize * 8 + 1 - label) if not label: hist[0] = (array == 0).sum() binEdges = numpy.arange(label, hist.shape[0] + label) for i in range(1, hist.shape[0] + label): hist[i - label] = (array & 1 << i - 1 > 0).sum() else: hist, binEdges = numpy.histogram(array, bins=_bins) print hist return hist, binEdges
def open_image(filename, page=0): """ Open image (lazy, i.e. not reading the whole image if not necessary). Args: filename: image filename. page (str or int): page of tiff file or internal path to dataset in HDF5 file. Returns: h5py._hl.dataset.Dataset, pytiff._pytiff.Tiff or numpy.ndarray containing image in row x col format """ print("open Image {}".format(filename)) if filename.endswith('.tif'): # open image with pytiff img = pytiff.Tiff(filename) img.set_page(int(page)) elif filename.endswith('.h5') or filename.endswith('.hdf5'): # open image with h5py f = h5py.File(filename, 'r') if page == 0: page = "/" # set default page for hdf5 files img = f[page] elif filename.endswith('.nii'): import nibabel as nib img = np.transpose(nib.load(filename).get_data()) # Reshape image, since some nii files contain 4 dimension shape = img.shape if len(shape) > 2: # After transposing, we have to adjust the dimensions img = img.reshape(shape[2], shape[3]) else: img = skimage.io.imread(filename) #, as_grey=True) # if rgb, convert to grayscale #if len(img.shape) > 2: # img = skimage.color.rgb2gray(img) return img
def read_im_stack(): ims = [] n_min = 1 n_max = 199 for i in range(n_min, n_max + 1): print("Reading tif No. {}...".format(i)) pt_ident = "slide1_1000wo_edges" sl_no = 1 print("path: {}".format( os.path.join(out_paths[pt_ident], crop_fname.format(sl_no, reg_size[0], reg_size[1], i)), )) with pytiff.Tiff( os.path.join( out_paths[pt_ident], crop_fname.format(sl_no, reg_size[0], reg_size[1], i))) as r_handle: part = r_handle[:, :] del r_handle ims.append(part) return ims
def main(): for input_file_path in input_filepaths[:]: input_filename = input_file_path.name.split('.')[0] input_filename = input_filename.replace('_', '') print('Processing:', str(input_file_path)) time_start = time() tiff = pytiff.Tiff(str(input_file_path)) # Deidentify IDs output_filename = input_filename output_path = pathlib.Path('rendered') / output_filename assert tiff.number_of_pages % num_channels == 0, "Pyramid/channel mismatch" num_levels = tiff.number_of_pages // num_channels with open(csv_path) as group_config: reader = csv.DictReader(group_config) config_rows = [dict(row) for row in reader] render_groups = OrderedDict() for i in config_rows: if i['Group'] not in render_groups.keys(): render_groups[i['Group']] = { 'Channel Number': [], 'Low': [], 'High': [], 'Color': [], 'Marker Name': [] } for key in render_groups[i['Group']]: render_groups[i['Group']][key].append(i[key]) channel_groups = [] for name, settings in render_groups.items(): channels = '--'.join(settings['Channel Number'][i] + '__' + settings['Marker Name'][i] for i in range(len(settings['Color']))) channel_groups += [{ 'Path': name.replace(' ', '-') + '_' + channels, 'Name': name, 'Colors': [colors.to_hex(c)[1:] for c in settings['Color']], 'Channels': settings['Marker Name'], }] json_str = '' with open('default_json.json') as f: json_str = f.read() pan_x = calculate_pan_x(tiff.shape[1], tiff.shape[0]) json_str = (json_str.replace( 'placeholder_slide_name', output_filename).replace( 'placeholder_exhibit_name', output_filename).replace( '"placeholder_width"', str(tiff.shape[1])).replace( '"placeholder_height"', str(tiff.shape[0])).replace( '"placeholder_max_level"', str(num_levels - 1)).replace( 'placeholder_first_ch_group', channel_groups[0]['Name']).replace( '"placeholder_pan_x"', str(pan_x)).replace( '"placeholder_pan_y"', str(0.5))) out_json = json.loads(json_str, object_pairs_hook=OrderedDict) out_json['Exhibit']['Groups'] = channel_groups out_json['Exhibit']['Layout']['Grid'] = [['i0']] with open(str(output_path / (output_filename + '.json')), 'w') as outfile: json.dump(out_json, outfile) with open(str(output_path / (output_filename + '.yml')), 'w') as outfile: yaml.SafeDumper.add_representer( OrderedDict, lambda dumper, data: dumper.represent_mapping( 'tag:yaml.org,2002:map', data.items())) yaml.safe_dump(out_json, outfile, default_flow_style=False, canonical=False) print('Used', str(int(time() - time_start)), 'sec for', output_filename)
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns sns.set(font_scale=1.2) from sklearn.feature_extraction import image from sklearn.feature_extraction.image import grid_to_graph from sklearn.cluster import AgglomerativeClustering from sklearn.utils.fixes import parse_version from scipy.ndimage.filters import gaussian_filter import skimage import pytiff #fairly new package, uploaded tiff file and automatically converted it to an array # In[3]: with pytiff.Tiff("5.tiff") as handle: part = handle[ 100:200, 200: 400] #supports tiled tiffs and bigtiff, so you can read parts of large images # In[4]: part #prints out image as array # In[7]: #slicing to keep ony array w/o first column and first row #remove paper noise eeg1 = part[200:len(part) - 200, 1:len(part[0])] # In[9]:
xLim[iCore] = I.shape[1] if x[iCore]<1: x[iCore]=1 y[iCore] = centroids[iCore,0] - estCoreDiamY[iCore]/2 yLim[iCore] = y[iCore] + estCoreDiamY[iCore] if yLim[iCore] > I.shape[0]: yLim[iCore] = I.shape[0] if y[iCore]<1: y[iCore]=1 bbox[iCore] = [round(x[iCore]), round(y[iCore]), round(xLim[iCore]), round(yLim[iCore])] coreStack = np.zeros((outputChan[1]-outputChan[0]+1,np.int(round(yLim[iCore])-round(y[iCore])-1),np.int(round(xLim[iCore])-round(x[iCore])-1))) for iChan in range(outputChan[0],outputChan[1]+1): with pytiff.Tiff(imagePath, "r", encoding='utf-8') as handle: handle.set_page(iChan) coreStack[iChan,:,:] =handle[np.uint32(bbox[iCore][1]):np.uint32(bbox[iCore][3]-1), np.uint32(bbox[iCore][0]):np.uint32(bbox[iCore][2]-1)] skio.imsave(outputPath + os.path.sep + str(iCore+1) + '.tif',np.uint16(coreStack),imagej=True,bigtiff=True) with pytiff.Tiff(imagePath, "r", encoding='utf-8') as handle: handle.set_page(args.channel) coreSlice= handle[np.uint32(bbox[iCore][1]):np.uint32(bbox[iCore][3]-1), np.uint32(bbox[iCore][0]):np.uint32(bbox[iCore][2]-1)] core = (coreLabel ==(iCore+1)) initialmask = core[np.uint32(y[iCore]*dsFactor):np.uint32(yLim[iCore]*dsFactor),np.uint32(x[iCore]*dsFactor):np.uint32(xLim[iCore]*dsFactor)] initialmask = resize(initialmask,size(coreSlice),cv2.INTER_NEAREST) singleProbMap = classProbs[np.uint32(y[iCore]*dsFactor):np.uint32(yLim[iCore]*dsFactor),np.uint32(x[iCore]*dsFactor):np.uint32(xLim[iCore]*dsFactor)] singleProbMap = resize(np.uint8(255*singleProbMap),size(coreSlice),cv2.INTER_NEAREST) TMAmask = coreSegmenterOutput(coreSlice,singleProbMap,initialmask,coreRad/20,False)
def main(): if len(input_filepaths) is 0: print('no file to process') for input_file_path in input_filepaths[:]: print('Processing:', str(input_file_path)) time_start = time() input_filename = input_file_path.name.split('.')[0] input_filename = input_filename.replace('_', '') output_path = pathlib.Path('rendered') / input_filename tiff = pytiff.Tiff(str(input_file_path)) assert tiff.number_of_pages % num_channels == 0, "Pyramid/channel mismatch" num_levels = tiff.number_of_pages // num_channels with open(csv_path) as group_config: reader = csv.DictReader(group_config) config_rows = [dict(row) for row in reader] render_groups = OrderedDict() for i in config_rows: if i['Group'] not in render_groups.keys(): render_groups[i['Group']] = { 'Channel Number': [], 'Low': [], 'High': [], 'Color': [], 'Marker Name': [] } for key in render_groups[i['Group']]: render_groups[i['Group']][key].append(i[key]) for name, settings in list(render_groups.items())[:]: channels = '--'.join(settings['Channel Number'][i] + '__' + settings['Marker Name'][i] for i in range(len(settings['Color']))) group_dir = name.replace(' ', '-') + '_' + channels if not (output_path / group_dir).exists(): (output_path / group_dir).mkdir(parents=True) for i, (marker, color, start, end) in enumerate( zip(settings['Channel Number'], settings['Color'], settings['Low'], settings['High'])): tiff.set_page(int(marker)) tile = tiff[:, :] if i == 0: target = np.zeros(tile.shape + (3, ), np.float32) composite_channel(target, tile, colors.to_rgb(color), float(start), float(end)) np.clip(target, 0, 1, out=target) target_u8 = (target * 255).astype(np.uint8) img = Image.frombytes('RGB', target.T.shape[1:], target_u8.tobytes()) # img = img.resize((int(img.width / 2), int(img.height / 2))) print(' Writing tiles to:', str(output_path / group_dir)) DeepZoomStaticTiler(img, str(output_path / group_dir), 'jpg', 1024, 0, False, 85, 8, False, is_PIL_Image_obj=True).run() print('Used', str(int(time() - time_start)), 'sec for', input_filename)
TILE_SIZE = 1024 EXT = 'jpg' num_channels = 40 csv_path = './rendering_settings_with_AXL/20190923_settings-2019.csv' input_file_dir = pathlib.Path('Z:/123-BOLAND_BIOPSY-2019JUN/ome_tiffs') input_filepaths = sorted(input_file_dir.glob('*.ome.tif')) for input_file_path in input_filepaths[:2]: print('Processing:', str(input_file_path)) # input_file_path = pathlib.Path('Z:/048-BENBIOPSY1-2017APR/D13_07880_B2.ome.tif') input_filename = input_file_path.name.split('.')[0] output_path = pathlib.Path('rendered') / input_filename tiff = pytiff.Tiff(str(input_file_path)) assert tiff.number_of_pages % num_channels == 0, "Pyramid/channel mismatch" num_levels = tiff.number_of_pages // num_channels with open(csv_path) as group_config: reader = csv.DictReader(group_config) config_rows = [dict(row) for row in reader] render_groups = OrderedDict() for i in config_rows: if i['Group'] not in render_groups.keys(): render_groups[i['Group']] = { 'Channel Number': [], 'Low': [],
%pylab import pytiff Fl = [] with pytiff.Tiff("cell1_1.tif") as handle: Flt = zeros((128,1024)) for i,page in enumerate(handle): Flt += page Fl = array(Fl) miFt = min(Flt.flatten()) maFt = max(Flt.flatten()) Ft = array(Flt[:,:512],dtype=float) imshow((Ft-miFt)/(maFt-miFt)) fftF = fftshift(fft2(Ft)) miff = min(log(abs(fftF)).flatten()) maff = max(log(abs(fftF)).flatten()) imshow((log(abs(fftF))-miff)/(maff-miff)) hist(log(abs(fftF)).flatten(),bins=41) imshow((Ft-miFt)/(maFt-miFt)) figure(2) fftF2 = fftF*(1+randn(fftF.shape[0],fftF.shape[1])*0.15); Ft2 = real(ifft2(ifftshift(fftF2))); miFt2 = min(Ft2.flatten()); maFt2 = max(Ft2.flatten()); imshow((Ft2-miFt2)/(maFt2-miFt2)) fftF2 = fftF*(1+randn(fftF.shape[0],fftF.shape[1])*0.85); Ft2 = real(ifft2(ifftshift(fftF2))); miFt2 = min(Ft2.flatten()); maFt2 = max(Ft2.flatten()); imshow((Ft2-miFt2)/(maFt2-miFt2))
def main(array_list, channel_name_list=None, out_path=None, tile_size=1024): if hasattr(os, 'sched_getaffinity'): num_workers = len(os.sched_getaffinity(0)) else: num_workers = multiprocessing.cpu_count() if channel_name_list is None: channel_name_list = [str(i+1) for i in range(len(array_list))] if out_path is None: out_path = './out.ome.tif' if os.path.exists(out_path): print("%s already exists, aborting" % out_path) sys.exit(1) print("Appending input images") for i, img_in in enumerate(array_list): print(" %d: %s" % (i + 1, channel_name_list[i])) if i == 0: base_shape = img_in.shape dtype = img_in.dtype kwargs = { 'description': '!!xml!!', 'software': 'Glencoe/Faas pyramid' } else: if img_in.shape != base_shape: print( "%s: expected shape %s, got %s" % (channel_name_list[i], base_shape, img_in.shape) ) sys.exit(1) if img_in.dtype != dtype: print( "%s: expected dtype %s, got %s" % (channel_name_list[i], dtype, img_in.dtype) ) sys.exit(1) kwargs = {} imsave(out_path, img_in, tile_size, **kwargs) print() num_channels = len(channel_name_list) num_levels = np.ceil(np.log2(max(base_shape) / tile_size)) + 1 factors = 2 ** np.arange(num_levels) shapes = (np.ceil(np.array(base_shape) / factors[:,None])).astype(int) print("Pyramid level sizes:") for i, shape in enumerate(shapes): print(" level %d: %s" % (i + 1, format_shape(shape)), end="") if i == 0: print(" (original size)", end="") print() print() executor = concurrent.futures.ThreadPoolExecutor(num_workers) shape_pairs = zip(shapes[:-1], shapes[1:]) for level, (shape_in, shape_out) in enumerate(shape_pairs): print( "Resizing images for level %d (%s -> %s)" % (level + 2, format_shape(shape_in), format_shape(shape_out)) ) ty = np.array(range(0, shape_in[0], tile_size)) tx = np.array(range(0, shape_in[1], tile_size)) coords = list(zip( itertools.product(ty, tx), itertools.product(ty + tile_size, tx + tile_size) )) img_in = pytiff.Tiff(out_path) img_out = np.empty(shape_out, dtype) for c in range(num_channels): page = level * num_channels + c img_in.set_page(page) for i, _ in enumerate(executor.map( preduce, coords, itertools.repeat(img_in), itertools.repeat(img_out) )): percent = int((i + 1) / len(coords) * 100) if i % 20 == 0 or percent == 100: print("\r %d: %d%%" % (c + 1, percent), end='') sys.stdout.flush() imsave(out_path, img_out, tile_size) print() img_in.close() print() xml = construct_xml(os.path.basename(out_path), shapes, num_channels, dtype, 0.325, channel_name_list=channel_name_list) patch_ometiff_xml(out_path, xml)
print("We will do analysis for file "+cfile) wdir = '' for fs in cfile.split("/")[:-1]: wdir = wdir+fs+'/' outputdir = cfile.split(".")[0]+'output/' fposB = loadtxt(outputdir+"FposB.dat") fposA = loadtxt(outputdir+"FposA.dat") cellname = cfile.split("/")[-1].split("_")[0] mask = pytiff.Tiff(wdir+cellname+"_Mask_CMOS.tif")[:,:] v = transfpar(fposB,fposA,transform = 2) v0 = v[:2] v1 = v[2:4] v2 = array([[0,v[4]],[v[5],0]]) fposBinA = fposB*v1+v0+dot(v2,fposB.transpose()).transpose() Av = zeros((fposA.shape[0]+fposB.shape[0]),dtype=int) ipos = array(fposA,dtype=int) lA = len(ipos) for i in range(len(ipos)): Av[i] = mask[ipos[i,1],ipos[i,0]]//255