def test_tiff_image_entry_creation(resource, expected_error_message): error_message = "" image_entry = None try: tiff_file = load_tiff_file(path=resource) image_entry = create_tiff_image_entry(tiff_file=tiff_file) except ValidationError as e: error_message = e.message # Asserts possible file opening failures assert error_message == expected_error_message # Asserts successful creation data if not error_message: tiff_file = tiff_lib.TiffFile(str(resource.absolute())) tiff_tags = tiff_file.pages[0].tags assert image_entry.name == resource.name assert image_entry.width == tiff_tags["ImageWidth"].value assert image_entry.height == tiff_tags["ImageLength"].value assert image_entry.depth == 1 assert image_entry.resolution_levels == len(tiff_file.pages) assert image_entry.color_space == get_color_space( str(tiff_tags["PhotometricInterpretation"].value))
def __init__(self): super().__init__() self.s = Q_(1, 's') self.us = Q_(1, 'us') self.mock = True self.temperature_setpoint = -10 self.cooler_on_state = False self.acq_mode = 'Run till abort' self.status_state = 'Camera is idle, waiting for instructions.' self.image_size = self.detector_shape self.preamp_st = 1 self.EM_gain_st = 1 self.ftm_state = False self.horiz_shift_speed_state = 1 self.n_preamps = 1 self.PreAmps = np.around([self.true_preamp(n) for n in np.arange(self.n_preamps)], decimals=1)[::-1] self.HRRates = [self.true_horiz_shift_speed(n) for n in np.arange(self.n_horiz_shift_speeds())] self.vertSpeeds = [np.round(self.true_vert_shift_speed(n), 1) for n in np.arange(self.n_vert_shift_speeds)] self.vertAmps = ['+' + str(self.true_vert_amp(n)) for n in np.arange(self.n_vert_clock_amps)] self.vertAmps[0] = 'Normal' with tiff.TiffFile(os.path.join(os.getcwd(), 'tormenta', 'control', 'beads.tif')) as ff: self.image = ff.asarray() self.expTime = 0.1 * self.s
def _custom_try_except(node, key): """ Parameters ---------- node: quilt.nodes.Node The current self node. key: str The target child node. Output ---------- Attempts to open the target by try -> except blocks with default loaders. If all loaders fail, it getattrs the target from current as a safety. """ # this is disgusting and im sorry try: return json.load(open(getattr(node, key)())) except: pass try: return tfle.TiffFile(getattr(node, key)()) except: pass return getattr(node, key)()
def axes(self): if not self._axes: best_first = 0 best_second = 0 for file_path in self._filenames: tif_axes = {} log.debug("Loading position list from %s" % file_path) with tifffile.TiffFile(file_path) as tif_stack: for tif in tif_stack: position_text = tif.micromanager_metadata['PositionName'] axis_positions = name_regex.search(position_text) if not axis_positions: print("Unable to determine the position of this field of view: %s" % position_text) else: first = int(axis_positions.group(1)) second = int(axis_positions.group(2)) best_first = max(first, best_first) best_second = max(second, best_second) tif_axes[position_text] = (first, second) if best_second > best_first: # the second thing is the major axis, so we need to invert them tif_axes = {position_text: (second, first) for position_text, (first, second) in tif_axes.items()} # no need to invert, just return the values we already have self._axes[file_path] = tif_axes return self._axes
def raw_parameters(rawFilePath): '''Obtain raw image parameters: zSpacing, xResolution and yResolution from TIFF''' rawImg = tiff.TiffFile(rawFilePath) try: zSpacing = rawImg.imagej_metadata['spacing'] except Exception as e: zSpacing = 1 if rawImg.imagej_metadata['unit'] == 'micron': measurementsInMicrons = True rawImg = Image.open(rawFilePath) if TAGS[282] == 'XResolution': xResolution = 1 / rawImg.tag_v2[282] if TAGS[283] == 'YResolution': yResolution = 1 / rawImg.tag_v2[283] if measurementsInMicrons: #To nanometers zSpacing = zSpacing * 1000 xResolution = xResolution * 1000 yResolution = yResolution * 1000 return zSpacing, xResolution, yResolution
def __init__(self, filename, verbose=False): super(TifReader, self).__init__(filename, verbose) # Save the filename self.fileptr = tifffile.TiffFile(filename) number_pages = len(self.fileptr.pages) # Get shape by loading first frame self.isize = self.fileptr.asarray(key=0).shape # Check if each page has multiple frames. if (len(self.isize) == 3): self.frames_per_page = self.isize[0] self.image_height = self.isize[1] self.image_width = self.isize[2] else: self.frames_per_page = 1 self.image_height = self.isize[0] self.image_width = self.isize[1] if self.verbose: print("{0:0d} frames per page, {1:0d} pages".format( self.frames_per_page, number_pages)) self.number_frames = self.frames_per_page * number_pages self.page_number = -1 self.page_data = None
def extract_tif_meta(fname): ''' Extracts .tif metadata (tags) and additional information embdedded in 'ImageDescription' meta = extract_tif_meta(fname) INPUTS: fname ~ string [path to .tif file] OUTPUTS: meta ~ dict [contains .tif tags (UPPERCASE keys) and additional information (lowercase keys, if present) ''' with tifffile.TiffFile(fname) as tif: meta = {item[0] : item[1].value \ for item in tif.pages[0].tags.items()} # Expand tags embedded in ImageDescription fields # Note: My current solution uses a literal_eval to turn the string into a # Python dictionary. I know that eval() is not good practice and I would not # normally use it, but ast.literal_eval() is at least rigorously limited to # parsing Python datatypes exclusively. try: tags_extra = ast.literal_eval(meta['ImageDescription']) meta.update(tags_extra) # Extra metadata appended to original tags except: pass # Exception handling in case 'ImageDescription' field is not formatted as dictionary try: tags_extra2 = ast.literal_eval(meta['ImageDescription1']) meta.update(tags_extra2) # Check in case 'ImageDescription1' might have some tags except: pass return meta
def split_tiff( in_path: Path, out_dir: Path, tile_size: int, overlap: int, nzplanes: int, selected_channels: list, ): with tif.TiffFile(in_path) as TF: npages = len(TF.pages) for z in range(0, nzplanes): pages = [] for c in selected_channels: page = c * nzplanes + z pages.append(page) print("pages", [p + 1 for p in pages], "/", npages) this_plane_tiles, this_plane_tile_names, slicer_info = split_plane( in_path, pages, z, tile_size, overlap ) task = [] for i, tile in enumerate(this_plane_tiles): out_path = path_to_str(out_dir.joinpath(this_plane_tile_names[i])) task.append( dask.delayed(tif.imwrite)(out_path, tile, photometric="minisblack") ) dask.compute(*task, scheduler="threads") return slicer_info
def path_is_otf(fpath): with warnings.catch_warnings(): warnings.simplefilter("ignore") with tf.TiffFile(fpath) as tif: if (not len(tif.series)) or (tif.series[0].ndim != 2): return False return array_is_otf(tif.series[0].asarray())
def read_si_tiffstack(path_name: str, header_only: bool = False) -> tuple: """Open a scanimage tiff file Reads header data using PIL and tiff image data using scikit-image. Todo: Using two libraries is inefficient, finding a single solution would be the best. Args: path_name (str): Path to a tif file header_only (bool): flag to parse header only and return no image data Returns: tuple: Image Data (numpy.ndarray (z,y,x)), header (dict) """ # convert any windows style if not isinstance(path_name, Path): file_to_open = Path(path_name) else: file_to_open = path_name assert file_to_open.exists(), 'File does not exist!' img = tifffile.TiffFile(file_to_open) if img.is_bigtiff: header = parse_si_header(img.scanimage_metadata['FrameData']) else: header = parse_si_header(img.scanimage_metadata['Description']) if not header_only: img_data = img.asarray() else: img_data = None return img_data, header
def small_Test_residual(): animal, day = 'IT2', '181115' root = "/Volumes/DATA_01/NL/layerproject/" root = "/Volumes/DATA_01/NL/layerproject/" # TODO: VISUALLY INSPECT A and C. ORDER = 'F' T = 200 rawf_name = "baseline_00001.tif" hf = h5py.File( root + "processed/{}/full_{}_{}__data.hdf5".format(animal, animal, day), 'r') rawf = os.path.join(root, "raw/{}/{}/{}".format(animal, day, rawf_name)) rf = tifffile.TiffFile(rawf) Y = np.concatenate([p.asarray()[:, :, np.newaxis] for p in rf.pages[:T]], axis=2) #shape=(256, 256, T) B = np.array(hf['base_im']).reshape((-1, 4)) #shape=(65536, 4) Yr = Y.reshape((-1, T), order=ORDER) data = hf['Nsparse']['data'] indices = hf['Nsparse']['indices'] indptr = hf['Nsparse']['indptr'] Asparse = csc_matrix((data, indices, indptr)) #(N, P) #Asparse = csc_matrix(np.array(data), np.array(indices), np.array(indptr)) A_all = np.sum(Asparse.toarray(), axis=0) C = hf['C'] C_samp = C[:, :T] CP = Asparse.T @ C_samp R = Yr - CP
def makeJpg(filename, resize, outputFolder): try: kelvin = -273.15 name = ntpath.basename(filename) dt = "" print("BEFORE") with tiff.TiffFile(filename) as tif: imgDataAsNumpy = tif.asarray() # Obtains the DateTime from the tiff file and stores it in dt print(type(tif)) for page in tif: print("AFTER") dt = page.tags['datetime'].value dt = dt.decode("utf-8") #print('Date ', dt) # Gets the maximum and minimum values from the image array which is wrong. h, w = imgDataAsNumpy.shape # Hard code the minimum and maximum values for the color palette temp_min = 213.15 # -60 Celsius temp_max = np.max(imgDataAsNumpy) print('Temperatures ', temp_min + kelvin, temp_max + kelvin) imc = Image.new("P", (w, h)) pco = imc.load() # Computes the minimum index for the palette (equivalent to -32 Celsius) minTempIdx = int(temptoindex(Celsius2Kelvin(-30.0), temp_max, temp_min)) p = creapaleta(minTempIdx) imc.putpalette(p) # Compute the 'color' index temperature value for the image temp = ( (temp_max - imgDataAsNumpy) * 256) / (temp_max - temp_min + .0001) for j in range(h - 1): for i in range(w - 1): pco[i, j] = int(temp[j, i]) hazbarra(imc, minTempIdx) haztitulo(imc, "GOES16 C13 UTC: " + dt, minTempIdx) # print(os.path.dirname(os.path.realpath(__file__))) marco = Image.open( os.path.dirname(os.path.realpath(__file__)) + "/marco.png") out = imc.convert("RGB") out.paste(marco, (0, 0), marco.convert("L")) if (resize < 1.0): out = out.resize((int(w * resize), int(h * resize))) out.save(outputFolder + '/' + name + '.jpg') except Exception as e: print("ERROR: Received at makeJpg") print(e) raise
def read_tiff_voxel_size(file_path): """ Implemented based on information found in https://pypi.org/project/tifffile """ def _xy_voxel_size(tags, key): assert key in ['XResolution', 'YResolution'] if key in tags: num_pixels, units = tags[key].value return units / num_pixels # return default return 1. with tifffile.TiffFile(file_path) as tiff: image_metadata = tiff.imagej_metadata if image_metadata is not None: z = image_metadata.get('spacing', 1.) else: # default voxel size z = 1. tags = tiff.pages[0].tags # parse X, Y resolution y = _xy_voxel_size(tags, 'YResolution') x = _xy_voxel_size(tags, 'XResolution') # return voxel size return [z, y, x]
def loader(opened_file): with tifffile.TiffFile(opened_file) as tif: fh = tif.filehandle for page in tif.pages: fh.seek(page.dataoffsets[0]) fh.read(page.databytecounts[0]) return
def dataSize(filename, **args): """Returns size of data in tif file Arguments: filename (str): file name as regular expression x,y,z (tuple): data range specifications Returns: tuple: data size """ t = tiff.TiffFile(filename) d3 = len(t.pages) d2 = t.pages[0].shape #d2 = (d2[0], d2[1]); if len(d2) == 3: d2 = (d2[2], d2[1], d2[0]) else: d2 = (d2[1], d2[0]) if d3 > 1: dims = d2 + (d3, ) else: dims = d2 return io.dataSizeFromDataRange(dims, **args)
def _get_filenames(self, xml_path, sync_path): super(PrairieHaussIO, self)._get_filenames(xml_path, sync_path) if not os.path.exists(self.filetrunk + "{0:04d}.tif".format(1)): if not os.path.exists(self.dirname): os.makedirs(self.dirname) sys.stdout.write("Converting to individual tiffs... ") sys.stdout.flush() self.mptifs = [tifffile.TiffFile(self.dirname + ".tif")] for mptif in self.mptifs: for nf, frame in enumerate(mptif.pages): tifffile.imsave( self.filetrunk + "{0:04d}.tif".format(nf + 1), frame.asarray()) sys.stdout.write("done\n") if xml_path is None: self.xml_name = self.dirname + ".xml" else: self.xml_name = xml_path # This needs to be done *after* the individual tiffs have been written self.filenames = sorted(glob.glob(self.filetrunk + "*.tif")) if "?" in self.filetrunk: self.ffmpeg_fn = "'" + self.filetrunk + self.format_index( "?") + ".tif'" else: self.ffmpeg_fn = self.filetrunk + self.format_index("%") + ".tif"
def list_of_frames(img_name): """Return the list of frames for an image file. Details are as described in the imgimport_intelligent docstring. """ img = tifffile.TiffFile(img_name) #img = Image.open(img_name) imglist = [] try: for i in range(np.size(img)): imdata = img[i].asarray() # fix 3-channel TIFF images if np.rank(imdata) == 3: imdata = imdata[:, :, 0] + 256 * imdata[:, :, 1] + 65536 * imdata[:, :, 2] imglist.append(imdata) except EOFError: pass if not imglist: raise ImportError, 'No frames detected in file %s' % img_name else: return imglist
def setUp(self): Rois2MasksTestMixin.setUp(self) os.makedirs(self.tempdir) self.filename = os.path.join(self.tempdir, "tmp.tif") tifffile.imsave(self.filename, self.data) self.data = tifffile.TiffFile(self.filename) self.datahandler = extraction.DataHandlerTifffileLazy()
def addLSM(self, ch): #this should be a LSM file containing ch spectral channels # ch=9 valerr = False LSMfile = tkinter.filedialog.askopenfilename( title='Select a .LSM file', filetypes=[("LSM files", "*.LSM")]) if os.path.splitext(LSMfile)[1] == '.lsm': ti = tiff.TiffFile(LSMfile) # read in first file in directory self.SpecfileName.append(LSMfile) self.order.append(ti.series[0].axes.lower()) # self.meta.append(ti.lsm_metadata()) try: self.spectralRange.append( np.asarray(ti.lsm_metadata['ChannelColors'] ['ColorNames']).astype(float)[:ch]) except ValueError: valerr = True ct = 0 for i in ti.lsm_metadata['ChannelColors']['ColorNames']: try: float(i) ct += 1 except: break # self.spectralRange.append(np.asarray(ti.lsm_metadata['ChannelColors']['ColorNames'])[:ct].astype(float)) self.spectralRange.append( np.asarray(ti.lsm_metadata['ChannelColors']['ColorNames']) [:ch].astype(float)) c = ti.series[0].axes.lower().find('c') self.spectralIm.append( np.delete(ti.asarray()[:, :, :ch + 1, :, :], -1, axis=c)) if valerr == False: self.spectralIm.append(ti.asarray()[:, :, :ch, :, :])
def _imload(self, filename): ext = osp.splitext(filename)[-1] if 'tif' in ext: image = tifffile.TiffFile(filename).asarray() else: image = np.array(Image.open(filename)) return image
def read_tiffstack(path): """ converts a tiff stack (image x y dimensions, individual tiff pages t) into a 3d np array, dimensions are (x,y,t)""" data = tifffile.TiffFile(path).asarray() data = data.swapaxes(0,2) # moves t to last dim. tifffile reads pages as first dim return data
def __call__(self, point_number): import tifffile ret = [] for fn in self._fnames_for_point(point_number): with tifffile.TiffFile(fn) as tif: ret.append(tif.asarray()) return np.array(ret).squeeze()
def __iter__(self): first_filename = self._filenames[0] with tifffile.TiffFile(first_filename) as tif: #FLETCHER EDIT summary = tif.shape height, width = summary[1], summary[2] if height % 512 != 0 or width % 512 != 0: raise ValueError("CHAMP currently only supports images with sides that are multiples of 512 pixels.") # if the images are larger than 512x512, we need to subdivide them subrows, subcolumns = range(height / 512), range(width / 512) for file_path in self._filenames: major_axis_position, minor_axis_position = self.axes[file_path] # let the user ignore images in certain columns. This is useful when an experiment is started and # only afterwards do we discover that data on the edges isn't useful. if self._min_column is not None and major_axis_position < self._min_column: continue if self._max_column is not None and major_axis_position > self._max_column: continue for subrow in subrows: minor_axis_label = (minor_axis_position * len(subrows)) + subrow for subcolumn in subcolumns: major_axis_label = (major_axis_position * len(subcolumns)) + subcolumn dataset_name = '(Major, minor) = ({}, {})'.format(major_axis_label, minor_axis_label) #FLETCHER EDIT return dataset_name
def GetThumb(args): filepath = args[0] try: md5val = md5file(filepath) cachefolder = GetCachefolder() thumbpath = '%s/%s.jpg' % (cachefolder, md5val) # create thumb if not os.path.exists(thumbpath): img = tiff.imread(filepath, key=0) # img = cv2.resize(img, (512, 512)) img = transform.resize(img,(512,512)) p2 = np.percentile(img, 0.5) p98 = np.percentile(img, 99.5) img = exposure.rescale_intensity(img, in_range=(p2, p98)) print('MIN',np.min(img),'MAX',np.max(img)) img = (255*img).astype('uint8') img = cv2.applyColorMap(img, cv2.COLORMAP_VIRIDIS) cv2.imwrite(thumbpath, img) dim = tiff.TiffFile(filepath).series[0].shape res = 't\n%s\n%s\n%s' % (filepath, thumbpath, dim) return res except: log('Error in GetThumb, %s, %s' % (filepath,traceback.format_exc())) res = 't\n%s\n%s\n%s' % (filepath, '0','N/A') return res
def load_full_img(path, verbose=True): """ Reads using Tifffile one stack from the Tiff on a 3D Numpy array (TZCYX). :param verbose: :param channel: :param frame: :param meta: :param path: """ import tifffile import sys import numpy as np if verbose: print('Loading the full image...'), sys.stdout.flush() with tifffile.TiffFile(path, fastij=True) as tif: img = tif.asarray() size = (sys.getsizeof(img)) / float(1024**3) if verbose: print(' [Done]') print(np.shape(img)) print('Total of {:.2f} GB'.format(size)) sys.stdout.flush() return img
def openLSM(fname, callback=None): """ open LSM780 file using tifffile """ info = dict() info["type"] = "binned" lsm = tifffile.TiffFile(fname) # two channels 0, 1? info["data_binned"] = lsm.asarray()[0] info["system_clock"] = 1 page = lsm.pages[0] # pixel time in us info["bin_time"] = page.cz_lsm_scan_information["tracks"][0]["pixel_time"] # line time in s -> us info["line_time"] = (page.cz_lsm_time_stamps[1] - page.cz_lsm_time_stamps[0]) * 1e6 # total time in s -> us info["total_time"] = (page.cz_lsm_time_stamps[-1] - page.cz_lsm_time_stamps[0]) * 1e6 info["bins_per_line"] = info["data_binned"].shape[1] info["size"] = info["data_binned"].shape[0] * info["data_binned"].shape[1] info["bin_shift"] = None return info
def _open(self, **kwargs): if not _tifffile: load_lib() self._tf = _tifffile.TiffFile(self.request.get_file(), **kwargs) # metadata is the same for all images self._meta = {}
def load(self, warn=True): if _tf is None: raise NotImplementedError data = [] if self.load_metadata: metadata = dict() else: metadata = None t = _tf.TiffFile(self.name) for i, p in enumerate(t.pages): d = p.asarray() if p.photometric == p.photometric.RGB: # convert to an rgb dataset d = _core.asarray(d, dtype=_core.int16).view(_RGB) if not self.ascolour: d = d.get_grey() data.append(("image-%02d" % (i+1,), d)) if self.load_metadata: for k,v in p.tags.items(): metadata[k] = v.value if len(data) < 1: pass return DataHolder(data, metadata, warn)
def test_tags_rbg_tiled(tmpdir_factory): testfile = "test_data/tiled_rgb_sample.tif" basename = os.path.basename(testfile) with Tiff(testfile) as handle: tags = handle.read_tags() with tifffile.TiffFile(testfile) as handle: page1 = handle.pages[0] tifffile_tags = {} for tag in page1.tags.values(): name, value = tag.name, tag.value tifffile_tags[name] = value image = page1.asarray() compare_tags(tags, tifffile_tags) filename = str(tmpdir_factory.mktemp("write_tags").join(basename)) with Tiff(filename, "w") as handle: handle.set_tags(**tags) handle.write(image, method="tile", tile_length=tags["tile_length"], tile_width=tags["tile_width"]) with Tiff(filename) as handle: written_tags = handle.read_tags() written_image = handle[:] assert np.all(written_image == image) check_written_tags(written_tags, tags)
def step_load_mask(self, operation: MaskMapper, children: List[CalculationTree]): """ Load mask using mask mapper (mask can be defined with suffix, substitution, or file with mapping saved, then iterate over ``children`` nodes. :param MaskMapper operation: operation to perform :param List[CalculationTree] children: list of nodes to iterate over with applied mask """ mask_path = operation.get_mask_path(self.calculation.file_path) if mask_path == "": raise ValueError("Empty path to mask.") with tifffile.TiffFile(mask_path) as mask_file: mask = mask_file.asarray() mask = TiffImageReader.update_array_shape( mask, mask_file.series[0].axes)[..., 0] mask = (mask > 0).astype(np.uint8) try: mask = self.image.fit_array_to_image(mask)[0] # TODO fix this time bug fix except ValueError: raise ValueError("Mask do not fit to given image") old_mask = self.mask self.mask = mask self.iterate_over(children) self.mask = old_mask