Esempio n. 1
0
    def run(self):
        from pr0ntools.stitch.pto.project import PTOProject
        
        '''Take in a list of pto files and merge them into pto'''
        pto_temp_file = ManagedTempFile.get(None, ".pto")

        args = ["pto_merge"]
        args.append("--output=%s" % pto_temp_file)

        for pto in self.ptos:
            args.append(pto.get_a_file_name())
    
        print 'MERGING: %s' % (args,)

        rc = execute.without_output(args)
        # go go go
        if not rc == 0:
            print
            print
            print
            #print 'Output:'
            #print output
            print 'rc: %d' % rc
            if rc == 35072:
                # ex: empty projects seem to cause this
                print 'Out of memory, expect malformed project file'
            raise Exception('failed pto_merge')

        if not os.path.exists(str(pto_temp_file)):
            raise Exception('Output file missing: %s' % (pto_temp_file,))

        return PTOProject.from_temp_file(pto_temp_file)
Esempio n. 2
0
    def run(self):
        from pr0ntools.stitch.pto.project import PTOProject
        '''Take in a list of pto files and merge them into pto'''
        pto_temp_file = ManagedTempFile.get(None, ".pto")

        args = ["pto_merge"]
        args.append("--output=%s" % pto_temp_file)

        for pto in self.ptos:
            args.append(pto.get_a_file_name())

        print 'MERGING: %s' % (args, )

        rc = execute.without_output(args)
        # go go go
        if not rc == 0:
            print
            print
            print
            #print 'Output:'
            #print output
            print 'rc: %d' % rc
            if rc == 35072:
                # ex: empty projects seem to cause this
                print 'Out of memory, expect malformed project file'
            raise Exception('failed pto_merge')

        if not os.path.exists(str(pto_temp_file)):
            raise Exception('Output file missing: %s' % (pto_temp_file, ))

        return PTOProject.from_temp_file(pto_temp_file)
Esempio n. 3
0
    def run(self):
        bench = Benchmark()
        
        # The following will assume all of the images have the same size
        self.verify_images()
        
        fns = []
        # Copy project so we can trash it
        project = self.project.copy()
        for il in project.get_image_lines():
            fns.append(il.get_name())
        self.icm = ImageCoordinateMap.from_tagged_file_names(fns)

        pre_opt(project, self.icm)
        prepare_pto(project, reoptimize=False)
        
        # "PToptimizer out.pto"
        args = ["PToptimizer"]
        args.append(project.get_a_file_name())
        print 'Optimizing %s' % project.get_a_file_name()
        #raise Exception()
        #self.project.save()
        rc = execute.without_output(args)
        if rc != 0:
            raise Exception('failed position optimization')
        # API assumes that projects don't change under us
        project.reopen()
        
        # 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))
        
        print 'Merging project...'
        merge_pto(project, self.project)
        if self.debug:
            print self.project
        
        bench.stop()
        print 'Optimized project in %s' % bench
Esempio n. 4
0
    def run(self):
        '''
        The base Hugin project seems to work if you take out a few things:
        Eb1 Eev0 Er1 Ra0 Rb0 Rc0 Rd0 Re0 Va1 Vb0 Vc0 Vd0 Vx-0 Vy-0
        So say generate a project file with all of those replaced
        
        In particular we will generate new i lines
        To keep our original object intact we will instead do a diff and replace the optimized things on the old project
        
        
        Output is merged into the original file and starts after a line with a single *
        Even Hugin wpon't respect this optimization if loaded in as is
        Gives lines out like this
        
        o f0 r0 p0 y0 v51 a0.000000 b0.000000 c0.000000 g-0.000000 t-0.000000 d-0.000000 e-0.000000 u10 -buf 
        These are the lines we care about
        
        C i0 c0  x3996.61 y607.045 X3996.62 Y607.039  D1.4009 Dx-1.15133 Dy0.798094
        Where D is the magnitutde of the distance and x and y are the x and y differences to fitted solution
        
        There are several other lines that are just the repeats of previous lines
        '''
        bench = Benchmark()
        
        # The following will assume all of the images have the same size
        self.verify_images()
        
        # Copy project so we can trash it
        project = self.project.copy()
        prepare_pto(project, self.reoptimize)
        
        pre_run_text = project.get_text()
        if 0:
            print
            print
            print 'PT optimizer project:'
            print pre_run_text
            print
            print
                
        
        # "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)
        print 'Optimized project parsed: %d' % project.parsed

        print 'Merging project...'
        merge_pto(project, self.project)
        if self.debug:
            print self.project
        
        bench.stop()
        print 'Optimized project in %s' % bench
Esempio n. 5
0
    def run(self):
        '''
        The base Hugin project seems to work if you take out a few things:
        Eb1 Eev0 Er1 Ra0 Rb0 Rc0 Rd0 Re0 Va1 Vb0 Vc0 Vd0 Vx-0 Vy-0
        So say generate a project file with all of those replaced
        
        In particular we will generate new i lines
        To keep our original object intact we will instead do a diff and replace the optimized things on the old project
        
        
        Output is merged into the original file and starts after a line with a single *
        Even Hugin wpon't respect this optimization if loaded in as is
        Gives lines out like this
        
        o f0 r0 p0 y0 v51 a0.000000 b0.000000 c0.000000 g-0.000000 t-0.000000 d-0.000000 e-0.000000 u10 -buf 
        These are the lines we care about
        
        C i0 c0  x3996.61 y607.045 X3996.62 Y607.039  D1.4009 Dx-1.15133 Dy0.798094
        Where D is the magnitutde of the distance and x and y are the x and y differences to fitted solution
        
        There are several other lines that are just the repeats of previous lines
        '''
        bench = Benchmark()

        # The following will assume all of the images have the same size
        self.verify_images()

        # Copy project so we can trash it
        project = self.project.copy()
        prepare_pto(project, self.reoptimize)

        pre_run_text = project.get_text()
        if 0:
            print
            print
            print 'PT optimizer project:'
            print pre_run_text
            print
            print

        # "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)
        print 'Optimized project parsed: %d' % project.parsed

        print 'Merging project...'
        merge_pto(project, self.project)
        if self.debug:
            print self.project

        bench.stop()
        print 'Optimized project in %s' % bench

        # These are beyond this scope
        # Move them somewhere else if we want them
        if 0:
            # The following will assume all of the images have the same size
            self.verify_images()

            # Final dimensions are determined by field of view and width
            # Calculate optimial dimensions
            self.calc_dimensions()

            print 'Centering project...'
            self.center_project()
            '''
            WARNING WARNING WARNING
            The panotools model is too advanced for what I'm doing right now
            The image correction has its merits but is mostly getting in the way to distort images
        
            Therefore, I'd like to complete this to understand the intended use but I suspect its not a good idea
            and I could do my own nona style program much better
            The only downside is that if / when I start doing lens model corrections I'll have to rethink this a little
        
            Actually, a lot of these problems go away if I trim to a single tile
            I can use the same FOV as the source image or something similar
            '''
            print 'Calculating optimial field of view to match desired size...'
            self.calc_fov()
Esempio n. 6
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)
Esempio n. 7
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)
Esempio n. 8
0
    def run(self):
        '''
        The base Hugin project seems to work if you take out a few things:
        Eb1 Eev0 Er1 Ra0 Rb0 Rc0 Rd0 Re0 Va1 Vb0 Vc0 Vd0 Vx-0 Vy-0
        So say generate a project file with all of those replaced
        
        In particular we will generate new i lines
        To keep our original object intact we will instead do a diff and replace the optimized things on the old project
        
        
        Output is merged into the original file and starts after a line with a single *
        Even Hugin wpon't respect this optimization if loaded in as is
        Gives lines out like this
        
        o f0 r0 p0 y0 v51 a0.000000 b0.000000 c0.000000 g-0.000000 t-0.000000 d-0.000000 e-0.000000 u10 -buf 
        These are the lines we care about
        
        C i0 c0  x3996.61 y607.045 X3996.62 Y607.039  D1.4009 Dx-1.15133 Dy0.798094
        Where D is the magnitutde of the distance and x and y are the x and y differences to fitted solution
        
        There are several other lines that are just the repeats of previous lines
        '''
        bench = Benchmark()
        
        # The following will assume all of the images have the same size
        self.verify_images()
        
        # Copy project so we can trash it
        project = self.project.copy()
        prepare_pto(project, self.reoptimize)
        
        pre_run_text = project.get_text()
        if 0:
            print
            print
            print 'PT optimizer project:'
            print pre_run_text
            print
            print
                
        
        # "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)
        print 'Optimized project parsed: %d' % project.parsed

        print 'Merging project...'
        merge_pto(project, self.project)
        if self.debug:
            print self.project
        
        bench.stop()
        print 'Optimized project in %s' % bench
        
        # These are beyond this scope
        # Move them somewhere else if we want them
        if 0:
            # The following will assume all of the images have the same size
            self.verify_images()
        
            # Final dimensions are determined by field of view and width
            # Calculate optimial dimensions
            self.calc_dimensions()
        
            print 'Centering project...'
            self.center_project()
        
            '''
            WARNING WARNING WARNING
            The panotools model is too advanced for what I'm doing right now
            The image correction has its merits but is mostly getting in the way to distort images
        
            Therefore, I'd like to complete this to understand the intended use but I suspect its not a good idea
            and I could do my own nona style program much better
            The only downside is that if / when I start doing lens model corrections I'll have to rethink this a little
        
            Actually, a lot of these problems go away if I trim to a single tile
            I can use the same FOV as the source image or something similar
            '''
            print 'Calculating optimial field of view to match desired size...'
            self.calc_fov()