def run_print(pto_fn, stdev=3): print('In: %s' % pto_fn) pto = PTOProject.from_file_name(pto_fn) icm = pto2icm(pto) for ((n_fn, N_fn), (nx, ny), (Nx, Ny)) in gen_cps(pto, icm=icm): print("%s:(%s, %s) %s:(%s, %s)" % (n_fn, nx, ny, N_fn, Nx, Ny)) print(" %s, %s" % (nx - Nx, ny - Ny))
def run(pto_fn, pto_fn_out=None, stdev=3.0): print('In: %s' % pto_fn) bench = Benchmark() # TODO: l/r compensation pto = PTOProject.from_file_name(pto_fn) icm = pto2icm(pto) deltas = [] pairs = [] cpls = [] for cpl, ((n_fn, N_fn), (nx, ny), (Nx, Ny)) in gen_cps(pto, icm=icm): delta = ((nx - Nx)**2 + (ny - Ny)**2)**0.5 deltas.append(delta) pairs.append((n_fn, N_fn)) cpls.append(cpl) if tmpdbg and (n_fn == 'c005_r003.jpg' and N_fn == 'c005_r004.jpg'): print('debug', (n_fn, N_fn), (nx, ny), (Nx, Ny)) print('debug', delta) deltas_u = statistics.mean(deltas) deltas_sd = statistics.stdev(deltas) print("Delta mean: %0.1f" % deltas_u) print("Delta stdev: %0.1f" % deltas_sd) _deltas_min = deltas_u - deltas_sd * stdev deltas_max = deltas_u + deltas_sd * stdev outlier_cps = 0 outlier_pairs = set() pair_cur = None pairi = 0 for cpl, (n_fn, N_fn), delta in zip(cpls, pairs, deltas): if pair_cur != (n_fn, N_fn): pairi = 0 pair_cur = (n_fn, N_fn) else: pairi += 1 # really only care about max if delta > deltas_max: # canonical file names fna, fnb = sorted((n_fn, N_fn)) print("%s %s %u: outlier delta %0.1f" % (fna, fnb, pairi, delta)) outlier_pairs.add((fna, fnb)) outlier_cps += 1 pto.remove_control_point_line(cpl) print("") print("Flagged cps: %u" % outlier_cps) print("Flagged pairs: %u" % len(outlier_pairs)) for fna, fnb in sorted(list(outlier_pairs)): print(" %s %s" % (fna, fnb)) if pto_fn_out: pto.save_as(pto_fn_out) bench.stop() print('Completed in %s' % bench)
_outdate = IOTimestamp(sys, 'stdout') _errdate = IOTimestamp(sys, 'stderr') if exist: _outlog.out_fd.write('\n') _outlog.out_fd.write('\n') _outlog.out_fd.write('\n') _outlog.out_fd.write('*' * 80 + '\n') _outlog.out_fd.write('*' * 80 + '\n') _outlog.out_fd.write('*' * 80 + '\n') print 'pr0npto starting' print 'In: %s' % pto_in print 'Out: %s' % pto_out bench = Benchmark() pto = PTOProject.from_file_name(pto_in) # Make sure we don't accidently override the original pto.remove_file_name() config_pto_defaults(pto) if args.center is True: center(pto) if args.anchor: print 'Re-finding anchor' center_anchor(pto) if args.basename: print 'Converting to basename' make_basename(pto)
def run(args): if args.threads < 1: raise Exception('Bad threads') print 'Using %d threads' % args.threads log_dir = args.log out_dir = 'out' _dt = logwt(log_dir, 'main.log', shift_d=True) fn = args.pto[0] auto_size = not (args.stp or args.stm or args.stw or args.sth) print 'Assuming input %s is pto project to be stitched' % args.pto project = PTOProject.from_file_name(args.pto) print 'Creating tiler' stp = None if args.stp: stp = mksize(args.stp) elif args.stm: stp = mem2pix(mksize(args.stm)) print 'Memory %s => %s pix' % (args.stm, size2str(stp)) elif auto_size: stm = config.super_tile_memory() if stm: stp = mem2pix(mksize(stm)) # having issues creating very large if stp > 2**32 / 4: # 66 GB max useful as currently written print 'WARNING: reducing to maximum tile size' stp = 2**32 / 4 t = Tiler(project, out_dir, stw=mksize(args.stw), sth=mksize(args.sth), stp=stp, clip_width=args.clip_width, clip_height=args.clip_height, log_dir=log_dir, is_full=args.full) t.threads = args.threads t.verbose = args.verbose t.st_dir = args.st_dir t.out_extension = args.out_ext t.ignore_errors = args.ignore_errors t.ignore_crop = args.ignore_crop t.st_limit = float(args.st_limit) # TODO: make this more proper? if args.nona_args: t.nona_args = args.nona_args.replace('"', '').split(' ') if args.enblend_args: t.enblend_args = args.enblend_args.replace('"', '').split(' ') if args.super_t_xstep: t.super_t_xstep = args.super_t_xstep if args.super_t_ystep: t.super_t_ystep = args.super_t_ystep if args.clip_width: t.clip_width = args.clip_width if args.clip_height: t.clip_height = args.clip_height # if they specified clip but not supertile step recalculate the step so they don't have to do it if args.clip_width or args.clip_height and not (args.super_t_xstep or args.super_t_ystep): t.recalc_step() t.enblend_lock = args.enblend_lock if args.single_dir and not os.path.exists(args.single_dir): os.mkdir(args.single_dir) print('Running tiler') try: t.run() except KeyboardInterrupt: if t.stale_worker: print 'WARNING: forcing exit on stuck worker' time.sleep(0.5) os._exit(1) raise print('Tiler done!') print('Creating single image') single_fn = args.single_fn if single_fn is None: single_fn = 'out.jpg' if args.single_dir: single_fn = os.path.join(args.single_dir, single_fn) # sometimes I restitch with different supertile size # this results in excessive merge, although really I should just delete the old files if 1: print 'Single: using glob strategy on merge' s_fns = glob.glob(os.path.join(args.st_dir, 'st_*x_*y.jpg')) else: print 'Single: using output strategy' s_fns = t.st_fns single_fn_alt = None if args.single_fn is None: single_fn_alt = single_fn.replace('.jpg', '.tif') try: singlify(s_fns, single_fn, single_fn_alt) except HugeImage: print 'WARNING: single: exceeds max image size, skipped'
def main(): parser = argparse.ArgumentParser( description='create tiles from unstitched images') # +/- 2 => 5 x 5 => 25 images # +/- 3 => 7 x 7 => 49 images parser.add_argument('--xydelta', default=3, type=int, help='border size') parser.add_argument('pto', default='out.pto', nargs='?', help='pto project') args = parser.parse_args() pto_orig = PTOProject.from_file_name(args.pto) print("Finding worst image optimization") n, rms = worst_image(pto_orig) print(("got", n, rms)) il = pto_orig.image_lines[n] fn = il.get_name() refrow, refcol = get_row_col(fn) print((fn, refcol, refrow)) img_fns = [] for il in pto_orig.get_image_lines(): img_fns.append(il.get_name()) icm = ImageCoordinateMap.from_tagged_file_names(img_fns) # Delete all ils not in our ROI pto_orig.build_image_fn_map() ils_keep = set() for col, row in iter_center_cr_max(icm, refcol, refrow, args.xydelta): im = icm.get_image(col, row) if im is None: continue ils_keep.add(pto_orig.img_fn2il[im]) ils_del = set(pto_orig.image_lines) - ils_keep print(("%s - %s image lines, keeping %s" % (len(pto_orig.image_lines), len(ils_del), len(ils_keep)))) # Reduced .pto pto_red = pto_orig.copy() print(('Deleting %d / %d images' % (len(ils_del), icm.width() * icm.height()))) pto_red.del_images(ils_del) print((len(pto_orig.image_lines), len(pto_red.image_lines))) print("Centering...") center(pto_red) print("Set XY var optimization mode...") optimize_xy_only(pto_red) # p w25989 h25989 f0 v165 n"TIFF_m c:LZW" E0.0 R0 S"514,25955,8128,32815" pto_red.get_panorama_line().uncrop() print("Saving preliminary project...") pto_red_fn = pto_orig.file_name.replace('.pto', '_sm.pto') pto_red.save_as(pto_red_fn, is_new_filename=True) print("Fitting FOV") subprocess.check_call("pano_modify --fov=AUTO --canvas=AUTO -o %s %s" % (pto_red_fn, pto_red_fn), shell=True) print(('Opening temp file %s' % pto_red.file_name)) subp = subprocess.Popen(['hugin', pto_red.file_name], shell=False) subp.communicate() print(('Hugin exited with code %d' % subp.returncode)) red_orig_ncpls = len(pto_red.control_point_lines) pto_red.reopen() red_new_ncpls = len(pto_red.control_point_lines) # Filter control point lines # Delete all control points associated with subproject # Then import all new control points print("Deleting stale control points") # Convert image lines to indices iln_keep = set() orig_ncpls = len(pto_orig.control_point_lines) for iln, il in enumerate(pto_orig.image_lines): if il in ils_keep: iln_keep.add(iln) # Filter out any control point lines that were within our ROI cpls_new = [] for cpl in pto_orig.control_point_lines: n = cpl.get_variable("n") N = cpl.get_variable("N") if not (n in iln_keep and N in iln_keep): cpls_new.append(cpl) # Shift into main object, discarding munged cpls print(("cpl filtering %u => %u" % (len(pto_orig.control_point_lines), len(cpls_new)))) pto_orig.control_point_lines = cpls_new red_fn2il = pto_red.build_image_fn_map() red_il2fn = dict([(v, k) for k, v in list(red_fn2il.items())]) red_il2i = pto_red.build_il2i() red_i2il = dict([(v, k) for k, v in list(red_il2i.items())]) full_fn2il = pto_orig.build_image_fn_map() full_il2i = pto_orig.build_il2i() def iln_red2orig(nred): fn = red_il2fn[red_i2il[nred]] return full_il2i[full_fn2il[fn]] # Now add new cpls in # Be very careful translating image indices print("Adding new control points") for cpl in pto_red.control_point_lines: n = cpl.get_variable("n") n2 = iln_red2orig(n) cpl.set_variable('n', n2) N = cpl.get_variable("N") N2 = iln_red2orig(N) cpl.set_variable('N', N2) # print("cpl n=%u N=%u => n=%u N=%u" % (n, N, n2, N2)) cpl.project = pto_orig pto_orig.control_point_lines.append(cpl) print(("image lines", len(pto_orig.image_lines), len(pto_red.image_lines))) print('Saving final project') # small backup in case something went wrong shutil.copy(pto_orig.file_name, 'cphugin_old.pto') pto_orig.save_as(pto_orig.file_name) new_ncpls = len(pto_orig.control_point_lines) print(("roi %u => %u cpls" % (red_orig_ncpls, red_new_ncpls))) print(("pto %u => %u cpls" % (orig_ncpls, new_ncpls))) print('Done!')
from xystitch.image_coordinate_map import ImageCoordinateMap import subprocess import shutil if __name__ == "__main__": parser = argparse.ArgumentParser( description='create tiles from unstitched images') parser.add_argument('--border', default='1', help='border size') parser.add_argument('pto', default='out.pto', nargs='?', help='pto project') args = parser.parse_args() args.border = int(args.border, 0) pto_orig = PTOProject.from_file_name(args.pto) img_fns = [] for il in pto_orig.get_image_lines(): img_fns.append(il.get_name()) icm = ImageCoordinateMap.from_tagged_file_names(img_fns) # Reduced .pto pto_red = pto_orig.copy() # Delete all lines not in the peripheral pto_orig.build_image_fn_map() ils_del = [] for y in xrange(args.border, icm.height() - args.border): for x in xrange(args.border, icm.width() - args.border): im = icm.get_image(x, y) if im is None: continue
def run(args): log_dir = args.log out_dir = 'out' _dt = logwt(log_dir, 'main.log', shift_d=True) fn = args.pto[0] auto_size = not (args.stp or args.stm or args.stw or args.sth) if args.threads < 1: raise Exception('Bad threads') print(('Using %d threads' % args.threads)) print(('Loading %s' % args.pto)) project = PTOProject.from_file_name(args.pto) print('Creating tiler') t = Tiler(project, out_dir, stw=mksize(args.stw), sth=mksize(args.sth), stp=None, clip_width=args.clip_width, clip_height=args.clip_height, log_dir=log_dir, is_full=args.full) t.threads = args.threads t.verbose = args.verbose t.st_dir = args.st_dir t.force = args.force t.merge = args.merge t.out_extension = args.out_ext t.ignore_errors = args.ignore_errors t.ignore_crop = args.ignore_crop t.st_limit = float(args.st_limit) # TODO: make this more proper? if args.nona_args: t.nona_args = args.nona_args.replace('"', '').split(' ') if args.enblend_args: t.enblend_args = args.enblend_args.replace('"', '').split(' ') if args.super_t_xstep: t.super_t_xstep = args.super_t_xstep if args.super_t_ystep: t.super_t_ystep = args.super_t_ystep t.enblend_lock = args.enblend_lock if args.single_dir and not os.path.exists(args.single_dir): os.mkdir(args.single_dir) t.calc_expected_tiles() t.calc_vars() print('Forcing tiler on all images') for fn in glob.glob(args.st_dir + "/*.jpg"): print("") print(("%s" % fn)) im = Image.open(fn) width, height = im.size x0, y0 = coord(fn) #t.make_tile(im, x, y, row, col) st_bounds = [x0, x0 + width, y0, y0 + height] t.process_image(fn, im, st_bounds)
def run(args): log_dir = args.log out_dir = 'out' _outlog, _errlog, outdate, _errdate = logwt(log_dir, 'main.log', shift_d=True) worker_stdout = outdate.fd bench = Benchmark() try: print('Assuming input %s is pto project to be stitched' % args.pto) project = PTOProject.from_file_name(args.pto) print('Creating tiler') threads, stp = make_threads_stp(args) t = Tiler(pto=project, out_dir=out_dir, stw=mksize(args.stw), sth=mksize(args.sth), stp=stp, clip_width=args.clip_width, clip_height=args.clip_height, log_dir=log_dir, is_full=args.full, dry=args.dry, worker_stdout=worker_stdout) t.set_threads(threads) t.set_verbose(args.verbose) t.set_st_dir(args.st_dir) t.set_out_extension(args.out_ext) t.set_ignore_errors(args.ignore_errors) t.set_ignore_crop(args.ignore_crop) t.set_st_limit(float(args.st_limit)) # TODO: make this more proper? if args.nona_args: t.nona_args = args.nona_args.replace('"', '').split(' ') if args.enblend_args: t.enblend_args = args.enblend_args.replace('"', '').split(' ') if args.super_t_xstep: t.set_super_t_xstep(args.super_t_xstep) if args.super_t_ystep: t.set_super_t_ystep(args.super_t_ystep) if args.clip_width: t.set_clip_width(args.clip_width) if args.clip_height: t.set_clip_height(args.clip_height) # if they specified clip but not supertile step recalculate the step so they don't have to do it if args.clip_width or args.clip_height and not (args.super_t_xstep or args.super_t_ystep): t.recalc_step() t.set_enblend_lock(args.enblend_lock) if args.single_dir and not os.path.exists(args.single_dir): os.mkdir(args.single_dir) config.set_enblend_safer_mode(args.safer_mode) config.set_enblend_safest_mode(args.safest_mode) print('Running tiler') try: t.run() except KeyboardInterrupt: if t.stale_worker: print('WARNING: forcing exit on stuck worker') time.sleep(0.5) os._exit(1) raise print('Tiler done!') print('Creating single image') single_fn = args.single_fn if single_fn is None: single_fn = 'out.jpg' if args.single_dir: single_fn = os.path.join(args.single_dir, single_fn) # sometimes I restitch with different supertile size # this results in excessive merge, although really I should just delete the old files if 1: print('Single: using glob strategy on merge') s_fns = glob.glob(os.path.join(args.st_dir, 'st_*x_*y.jpg')) else: print('Single: using output strategy') s_fns = t.st_fns single_fn_alt = None if args.single_fn is None: single_fn_alt = single_fn.replace('.jpg', '.tif') try: singlify(s_fns, single_fn, single_fn_alt) except HugeImage: print('WARNING: single: exceeds max image size, skipped') finally: bench.stop() print('Completed in %s' % bench)
default=False, help='Manually optimize border') args = parser.parse_args() pto_ref_fn = args.pto_ref[0] pto_out_fn = args.pto_out print('Reference in: %s' % pto_ref_fn) print('Out: %s' % pto_out_fn) # Have to start somewhere... pto_out = PTOProject.from_default() # Add the images in for image in args.images: pto_out.add_image(image) pto_ref = PTOProject.from_file_name(pto_ref_fn) pto_ref.remove_file_name() linear_reoptimize(pto_out, pto_ref, allow_missing=args.allow_missing, order=2, border=args.border) print('Centering...') center(pto_out) print('Converting to Hugin form...') resave_hugin(pto_out) print('Saving to %s' % pto_out_fn)