import re import time class Streamer: def __init__(self, filepath, delay=0.02): self.filepath = filepath self.delay = delay def stream(self): """Yield letters one by one from the file with delay""" with open(self.filepath, "r", encoding="utf-16") as f: content = f.read() for char in content: yield char time.sleep(self.delay) def __iter__(self): return self.stream() # dummy tokenizer class Tokenizer: def __init__(self): pass def decode(tok, skip_special_tokens=False): return tok class RegexStopper: def __init__(self, pattern): super().__init__() self.pattern = pattern self.match = None self.decoded_so_far = "" def __call__(self, new_text, **kwargs): self.decoded_so_far += new_text match = self.pattern.search(self.decoded_so_far) if match: self.match = match self.decoded_so_far = "" return match import cv2 import templates import numpy as np from PIL import Image, ImageFilter def get_cnt_level(i, hierarchy): # hierarchy[i] -> [next, prev, child, parent] level = 0 parent = hierarchy[i][3] while parent != -1: level += 1 parent = hierarchy[parent][3] return level def contour_to_path_data(contour): contour = contour.squeeze() # ensures shape (N,2) if contour.ndim != 2: return "" d = f"M {contour[0,0]} {contour[0,1]}" for x, y in contour[1:]: d += f" L {x} {y}" d += " Z" return d def rectangle_path(width, height): # path string for a rectangle starting at (0, 0). return f"M 0 0 H{width} V{height} H0 Z" def smooth(mask): img_height, img_width = mask.shape mask = Image.fromarray(mask).convert("L") blur_radius = (img_height * img_width) ** 0.5 // 100 blur_mask = mask.filter(ImageFilter.GaussianBlur(radius=blur_radius)) smoooth_mask = np.array(blur_mask) > (255/1.8) smoooth_mask = smoooth_mask.astype(np.uint8) * 255 return smoooth_mask def mask_to_svg(mask): img_height, img_width = mask.shape # Find contours with hierarchy contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) hierarchy = np.squeeze(hierarchy, 0) # ensures shape (N,4), hierarchy[i] -> [next, prev, child, parent] # Organize into SVG components paths = [] mask_idx = 0 masks = [] mask_paths = [] bg_mask_paths = [templates.svg.path.render(elem_class="inner", d=rectangle_path(img_width, img_height))] for i, cnt in enumerate(contours): path_data = contour_to_path_data(cnt) level = get_cnt_level(i, hierarchy) pos_class = "outer" if level % 2 == 0 else "inner" if level == 0: # Wrap any existing level 0 (most-outer clipping mask) if mask_paths: mask = templates.svg.mask.render(mask_idx=mask_idx, paths="\n\t\t\t".join(mask_paths)) masks.append(mask) mask_paths = [] mask_idx += 1 # create new level 0 mask_url = templates.svg.mask_url.render(mask_idx=mask_idx) path = templates.svg.path.render(elem_class=f"{pos_class} level0", d=path_data, mask_url=mask_url) mask_path = templates.svg.path.render(elem_class=pos_class, d=path_data) else: mask_path = path = templates.svg.path.render(elem_class=pos_class, d=path_data) paths.append(path) mask_paths.append(mask_path) bg_mask_paths.append(mask_path) # Wrap any existing level 0 mask = templates.svg.mask.render(mask_idx=mask_idx, paths="\n\t\t\t".join(mask_paths)) masks.append(mask) # wrap bg mask bg_path = templates.svg.bg_path.render(d=rectangle_path(img_width, img_height)) bg_mask = templates.svg.bg_mask.render(paths="\n\t\t\t".join(bg_mask_paths)) # create anatomy svg svg = templates.svg.anatomy.render(width=img_width, height=img_height, bg_mask=bg_mask, masks="\n".join(masks), bg_path=bg_path, paths="\n\t".join(paths)) return svg