def __init__(self): self.path = os.path.join(os.getcwd(), 'tmp') self.prefix = '' self.save_flag = False self._counter = 0 console.show_status(f'Current path is `{self.path}`')
def locate(self, diameter=7, plot_progress=False, **configs): configs['diameter'] = diameter # self.locate_configs has the highest priority configs.update(self.locate_configs) # Calculate locations tic = time.time() # Locate tp.quiet() def after_locate(frame_no, features): # Plot progress if required if plot_progress: self.show_text( self.axes, 'Calculating {}/{} ...'.format(frame_no, self.n_frames)) self.canvas.draw() console.print_progress(frame_no, self.n_frames) return features self.locations = tp.batch(self.objects, processes=0, after_locate=after_locate, **configs) console.show_status('Locating completed. Configurations:') console.supplement(configs) # Clear status if plot_progress: self.axes.cla() self.effective_locate_config = configs
def method(): if self.Keys.locations not in self._pocket: # Calculate locations data_frames = [] tic = time.time() for i in range(self.n_frames): self.show_text('Calculating {}/{} ...'.format( i + 1, self.n_frames)) df = tp.locate(self.images[i], diameter, **kwargs) data_frames.append(df) console.print_progress(i + 1, self.n_frames, start_time=tic) self.put_into_pocket(self.Keys.locations, data_frames, exclusive=False) console.show_status('Locating completed. Configurations:') kwargs['diameter'] = diameter console.supplement(kwargs) # Clear status self.axes.cla() # Display dfs = self.get_from_pocket(self.Keys.locations) tp.annotate(dfs[self.cursor], self.raw_frames[self.cursor], ax=self.axes) # Set title title = ', '.join( ['{} = {}'.format(k, v) for k, v in kwargs.items()]) self.set_axes_style(title)
def _preprocess(self): if self.L is None: return console.show_status('Preprocessing ...') import cv2 resized, dsize = [], (self.L, self.L) self.background = cv2.resize(self.background, dsize) for i, ig in enumerate(self.interferograms): resized.append(cv2.resize(ig, dsize)) console.print_progress(i, len(self.interferograms)) self.interferograms = resized
def set_bookmark(self, n): assert isinstance(n, int) and 0 <= n <= 9 channel = self._determine_list(n) if channel is None: return elif channel is self.layer_plotters: cursor, key = self.layer_cursor, 'plotter' else: cursor, key = self.object_cursor, 'object' self.bookmarks[n] = cursor console.show_status('Bookmark[{}] set on {}[{}]'.format( n, key, self.layer_cursor + 1))
def read(path, fmt=None): if not os.path.exists(path): raise FileExistsError('!! File `{}` does not exist.'.format(path)) # Read image all frames in specified .tif file _, images = cv2.imreadmulti(path) img_seq = np.stack(images) # Process data according to given fmt if fmt in ('grey', 'duplicated_channel'): img_seq = img_seq[..., 0] console.show_status('Read `{}`, data shape: {}'.format( os.path.basename(path), img_seq.shape)) # Wrap data into Video object and return return Video(img_seq)
def save_image(self, image: np.ndarray, filp_flag=True): self.check_path() file_path = os.path.join(self.path, f'{self.prefix}{self.counter}.tif') # Check image if image.dtype in (np.float, ): image = cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U) cv2.imwrite(file_path, image) console.show_status(f'Image saved to `{file_path}`') if filp_flag: self.save_flag = False
def set_path(self): import tkinter as tk from tkinter import filedialog root = tk.Tk() root.withdraw() folder_path = filedialog.askdirectory() if folder_path is None: return self.path = folder_path console.show_status(f'Path set to `{folder_path}`')
def _init(self): # Fetch all interferograms console.show_status(f'Reading interferograms from `{self.path}`') self.interferograms = Retriever.read_interferograms(self.path, seq_id=self.seq_id, radius=80) self.background = self.interferograms[0].bg_array self.interferograms = [ig.img for ig in self.interferograms] self._preprocess() assert self.fetch_fps > 0 self.index = 0 console.show_status('Looping ...')
def save(interferograms: List[Interferogram], save_path, keys=('flattened_phase',), overwrite=False): total = len(interferograms) console.show_status('Generating {} ...'.format(', '.join( ['`{}`'.format(k) for k in keys]))) for i, ig in enumerate(interferograms): console.print_progress(i, total) for key in keys: _ = getattr(ig, key) # Localize intermediate results so that they can be saved by pickle ig.localize('extracted_image') ig.localize('corrected_image') ig.localize('flattened_phase') if os.path.exists(save_path) and not overwrite: raise FileExistsError('!! File `{}` already exist.'.format(save_path)) save(interferograms, save_path) console.show_status('Interferograms saved to `{}`'.format(save_path))
def clear_paths(paths): if len(paths) == 0: return if isinstance(paths, six.string_types): paths = [paths] console.show_status('Cleaning path ...') for path in paths: # Delete all files in path for root, dirs, files in os.walk(path, topdown=False): # Remove directories for folder in dirs: clear_paths(os.path.join(root, folder)) # Delete files for file in files: os.remove(os.path.join(root, file)) # Show status console.supplement('Directory "{}" has been cleared'.format(path))
def toggle_freeze_zoom_in(self): """Works only for 2-D plot""" # Try to get rect info from pocket rect = self.get_from_pocket(self.Keys.selected_rect) # Get full size X, Y = [abs(se[1] - se[0]) for se in self.axes.images[0].sticky_edges[:2]] # Get relative x/y lim xlim, ylim = self.axes.get_xlim(), self.axes.get_ylim() lims = ((xlim[0] / X, xlim[1] / X), (ylim[0] / Y, ylim[1] / Y)) if rect == lims: self.replace_stuff(self.Keys.selected_rect, None) console.show_status('Freeze-zoom-in function has been turned off.') self.refresh() else: self.put_into_pocket(self.Keys.selected_rect, lims, False) console.show_status( 'Zoom-in rect fixed to x:({:.1f}, {:.1f}), y:({:.1f}, {:.1f})'.format( *xlim, *ylim))
def link(self, search_range: int = 5, memory: int = 2, **configs): # Make sure particles have been located if self.locations is None: print(' ! No locations found.') return configs['search_range'] = search_range configs['memory'] = memory # self.link_config has the highest priority configs.update(self.link_configs) # Link locations self.trajectories = tp.link(self.locations, **configs) console.show_status('Linking completed. Configurations:') console.supplement(configs) self.effective_link_config = configs self._draw()
def analyze_dual_conv(self, L, omega=30, rs=(0.3, 0.6, 0.9), merge=False, rotundity=True, show_kernel=True, preprocess=True): from roma import console base_dict = self.get_fourier_dual_basis(L, omega, rs, return_dict=True, rotundity=rotundity) da = DaVinci('Dual Conv Analysis', init_as_image_viewer=True) # Add all if merge: base_dict[(-1, -1)] = np.sum( [np.real(b) for _, b in base_dict.items()], axis=0) if not show_kernel: da.add_image(self.img, 'Raw Interferogram') total = len(base_dict) for i, ((a, r), b) in enumerate(base_dict.items()): console.print_progress(i, total) knl = np.real(b) if show_kernel: im = np.real(knl) else: im = self.dual_conv(knl, mu=None if preprocess else 0) da.add_image(im, 'a={}, r={}'.format(a, r)) if not show_kernel: da.add_image(self.flattened_phase, 'Flattened Phase') console.show_status('Images set to Da Vinci.') da.toggle_log() da.show()
def load_checkpoint(path, session, saver): console.show_status("Access to directory '{}' ...".format(path)) ckpt_state = tf.train.get_checkpoint_state(path) if ckpt_state and ckpt_state.model_checkpoint_path: ckpt_name = os.path.basename(ckpt_state.model_checkpoint_path) saver.restore(session, os.path.join(path, ckpt_name)) # Find counter step_list = re.findall(r'-(\d+)$', ckpt_name) assert len(step_list) == 1 counter = int(step_list[0]) # Try to find rounds rnd_list = re.findall(r'\((\d+.\d+)_rounds\)', ckpt_name) if len(rnd_list) > 0: assert len(rnd_list) == 1 rnd = float(rnd_list[0]) else: rnd = None # Show status console.show_status("Loaded {}".format(ckpt_name)) return True, counter, rnd else: if tfr.context.hub.train and tfr.context.hub.save_model: console.show_status('New checkpoints will be created ...') else: console.warning('Can not found model checkpoint') return False, 0, None
def set_prefix(self, prefix=''): self.prefix = prefix console.show_status(f'Prefix set to `{self.prefix}`')
from roma import console from setuptools import setup # Specify version VERSION = '1.0.0.dev2' # Preprocess console.show_status('Running setup.py for goose-v' + VERSION + ' ...') console.split('-') # Run setup def readme(): with open('README.md', 'r') as f: return f.read() setup( name='goose', packages=['goose'], install_requires=['py-roma'], version=VERSION, description='Gua Gua Gua!', long_description=readme(), long_description_content_type='text/markdown', author='William Ro', author_email='*****@*****.**', url='https://github.com/WilliamRo/goose', download_url='https://github.com/WilliamRo/goose/tarball/v' + VERSION, license='Apache-2.0', keywords=['cloud', 'distributed'],
def export(self, which: str = None, fps: float = 2, cursor_range: str = None, fmt: str = 'gif', path: str = None, n_tail: int = 0): """If `fmt` is `mp4`, ffmpeg must be installed. Official instruction for windows system: https://www.wikihow.com/Install-FFmpeg-on-Windows """ from roma import console import matplotlib.animation as animation import re # Set function if which in (None, '-', '*'): # Try to set _func automatically, not recommended which = 'o' if len(self.objects) > len(self.layer_plotters) else 'l' if which not in ('l', 'o'): raise ValueError('!! First parameter must be `o` or `l`') _func = self.slc if which == 'l' else self.soc # Find cursor range if cursor_range is None: begin, end = 1, len(self.layer_plotters if which == 'l' else self.objects) else: if re.match('^\d+:\d+$', cursor_range) is None: raise ValueError('!! Illegal cursor range `{}`'.format(cursor_range)) begin, end = [int(n) for n in cursor_range.split(':')] end += 1 # Find path if fmt not in ('gif', 'mp4'): raise KeyError('!! `fmt` should be `gif` or `mp4`') if path is None: from tkinter import filedialog path = filedialog.asksaveasfilename() if re.match('.*\.{}$'.format(fmt), path) is None: path += '.{}'.format(fmt) # Find movie writer writer = animation.FFMpegWriter(fps=fps) # Create animation tgt = 'objects' if which == 'o' else 'layers' frames = list(range(begin, end)) # TODO: directly export mp4 file will lose last few frames. Use this code # block to circumvent this issue temporarily if fmt == 'mp4' and n_tail > 0: frames.extend([frames[-1] for _ in range(n_tail)]) console.show_status( 'Saving animation ({}[{}:{}]) ...'.format(tgt, frames[0], frames[-1])) def func(n): console.print_progress(n - begin, total=end - begin) _func(n) # This line is important when this Board is not shown self._draw() ani = animation.FuncAnimation( self.figure, func, frames=frames, interval=1000 / fps) ani.save(path, writer=writer) console.show_status('Animation saved to `{}`.'.format(path))
def read_interferograms( cls, path: str, radius=None, seq_id: int = 1, save=False, save_keys=('flattened_phase',), suffix='') -> List[Interferogram]: """Read a list of interferograms inside the given path. Raw images along with their corresponding background images for calibration should be organized in one of the three ways listed below: (1) path |-sample |-1.tif |- ... |-k.tif # k-th interferogram with sample |- ... |-bg |-1.tif # background of k-th interferogram |- ... |-k.tif |- ... (2) path |-1.tif |-2.tif |- ... |-<2k-1>.tif # k-th interferogram with sample |-<2k>.tif # background of k-th interferogram |- ... (3) path |-1 |-2 |- ... |-p # p-th sequence |-1.tif |- ... |-k.tif # k-th interferogram with sample of p-th sequence |- ... |-bg.tif # common background interferogram of p-th sequence |-... :param path: Trial path :param radius: filter radius in k-space :param seq_id: if interferograms are organized as sequences, only the `seq_id`-th sequence will be read :param save: whether to save interferogram list :param save_keys: contents to be localized :param suffix: file suffix :return: a list of interferograms """ # Read directly if buffer file exist save_fn = cls.get_save_file_name(radius, seq_id, suffix) save_path = os.path.join(path, save_fn) if radius is not None and os.path.exists(save_path): console.show_status('Loading `{}` ...'.format(save_path)) return load(save_path) # Get sample name sample_name = os.path.basename(path) # Find the file organization type by looking at the sub-folders interferograms = [] subfolders = walk(path, type_filter='folder', return_basename=True) # Remove folders which should be ignored if 'trash' in subfolders: subfolders.remove('trash') if 'sample' in subfolders and 'bg' in subfolders: # Case (1) console.show_status('Reading files organized as `sample/bg` ...') sample_folder, bg_folder = [ os.path.join(path, fn) for fn in ('sample', 'bg')] # Scan all sample files in sample folder for sample_path in walk( sample_folder, type_filter='file', pattern='*.tif*'): fn = os.path.basename(sample_path) bg_path = os.path.join(bg_folder, fn) if not os.path.exists(bg_path): console.warning( ' ! Background file `{}` does not exist'.format(bg_path)) else: ig = Interferogram.imread(sample_path, bg_path, radius) interferograms.append(ig) elif len(subfolders) == 0: # Case (2) console.show_status('Reading files organized as `odd/even` ...') file_list = walk( path, type_filter='file', pattern='*.tif', return_basename=True) while len(file_list) > 0: fn = file_list.pop(0) # Get int id index = int(fn.split('.')[0]) # If file is sample if index % 2 == 1: sample_fn = fn bg_fn = '{}.tif'.format(index + 1) mate = bg_fn else: bg_fn = fn sample_fn = '{}.tif'.format(index - 1) mate = sample_fn # Check if mate exists if mate not in file_list: console.warning(' ! Mate file `{}` of `{}` does not exist'.format( mate, fn)) continue # Remove mate from list and append sample/bg path to pairs file_list.remove(mate) # Read interferogram ig = Interferogram.imread( *[os.path.join(path, f) for f in (sample_fn, bg_fn)], radius) interferograms.append(ig) else: # Case (3) assert isinstance(seq_id, int) and seq_id > 0 if str(seq_id) not in subfolders: console.warning('`seq_id` should be one of the following options:') for sf in subfolders: console.supplement(sf, color='red') raise FileNotFoundError path = os.path.join(path, str(seq_id)) console.show_status( 'Reading files from `{}` organized as video sequences ...'.format(path)) # Read background bg = Interferogram.imread(os.path.join(path, 'bg.tif'), radius=radius) total = len(walk(path, 'file', pattern='*.tif')) - 1 for i in range(total): console.print_progress(i, total) p = os.path.join(path, '{}.tif'.format(i + 1)) ig = Interferogram.imread(p, radius=radius) # Using peak_index from background ig.peak_index = bg.peak_index # Set the same background to all interferograms ig._backgrounds = [bg] interferograms.append(ig) # Finalize for ig in interferograms: ig.sample_token = sample_name console.show_status('{} interferograms have been read.'.format( len(interferograms))) # Save if required if radius is not None and save: Retriever.save(interferograms, save_path, save_keys, overwrite=False) return interferograms
def set_background(self): if len(self.buffer) == 0: return self.background = self.buffer[-1] console.show_status('Background has been set')
def pause(self): if self._loop_flag is False: return self._loop_flag = False self._reset_tics() console.show_status('Pause')
def wizard(pattern=None, extension=None, current_dir=None, max_depth=1, input_with_enter=True): assert isinstance(max_depth, int) and max_depth >= 0 assert (isinstance(pattern, str) and len(pattern) > 0 or isinstance(extension, str) and len(extension) > 0) if extension is not None: pattern = r'[\w \(\),-]+\.{}'.format(extension) # if extension is not None: pattern = r'.+\.{}'.format(extension) input = lambda msg: console.read(msg, input_with_enter) is_file = lambda name: re.fullmatch(r'[\w \(\),-]+\.[\w]+', name ) is not None may_be_dir = lambda name: re.fullmatch(r'[\w \(\),-]+', name) is not None is_target = lambda name: re.fullmatch(pattern, name) is not None def contain_target(dir, max_depth): full_path = lambda f: os.path.join(dir, f) for file in os.listdir(dir): if is_file(file): if is_target(file): return True elif (may_be_dir(file) and os.path.isdir(full_path(file)) and max_depth > 0 and contain_target(full_path(file), max_depth - 1)): return True return False def search(dir, max_depth): targets = [] full_path = lambda f: os.path.join(dir, f) for file in os.listdir(dir): # if is_dir(file): if may_be_dir(file) and os.path.isdir(full_path(file)): if max_depth > 0 and contain_target(full_path(file), max_depth - 1): targets.append(file) elif is_target(file): targets.append(file) return targets if current_dir is None: current_dir = os.getcwd() dir_stack = [] selected_file = None while selected_file is None: targets = search(current_dir, max_depth - len(dir_stack)) if len(dir_stack) > 1: targets = list(reversed(targets)) if len(targets) == 0: console.show_status( 'Can not find targets in `{}`'.format(current_dir)) return None # Print targets console.show_status('Current directory is `{}`'.format(current_dir)) for i, t in enumerate(targets): console.supplement('[{}] {}'.format(i + 1, t)) selection = input('=> Please input: ') int_list = list(range(1, 26)) str_list = [str(i) for i in range(1, 10)] + list('abcdefghijklmnop') def get_str(i): return {i: s for i, s in zip(int_list, str_list)}[i] def get_int(s): return {s: i for i, s in zip(int_list, str_list)}[s] while True: if selection in ('..', '0') and len(dir_stack) > 0: current_dir = dir_stack.pop(-1) break elif selection == 'q': quit() elif selection in [get_str(i + 1) for i in range(len(targets))]: file = targets[get_int(selection) - 1] if is_target(file): selected_file = os.path.join(current_dir, file) else: dir_stack.append(current_dir) path = os.path.join(current_dir, file) current_dir = path break else: selection = input( '=> Invalid input `{}`, please input again: '.format( selection)) return selected_file