示例#1
0
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
示例#2
0
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
示例#3
0
    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)
示例#4
0
    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)