def pto_unsub(src_prj, sub_image_files, deltas, sub_to_real): ''' Transforms a sub-project back into original control point coordinate space using original file names Returns a new project file src_prj: base project that needs to be transformed sub_image_files: tuple specifying original project 0/1 positions needed to correctly apply deltas deltas: delta to apply to pair_project coordinates to bring back to target (original) project space 0: x 1: y images are relative to each other only has delta within relative image frame, not entire project canvas sub_to_real: map of project file names to target (original) project file names the output project must use these instead of the original names ''' ret = PTOProject.from_simple() same_order = True # Copy/fix images print 'Order check' for i, src_il in enumerate(src_prj.get_image_lines()): # copy it dst_il = ImageLine(str(src_il), ret) # fix the name so that it can be merged dst_il.set_name(sub_to_real[src_il.get_name()]) # add it ret.add_image_line(dst_il) same_order = same_order and sub_image_files[ i].file_name == src_il.get_name() print ' %d: %s vs %s' % (i, sub_image_files[i].file_name, src_il.get_name()) # Copy/shift control points # Should have been filtered out earlier if len(src_prj.get_control_point_lines()) == 0: raise Exception('No source control point lines') for src_cpl in src_prj.get_control_point_lines(): # copy it dst_cpl = ControlPointLine(str(src_cpl), ret) # shift to original coordinate space if same_order: # normal adjustment dst_cpl.set_variable('x', src_cpl.get_variable('x') + deltas[0]) dst_cpl.set_variable('y', src_cpl.get_variable('y') + deltas[1]) else: # they got flipped dst_cpl.set_variable('X', src_cpl.get_variable('X') + deltas[0]) dst_cpl.set_variable('Y', src_cpl.get_variable('Y') + deltas[1]) # add it ret.add_control_point_line(dst_cpl) return ret
def pto_unsub(src_prj, sub_image_files, deltas, sub_to_real): """ Transforms a sub-project back into original control point coordinate space using original file names Returns a new project file src_prj: base project that needs to be transformed sub_image_files: tuple specifying original project 0/1 positions needed to correctly apply deltas deltas: delta to apply to pair_project coordinates to bring back to target (original) project space 0: x 1: y images are relative to each other only has delta within relative image frame, not entire project canvas sub_to_real: map of project file names to target (original) project file names the output project must use these instead of the original names """ ret = PTOProject.from_simple() same_order = True # Copy/fix images print "Order check" for i, src_il in enumerate(src_prj.get_image_lines()): # copy it dst_il = ImageLine(str(src_il), ret) # fix the name so that it can be merged dst_il.set_name(sub_to_real[src_il.get_name()]) # add it ret.add_image_line(dst_il) same_order = same_order and sub_image_files[i].file_name == src_il.get_name() print " %d: %s vs %s" % (i, sub_image_files[i].file_name, src_il.get_name()) # Copy/shift control points # Should have been filtered out earlier if len(src_prj.get_control_point_lines()) == 0: raise Exception("No source control point lines") for src_cpl in src_prj.get_control_point_lines(): # copy it dst_cpl = ControlPointLine(str(src_cpl), ret) # shift to original coordinate space if same_order: # normal adjustment dst_cpl.set_variable("x", src_cpl.get_variable("x") + deltas[0]) dst_cpl.set_variable("y", src_cpl.get_variable("y") + deltas[1]) else: # they got flipped dst_cpl.set_variable("X", src_cpl.get_variable("X") + deltas[0]) dst_cpl.set_variable("Y", src_cpl.get_variable("Y") + deltas[1]) # add it ret.add_control_point_line(dst_cpl) return ret
def partial_optimize(self, xo0, xo1, yo0, yo1, xf0=0, xf1=0, yf0=0, yf1=0): ''' Return a PTOptimizer optimized sub-self.opt_project o: optimized row/col f: fixed row/col relative to counterpart allows to join in with pre-optimized rows/cols ''' print 'Optimizing base region' print 'Selected base region x(%d:%d), y(%d:%d)' % (xo0, xo1, yo0, yo1) if xf0 > 0: raise Exception('') if xf1 < 0: raise Exception('') if yf0 > 0: raise Exception('') if yf1 < 0: raise Exception('') xf0 += xo0 xf1 += xo1 yf0 += yo0 yf1 += yo1 ''' # Remove all previously selected optimizations project.variable_lines = [] # Mark the selected images for optimization for col in xrange(xo0, xo1 + 1, 1): for row in xrange(yo0, yo1 + 1, 1): fn = self.icm.get_image(col, row) img_i = self.project.img_fn2i(fn) vl = VariableLine('v d%d e%d' % (img_i, img_i), project) project.variable_lines.append(vl) ''' project = PTOProject.from_blank() # Copy special lines # in particular need to keep canvas scale project.set_pano_line_by_text(str(self.opt_project.panorama_line)) project.set_mode_line_by_text(str(self.opt_project.mode_line)) # Copy in image lines # Create a set of all images of interest to make relevant lines easy to find rel_i = set() for col in xrange(xf0, xf1 + 1, 1): for row in xrange(yf0, yf1 + 1, 1): fn = self.icm.get_image(col, row) il = self.project.img_fn2l(fn) rel_i.add(il.get_index()) # Image itself project.image_lines.append(ImageLine(str(il), project)) # save indices to quickly eliminate/replace them cpl_is = [] # Now that all images are added we can add features between them for cpli, cpl in enumerate(self.opt_project.get_control_point_lines()): # c n1 N0 x121.0 y258.0 X133.0 Y1056.0 t0 n = cpl.get_variable('n') N = cpl.get_variable('N') if n in rel_i and N in rel_i: cpl2 = ControlPointLine(str(cpl), project) # Indexes will be different, adjust accordingly cpl2.set_variable('n', project.i2i(self.opt_project, n)) cpl2.set_variable('N', project.i2i(self.opt_project, N)) project.control_point_lines.append(cpl2) cpl_is.append(cpli) anchor = None # All variable? if xo0 == xf0 and xo1 == xf1 and yo0 == yf0 and yo1 == yf1: # Then must anchor solution to a fixed tile anchor = ((xo0 + xo1) / 2, (xf0 + xf1) / 2) # Finally, set images to optimize (XY only) for col in xrange(xo0, xo1 + 1, 1): for row in xrange(yo0, yo1 + 1, 1): # Don't optimize if its the fixed image if (col, row) == anchor: continue fn = self.icm.get_image(col, row) img_i = project.img_fn2i(fn) vl = VariableLine('v d%d e%d' % (img_i, img_i), project) project.variable_lines.append(vl) # In case it crashes do a debug dump pre_run_text = project.get_text() if 0: print project.variable_lines print print print 'PT optimizer project:' print pre_run_text print print raise Exception('Debug break') # "PToptimizer out.pto" args = ["PToptimizer"] args.append(project.get_a_file_name()) #project.save() rc = execute.without_output(args) if rc != 0: fn = '/tmp/pr0nstitch.optimizer_failed.pto' print print print 'Failed rc: %d' % rc print 'Failed project save to %s' % (fn, ) try: open(fn, 'w').write(pre_run_text) except: print 'WARNING: failed to write failure' print print raise Exception('failed position optimization') # API assumes that projects don't change under us project.reopen() ''' Line looks like this # final rms error 24.0394 units ''' rms_error = None for l in project.get_comment_lines(): if l.find('final rms error') >= 00: rms_error = float(l.split()[4]) break print 'Optimize: RMS error of %f' % rms_error # Filter out gross optimization problems if self.rms_error_threshold and rms_error > self.rms_error_threshold: raise Exception("Max RMS error threshold %f but got %f" % (self.rms_error_threshold, rms_error)) if self.debug: print 'Parsed: %s' % str(project.parsed) if self.debug: print print print print 'Optimized project:' print project #sys.exit(1) ret = self.opt_project.copy() print 'Optimized project parsed: %d' % self.opt_project.parsed print 'Merging project...' merge_opt_pto(project, ret) ret.save_as('fixup.pto') return (ret, cpl_is)
def partial_optimize(self, xo0, xo1, yo0, yo1, xf0=0, xf1=0, yf0=0, yf1=0): ''' Return a PTOptimizer optimized sub-self.opt_project o: optimized row/col f: fixed row/col relative to counterpart allows to join in with pre-optimized rows/cols ''' print 'Optimizing base region' print 'Selected base region x(%d:%d), y(%d:%d)' % (xo0, xo1, yo0, yo1) if xf0 > 0: raise Exception('') if xf1 < 0: raise Exception('') if yf0 > 0: raise Exception('') if yf1 < 0: raise Exception('') xf0 += xo0 xf1 += xo1 yf0 += yo0 yf1 += yo1 ''' # Remove all previously selected optimizations project.variable_lines = [] # Mark the selected images for optimization for col in xrange(xo0, xo1 + 1, 1): for row in xrange(yo0, yo1 + 1, 1): fn = self.icm.get_image(col, row) img_i = self.project.img_fn2i(fn) vl = VariableLine('v d%d e%d' % (img_i, img_i), project) project.variable_lines.append(vl) ''' project = PTOProject.from_blank() # Copy special lines # in particular need to keep canvas scale project.set_pano_line_by_text(str(self.opt_project.panorama_line)) project.set_mode_line_by_text(str(self.opt_project.mode_line)) # Copy in image lines # Create a set of all images of interest to make relevant lines easy to find rel_i = set() for col in xrange(xf0, xf1 + 1, 1): for row in xrange(yf0, yf1 + 1, 1): fn = self.icm.get_image(col, row) il = self.project.img_fn2l(fn) rel_i.add(il.get_index()) # Image itself project.image_lines.append(ImageLine(str(il), project)) # save indices to quickly eliminate/replace them cpl_is = [] # Now that all images are added we can add features between them for cpli, cpl in enumerate(self.opt_project.get_control_point_lines()): # c n1 N0 x121.0 y258.0 X133.0 Y1056.0 t0 n = cpl.get_variable('n') N = cpl.get_variable('N') if n in rel_i and N in rel_i: cpl2 = ControlPointLine(str(cpl), project) # Indexes will be different, adjust accordingly cpl2.set_variable('n', project.i2i(self.opt_project, n)) cpl2.set_variable('N', project.i2i(self.opt_project, N)) project.control_point_lines.append(cpl2) cpl_is.append(cpli) anchor = None # All variable? if xo0 == xf0 and xo1 == xf1 and yo0 == yf0 and yo1 == yf1: # Then must anchor solution to a fixed tile anchor = ((xo0 + xo1) / 2, (xf0 + xf1) / 2) # Finally, set images to optimize (XY only) for col in xrange(xo0, xo1 + 1, 1): for row in xrange(yo0, yo1 + 1, 1): # Don't optimize if its the fixed image if (col, row) == anchor: continue fn = self.icm.get_image(col, row) img_i = project.img_fn2i(fn) vl = VariableLine('v d%d e%d' % (img_i, img_i), project) project.variable_lines.append(vl) # In case it crashes do a debug dump pre_run_text = project.get_text() if 0: print project.variable_lines print print print 'PT optimizer project:' print pre_run_text print print raise Exception('Debug break') # "PToptimizer out.pto" args = ["PToptimizer"] args.append(project.get_a_file_name()) #project.save() rc = execute.without_output(args) if rc != 0: fn = '/tmp/pr0nstitch.optimizer_failed.pto' print print print 'Failed rc: %d' % rc print 'Failed project save to %s' % (fn,) try: open(fn, 'w').write(pre_run_text) except: print 'WARNING: failed to write failure' print print raise Exception('failed position optimization') # API assumes that projects don't change under us project.reopen() ''' Line looks like this # final rms error 24.0394 units ''' rms_error = None for l in project.get_comment_lines(): if l.find('final rms error') >= 00: rms_error = float(l.split()[4]) break print 'Optimize: RMS error of %f' % rms_error # Filter out gross optimization problems if self.rms_error_threshold and rms_error > self.rms_error_threshold: raise Exception("Max RMS error threshold %f but got %f" % (self.rms_error_threshold, rms_error)) if self.debug: print 'Parsed: %s' % str(project.parsed) if self.debug: print print print print 'Optimized project:' print project #sys.exit(1) ret = self.opt_project.copy() print 'Optimized project parsed: %d' % self.opt_project.parsed print 'Merging project...' merge_opt_pto(project, ret) ret.save_as('fixup.pto') return (ret, cpl_is)