def main(): parser = argparse.ArgumentParser() parser.add_argument('--conv', type=int, default=3, help='Debayer algorithm to use (2,3).') parser.add_argument('--dev', default='cuda') parser.add_argument('image') args = parser.parse_args() # Read Bayer image b = cv2.imread(args.image, cv2.IMREAD_GRAYSCALE) # Init filter deb = debayer.Debayer2x2() if (args.conv == 2) else debayer.Debayer3x3() deb = deb.to(args.dev) # Prepare input with shape Bx1xHxW and t = (torch.from_numpy(b).to(torch.float32).unsqueeze(0).unsqueeze(0).to( args.dev)) / 255.0 # Compute and move back to CPU rgb = (deb(t).squeeze().permute(1, 2, 0).cpu().numpy()) fig, axs = plt.subplots(1, 2) axs[0].imshow(cv2.cvtColor(b, cv2.COLOR_BAYER_BG2RGB) / 255.0, interpolation='nearest') axs[0].set_title('OpenCV') axs[1].imshow(rgb, interpolation='nearest') axs[1].set_title('pytorch-debayer') plt.show()
def run_all(dev, mode): t = (torch.tensor(b).clone().unsqueeze(0).unsqueeze(0)) / 255.0 prec = mode["prec"] mods = { "Debayer2x2": debayer.Debayer2x2(layout=mode["layout"]).to(prec).to(dev), "Debayer3x3": debayer.Debayer3x3(layout=mode["layout"]).to(prec).to(dev), "Debayer5x5": debayer.Debayer5x5(layout=mode["layout"]).to(prec).to(dev), "DebayerSplit": debayer.DebayerSplit(layout=mode["layout"]).to(prec).to(dev), } mods = {k: v for k, v in mods.items() if k in args.methods} if mode["torchscript"]: mods = { k: torch.jit.script( torch.jit.trace( v, torch.rand(1, 1, 128, 128).to(dev).to(prec))) for k, v in mods.items() } for name, mod in mods.items(): e = run_pytorch(mod, t, dev, mode) print(fmt_line(name, devname, e, **mode))
def bench_debayer(b, args): devname = torch.cuda.get_device_name(args.dev) mode = dict(time_upload=args.time_upload, batch_size=args.batch) t = (torch.from_numpy(b).unsqueeze(0).unsqueeze(0)) / 255.0 deb = debayer.Debayer2x2().to(args.dev) deb = deb.to(args.dev) debname = deb.__class__.__name__ e = run_pytorch(deb, t, args.dev, **mode) print(fmt_line(debname, devname, e, **mode)) deb = debayer.Debayer3x3().to(args.dev) deb = deb.to(args.dev) debname = deb.__class__.__name__ e = run_pytorch(deb, t, args.dev, **mode) print(fmt_line(debname, devname, e, **mode))
def main(): logging.basicConfig(level=logging.INFO) parser = argparse.ArgumentParser() parser.add_argument("--dev", default="cuda") parser.add_argument("--half", action="store_true", help="Use 16bit fp precision") parser.add_argument("--save-zoom", action="store_true", help="Save zoom regions") parser.add_argument( "--layout", type=debayer.Layout, choices=list(debayer.Layout), default=debayer.Layout.RGGB, help= "Bayer layout of Bayer input image. Only applicable if --full-color is omitted", # noqa ) parser.add_argument( "--bayer", action="store_true", help="If input image is multi-channel, assume encoding is Bayer", ) parser.add_argument("image") args = parser.parse_args() prec = torch.float16 if args.half else torch.float32 methods = { "Debayer2x2": debayer.Debayer2x2(layout=args.layout).to(args.dev).to(prec), "Debayer3x3": debayer.Debayer3x3(layout=args.layout).to(args.dev).to(prec), "DebayerSplit": debayer.DebayerSplit(layout=args.layout).to(args.dev).to(prec), "Debayer5x5": debayer.Debayer5x5(layout=args.layout).to(args.dev).to(prec), } # Read Bayer image input_image, b = utils.read_image(args.image, bayer=args.bayer, layout=args.layout) # Compute debayer results # Prepare input with shape Bx1xHxW and t = (torch.from_numpy(b).to(prec).unsqueeze(0).unsqueeze(0).to( args.dev)) / 255.0 res = { **{ "Original": input_image, "OpenCV": cv2.cvtColor(b, utils.opencv_conversion_code(args.layout)) / 255.0, }, **{ k: deb(t).squeeze().permute(1, 2, 0).to(torch.float32).cpu().numpy( ) for k, deb in methods.items() }, } nrows = 2 ncols = 3 h, w = b.shape W, H = plt.figaspect((h * nrows) / (w * ncols)) fig = plt.figure(constrained_layout=True, figsize=(W, H)) spec = gridspec.GridSpec(ncols=ncols, nrows=nrows, figure=fig) spec.update(wspace=0, hspace=0) ax = None for idx, (key, img) in enumerate(res.items()): ax = fig.add_subplot(spec[idx], sharey=ax, sharex=ax) ax.imshow(img, interpolation="nearest") ax.set_title(key, size=10, y=1.0, pad=-14, color="white") ax.set_frame_on(False) ax.tick_params( bottom=False, top=False, left=False, right=False, labelleft=False, labelbottom=False, ) def create_image_mosaic(event_ax): left, right = event_ax.get_xlim() top, bottom = event_ax.get_ylim() return utils.create_mosaic(list(res.values()), (left, right, bottom, top), list(res.keys())) def on_ylims_change(event_ax): fig = create_image_mosaic(event_ax) left, right = event_ax.get_xlim() bottom, top = event_ax.get_ylim() left, right, top, bottom = map(int, [left, right, top, bottom]) iname = Path(args.image).with_suffix("").name path = f"tmp/{iname}-mosaic-l{left}-r{right}-b{bottom}-t{top}.png" print("Saved to", path) fig.savefig(path) plt.close(fig) if args.save_zoom: ax.callbacks.connect("ylim_changed", on_ylims_change) plt.show()
def main(): logging.basicConfig(level=logging.INFO) parser = argparse.ArgumentParser() parser.add_argument( "--methods", default=["Debayer3x3", "Debayer5x5", "OpenCV"], nargs="+", help="Which methods to run. List of methods or `all`.", choices=ALL_METHODS + ["all"], ) parser.add_argument("--half", action="store_true", help="Use 16bit fp precision") parser.add_argument("--dev", default="cuda") parser.add_argument("path", type=Path, help="Image file or folder") args = parser.parse_args() # Glob files image_paths = glob_image_paths(args.path) if len(image_paths) == 0: _logger.warning("No image files found") return # Setup precision and algorithms prec = torch.float16 if args.half else torch.float32 if "all" in args.methods: args.methods = ALL_METHODS methods = { "Debayer2x2": debayer.Debayer2x2(layout=LAYOUT).to(args.dev).to(prec), "Debayer3x3": debayer.Debayer3x3(layout=LAYOUT).to(args.dev).to(prec), "DebayerSplit": debayer.DebayerSplit(layout=LAYOUT).to(args.dev).to(prec), "Debayer5x5": debayer.Debayer5x5(layout=LAYOUT).to(args.dev).to(prec), "OpenCV": run_opencv, } methods = {k: v for k, v in methods.items() if k in args.methods} _logger.info(f"Enabled methods {list(methods.keys())}") results = [] for path in image_paths: _logger.info(f"Processing {path}") psnrs, eqmasks = reconstruct(path, methods, args.dev, prec) for method, psnr, eqmask in zip(methods.keys(), psnrs, eqmasks): results.append({ "Path": path, "Database": args.path.name, "Method": method, "R (dB)": psnr[0].item(), "G (dB)": psnr[1].item(), "B (dB)": psnr[2].item(), "PSNR (dB)": psnr.mean().item(), "Equal": eqmask.any().item(), }) import pandas as pd df = pd.DataFrame(results) print() print( df.groupby([df.Database, df.Method])[[ "Database", "Method", "R (dB)", "G (dB)", "B (dB)", "PSNR (dB)" ]].mean().reset_index().to_markdown(headers="keys", index=False, floatfmt=".2f", tablefmt="github"))