def resave_hugin(pto): from xystitch.merger import Merger from xystitch.pto.project import PTOProject # pto_merge -o converted.pto out.pto out.pto blank = PTOProject.from_blank() m = Merger([blank]) m.pto = pto new = m.run(to_pto=True) if new != pto: raise Exception('Expected self merge') dbg('Merge into self')
def run(self): if self.dry: print 'Dry run abort' return bench = Benchmark() if not self.output_project_file_name: raise Exception("need project file") #if not self.output_project_file_name: #self.project_temp_file = ManagedTempFile.get() #self.output_project_file_name = self.project_temp_file.file_name print 'Beginning stitch' print 'output project file name: %s' % self.output_project_file_name #sys.exit(1) self.init_failures() # Generate control points and merge them into a master project self.control_point_gen = get_cp_engine() # How many rows and cols to go to each side # If you hand took the pictures, this might suit you self.project = PTOProject.from_blank() if self.output_project_file_name: self.project.set_file_name(self.output_project_file_name) if os.path.exists(self.output_project_file_name): # Otherwise, we merge into it print 'WARNING: removing old project file: %s' % self.output_project_file_name os.remove(self.output_project_file_name) else: self.project.get_a_file_name(None, "_master.pto") self.project.image_file_names = self.image_file_names try: ''' Generate control points ''' self.generate_control_points() print 'Soften try: %s' % (self.soften_try, ) print 'Soften ok: %s' % (self.soften_ok, ) print 'Post stitch fixup...' optimize_xy_only(self.project) fixup_i_lines(self.project) fixup_p_lines(self.project) print print '***PTO project baseline final (%s / %s) data length %d***' % ( self.project.file_name, self.output_project_file_name, len(self.project.get_text())) print self.failure_json_w() print # Make dead sure its saved up to date self.project.save() # having issues with this.. if self.output_project_file_name and not self.project.file_name == self.output_project_file_name: raise Exception('project file name changed %s %s', self.project.file_name, self.output_project_file_name) # TODO: missing calc opt size/width/height/fov and crop except Exception as e: sys.stdout.flush() sys.stderr.flush() print print 'WARNING: stitch FAILED' traceback.print_exc() try: fn = self.project.file_name + ".failed" print 'Attempting to save intermediate result to %s' % fn self.project.save_as(fn) except: print 'WARNING: failed intermediate save' raise e finally: bench.stop() print 'Stitch done in %s' % bench
def generate_control_points(self): ''' Generate control points Generate to all neighbors to start with ''' print 'PHASE 1: adjacent images' cur_x = 0.0 cur_y = 0.0 x_delta = None y_delta = None # Eliminate special case from main loop for pair in self.linear_pairs_gen(): self.spatial_map.add_point(cur_y, cur_x, pair[0]) break n_pairs = len(set(self.linear_pairs_gen())) cur_pair_index = 0 for pair in self.linear_pairs_gen(): cur_pair_index += 1 print 'Working on %s (%d / %d)' % (repr(pair), cur_pair_index, n_pairs) result = self.analyze_image_pair(pair) if result is None: ''' Two situations: Early on: best guess is to go direction of last Also simple to implement, try always for now If we are at an edge (turn point) we are in trouble For large images this should be a minority if all images are equally likely to have issues Edges might have easier feature detection? Or worse since void Better: calculate average length and see how far we are along in the row Make a guess as to whether we should turn or not ''' print 'Attempting error recovery' # Leave values untouched to save from last loop value # If we failed on the first pass give up if x_delta is None or y_delta is None: raise Exception('Die') print 'Using last delta values: y=%f, x=%f' % (y_delta, x_delta) else: # Common / expected case (x_delta, y_delta) = result cur_x += x_delta cur_y += y_delta # Note we must add the estimate even if its not known self.spatial_map.add_point(cur_y, cur_x, pair[1]) print 'Created %d sub projects' % len(self.sub_projects) phase_1_project = PTOProject.from_blank() print 'Sub projects (full image):' for project in self.sub_projects: # prefix so I can grep it for debugging print '\tSUB: ' + project.file_name phase_1_project.merge_into(self.sub_projects) # Save is more of debug thing now...helps analyze crashes phase_1_project.get_a_file_name() phase_1_project.save() print print print print phase_1_project.text print print print print 'Master project file: %s' % phase_1_project.file_name print 'PHASE 1: done' print 'PHASE 2: fortify' fortify_stitch = FortifyStitch.from_wander(phase_1_project, self.image_file_names, self.tried_pairs, self.spatial_map) fortify_stitch.set_output_project_file_name(self.project.file_name) fortify_stitch.run() self.project = fortify_stitch.project print 'PHASE 2: done'