from pathlib import Path import time from collections import OrderedDict import numpy as np import cv2 import rawpy import torch import colour_demosaicing class AverageTimer: """Class to help manage printing simple timing of code execution.""" def __init__(self, smoothing=0.3, newline=False): self.smoothing = smoothing self.newline = newline self.times = OrderedDict() self.will_print = OrderedDict() self.reset() def reset(self): now = time.time() self.start = now self.last_time = now for name in self.will_print: self.will_print[name] = False def update(self, name="default"): now = time.time() dt = now - self.last_time if name in self.times: dt = self.smoothing * dt + (1 - self.smoothing) * self.times[name] self.times[name] = dt self.will_print[name] = True self.last_time = now def print(self, text="Timer"): total = 0.0 print("[{}]".format(text), end=" ") for key in self.times: val = self.times[key] if self.will_print[key]: print("%s=%.3f" % (key, val), end=" ") total += val print("total=%.3f sec {%.1f FPS}" % (total, 1.0 / total), end=" ") if self.newline: print(flush=True) else: print(end="\r", flush=True) self.reset() class VideoStreamer: def __init__(self, basedir, resize, image_glob): self.listing = [] self.resize = resize self.i = 0 if Path(basedir).is_dir(): print("==> Processing image directory input: {}".format(basedir)) self.listing = list(Path(basedir).glob(image_glob[0])) for j in range(1, len(image_glob)): image_path = list(Path(basedir).glob(image_glob[j])) self.listing = self.listing + image_path self.listing.sort() if len(self.listing) == 0: raise IOError("No images found (maybe bad 'image_glob' ?)") self.max_length = len(self.listing) else: raise ValueError('VideoStreamer input "{}" not recognized.'.format(basedir)) def load_image(self, impath): raw = rawpy.imread(str(impath)).raw_image_visible raw = np.clip(raw.astype("float32") - 512, 0, 65535) img = colour_demosaicing.demosaicing_CFA_Bayer_bilinear(raw, "RGGB").astype( "float32" ) img = np.clip(img, 0, 16383) m = img.mean() d = np.abs(img - img.mean()).mean() img = (img - m + 2 * d) / 4 / d * 255 image = np.clip(img, 0, 255) w_new, h_new = self.resize[0], self.resize[1] im = cv2.resize( image.astype("float32"), (w_new, h_new), interpolation=cv2.INTER_AREA ) return im def next_frame(self): if self.i == self.max_length: return (None, False) image_file = str(self.listing[self.i]) image = self.load_image(image_file) self.i = self.i + 1 return (image, True) def frame2tensor(frame, device): if len(frame.shape) == 2: return torch.from_numpy(frame / 255.0).float()[None, None].to(device) else: return torch.from_numpy(frame / 255.0).float().permute(2, 0, 1)[None].to(device) def make_matching_plot_fast( image0, image1, mkpts0, mkpts1, color, text, path=None, margin=10, opencv_display=False, opencv_title="", small_text=[], ): H0, W0 = image0.shape[:2] H1, W1 = image1.shape[:2] H, W = max(H0, H1), W0 + W1 + margin out = 255 * np.ones((H, W, 3), np.uint8) out[:H0, :W0, :] = image0 out[:H1, W0 + margin :, :] = image1 # Scale factor for consistent visualization across scales. sc = min(H / 640.0, 2.0) # Big text. Ht = int(30 * sc) # text height txt_color_fg = (255, 255, 255) txt_color_bg = (0, 0, 0) for i, t in enumerate(text): cv2.putText( out, t, (int(8 * sc), Ht * (i + 1)), cv2.FONT_HERSHEY_DUPLEX, 1.0 * sc, txt_color_bg, 2, cv2.LINE_AA, ) cv2.putText( out, t, (int(8 * sc), Ht * (i + 1)), cv2.FONT_HERSHEY_DUPLEX, 1.0 * sc, txt_color_fg, 1, cv2.LINE_AA, ) out_backup = out.copy() mkpts0, mkpts1 = np.round(mkpts0).astype(int), np.round(mkpts1).astype(int) color = (np.array(color[:, :3]) * 255).astype(int)[:, ::-1] for (x0, y0), (x1, y1), c in zip(mkpts0, mkpts1, color): c = c.tolist() cv2.line( out, (x0, y0), (x1 + margin + W0, y1), color=c, thickness=1, lineType=cv2.LINE_AA, ) # display line end-points as circles cv2.circle(out, (x0, y0), 2, c, -1, lineType=cv2.LINE_AA) cv2.circle(out, (x1 + margin + W0, y1), 2, c, -1, lineType=cv2.LINE_AA) # Small text. Ht = int(18 * sc) # text height for i, t in enumerate(reversed(small_text)): cv2.putText( out, t, (int(8 * sc), int(H - Ht * (i + 0.6))), cv2.FONT_HERSHEY_DUPLEX, 0.5 * sc, txt_color_bg, 2, cv2.LINE_AA, ) cv2.putText( out, t, (int(8 * sc), int(H - Ht * (i + 0.6))), cv2.FONT_HERSHEY_DUPLEX, 0.5 * sc, txt_color_fg, 1, cv2.LINE_AA, ) if path is not None: cv2.imwrite(str(path), out) if opencv_display: cv2.imshow(opencv_title, out) cv2.waitKey(1) return out / 2 + out_backup / 2