Example #1
0
	def test_multi(self):
		print 'Multi test'
		project = PTOProject.parse_from_file_name('in.pto')
		remapper = Remapper(project)
		remapper.image_type = Remapper.TIFF_SINGLE
		remapper.run()	
		self.clean()
Example #2
0
	def test_single(self):
		print 'Single test'
		project = PTOProject.from_file_name('in.pto')
		remapper = Remapper(project)
		remapper.image_type = Remapper.TIFF_SINGLE
		remapper.run()	
		self.clean()
Example #3
0
	def test_tile_real(self):
		project = PTOProject.parse_from_file_name('in.pto')
		print 'Creating tiler'
		t = Tiler(project, 'out', st_scalar_heuristic=2)
		self.assertEqual(len(list(t.gen_supertiles())), 4)
		print 'Unit test running tiler (real)'
		t.run()
Example #4
0
	def test_tile_dry(self):
		'''
		Inputs are 1632 x 1224
		a 3 x 3 grid allows testing edge boundary conditions as well as internal
		The reference fully stitched image is 3377 x 2581
		'''
		project = PTOProject.parse_from_file_name('in.pto')
		print 'Creating tiler'
		t = Tiler(project, 'out', st_scalar_heuristic=2)
		#iw = 1632
		#ih = 1224
		#t.set_size_heuristic(iw, ih)
		'''
		Should make 4 tiles with 3 X 3
		'''
		#t.super_tw = 2 * iw
		#t.super_th = 2 * ih
		'''
		Each supertile should cover two images as setup
		There will be some overlap in the center and unique area on all four edges
		'''
		self.assertEqual(len(list(t.gen_supertiles())), 4)
		print 'Unit test running tiler (real)'
		t.dry = True
		t.run()
Example #5
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)
Example #6
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)
Example #7
0
 def test_multi(self):
     print 'Multi test'
     project = PTOProject.from_file_name('in.pto')
     remapper = Remapper(project)
     remapper.image_type = Remapper.TIFF_SINGLE
     remapper.run()
     self.clean()
Example #8
0
 def test_tile_real(self):
     project = PTOProject.from_file_name('in.pto')
     print 'Creating tiler'
     t = Tiler(project, 'out', st_scalar_heuristic=2)
     self.assertEqual(len(list(t.gen_supertiles())), 4)
     print 'Unit test running tiler (real)'
     t.run()
Example #9
0
    def test_tile_dry(self):
        '''
		Inputs are 1632 x 1224
		a 3 x 3 grid allows testing edge boundary conditions as well as internal
		The reference fully stitched image is 3377 x 2581
		'''
        project = PTOProject.from_file_name('in.pto')
        print 'Creating tiler'
        t = Tiler(project, 'out', st_scalar_heuristic=2)
        #iw = 1632
        #ih = 1224
        #t.set_size_heuristic(iw, ih)
        '''
		Should make 4 tiles with 3 X 3
		'''
        #t.super_tw = 2 * iw
        #t.super_th = 2 * ih
        '''
		Each supertile should cover two images as setup
		There will be some overlap in the center and unique area on all four edges
		'''
        self.assertEqual(len(list(t.gen_supertiles())), 4)
        print 'Unit test running tiler (real)'
        t.dry = True
        t.run()
Example #10
0
    def test_optimize(self):
		print 'Loading raw project...'
		project = PTOProject.from_file_name('in.pto')
		print 'Creating optimizer...'
		optimizer = PTOptimizer(project)
		#self.assertTrue(project.text != None)
		print 'Running optimizer...'
		optimizer.run()
Example #11
0
    def test_center_anchor(self):
        project = PTOProject.from_file_name('in.pto')
        center_anchor(project)
        '''
		Image 4 at (1, 1) is the correct answer
		'''
        #vl = project.get_variable_lines()[4]
        project.save()
Example #12
0
	def test_center_anchor(self):
		project = PTOProject.from_file_name('in.pto')
		center_anchor(project)
		'''
		Image 4 at (1, 1) is the correct answer
		'''
		#vl = project.get_variable_lines()[4]
		project.save()
Example #13
0
 def test_optimize(self):
     print 'Loading raw project...'
     project = PTOProject.from_file_name('in.pto')
     print 'Creating optimizer...'
     optimizer = PTOptimizer(project)
     #self.assertTrue(project.text != None)
     print 'Running optimizer...'
     optimizer.run()
Example #14
0
def resave_hugin(pto):
	from pr0ntools.stitch.merger import Merger
	from pr0ntools.stitch.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')
	print 'Merge into self'
Example #15
0
def resave_hugin(pto):
    from pr0ntools.stitch.merger import Merger
    from pr0ntools.stitch.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')
Example #16
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
Example #17
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
Example #18
0
	def run(self, to_pto = False):
		from pr0ntools.stitch.pto.project import PTOProject
		
		others = self.files
		pto = self.pto

		'''Take in a list of pto files and merge them into pto'''
		if to_pto:
			pto_temp_file = self.pto.get_a_file_name()
		else:
			pto_temp_file = ManagedTempFile.get(None, ".pto")

		command = "pto_merge"
		args = list()
	
		args.append("--output=%s" % pto_temp_file)

		# Possible this is still empty
		if pto.file_name and os.path.exists(pto.file_name):
			args.append(pto.file_name)
		for other in others:
			 args.append(other.get_a_file_name())
	
		print_debug(args)

		(rc, output) = Execute.with_output(command, 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 to_pto:
			self.pto.reopen()
			return self.pto
		else:
			return PTOProject.from_temp_file(pto_temp_file)
Example #19
0
    def generate_core(self, image_file_names):
        project_file = ManagedTempFile.get(None, ".pto")

        command = "autopano-sift-c"
        args = list()

        # Try to post process them to make them more accurate
        #args.append("--refine")

        # Perform RANSAC to try to get bad control points out
        #args.append("--ransac")
        #args.append("on")

        # Unlimited matches
        args.append("--maxmatches")
        args.append("0")

        # ?
        #args.append("--maxdim")
        #args.append("10000")

        # Project file
        args.append(project_file.file_name)

        # Images
        for image_file_name in image_file_names:
            args.append(image_file_name)

        # go go go
        #(rc, output) = Execute.with_output(command, args)
        (rc, output) = (exc_ret_istr(command, args), '')
        if not rc == 0:
            print
            print
            print
            print 'output:\n%s' % output

            raise Exception('Bad rc: %d' % rc)

        # We return PTO object, not string
        return PTOProject.from_temp_file(project_file)
Example #20
0
    def generate_core(self, image_file_names):
        project_file = ManagedTempFile.get(None, ".pto")

        command = "autopano-sift-c"
        args = list()

        # Try to post process them to make them more accurate
        # args.append("--refine")

        # Perform RANSAC to try to get bad control points out
        # args.append("--ransac")
        # args.append("on")

        # Unlimited matches
        args.append("--maxmatches")
        args.append("0")

        # ?
        # args.append("--maxdim")
        # args.append("10000")

        # Project file
        args.append(project_file.file_name)

        # Images
        for image_file_name in image_file_names:
            args.append(image_file_name)

        # go go go
        # (rc, output) = Execute.with_output(command, args)
        (rc, output) = (exc_ret_istr(command, args), "")
        if not rc == 0:
            print
            print
            print
            print "output:\n%s" % output

            raise Exception("Bad rc: %d" % rc)

        # We return PTO object, not string
        return PTOProject.from_temp_file(project_file)
Example #21
0
    def generate_core(self, image_file_names):
        command = "autopanoaj"
        args = list()
        project_file = ManagedTempFile.get(None, ".pto")

        # default is .oto
        args.append("/project:hugin")
        # Use image args instead of dir
        args.append("/f")
        args.append('/path:Z:\\tmp')

        # Images
        for image_file_name in image_file_names:
            args.append(image_file_name.replace("/tmp/", "Z:\\tmp\\"))

        # go go go
        #(rc, output) = Execute.with_output(command, args)
        rc, output = exc_ret_istr(command, args, print_out=True)

        if not rc == 0:
            raise Exception('Bad rc: %d' % rc)

        # We return PTO object, not string
        # Ditch the gen file because its unreliable
        shutil.move("/tmp/panorama0.pto", project_file.file_name)
        f = open(project_file.file_name, 'r')
        project_text = f.read()
        # Under WINE, do fixup
        project_text = project_text.replace('Z:\\tmp\\', '/tmp/')
        if 0:
            print
            print
            print
            print project_text
            print
            print
            print
        f.close()
        f = open(project_file.file_name, 'w')
        f.write(project_text)
        return PTOProject.from_temp_file(project_file)
Example #22
0
    def generate_core(self, image_file_names):
        command = "autopanoaj"
        args = list()
        project_file = ManagedTempFile.get(None, ".pto")

        # default is .oto
        args.append("/project:hugin")
        # Use image args instead of dir
        args.append("/f")
        args.append("/path:Z:\\tmp")

        # Images
        for image_file_name in image_file_names:
            args.append(image_file_name.replace("/tmp/", "Z:\\tmp\\"))

        # go go go
        # (rc, output) = Execute.with_output(command, args)
        rc, output = exc_ret_istr(command, args, print_out=True)

        if not rc == 0:
            raise Exception("Bad rc: %d" % rc)

        # We return PTO object, not string
        # Ditch the gen file because its unreliable
        shutil.move("/tmp/panorama0.pto", project_file.file_name)
        f = open(project_file.file_name, "r")
        project_text = f.read()
        # Under WINE, do fixup
        project_text = project_text.replace("Z:\\tmp\\", "/tmp/")
        if 0:
            print
            print
            print
            print project_text
            print
            print
            print
        f.close()
        f = open(project_file.file_name, "w")
        f.write(project_text)
        return PTOProject.from_temp_file(project_file)
Example #23
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)
Example #24
0
				arg_key = arg[2:]

			if arg_key == "help":
				help()
				sys.exit(0)
			else:
				arg_fatal('Unrecognized arg: %s' % arg)
		else:
			if arg.find('.pto') > 0:
				project_file_names.append(arg)
			elif os.path.isfile(arg) or os.path.isdir(arg):
				image_file_names.append(arg)
			else:
				arg_fatal('unrecognized arg: %s' % arg)

	project = PTOProject.from_file_name('panorama0.pto')
	project.parse()
	
	calc_centroid()
	sys.exit(1)
	
	project.regen()
	print
	print
	print
	print project.get_text()
	#project.save_as('out_reparsed.pto')
	print
	print
	print
	
Example #25
0
    def generate_core(self, img_fns):
        # cpfind (and likely cpclean) trashes absolute file names
        # we need to restore them so that tools recognize the file names
        real_fn_base2full = {}

        args = list()
        project = PTOProject.from_default2()
        fn_obj = ManagedTempFile.get(None, ".pto")
        project.set_file_name(fn_obj.file_name)

        # Start with cpfind
        args.append("--prealigned")
        args.append("--fullscale")
        args.append("--minmatches")
        args.append("1")
        args.append("--ransacdist")
        args.append("5")
        args.append("--kdtreeseconddist")
        args.append("0.5")
        # output file
        args.append("-o")
        args.append(project.file_name)
        # input file
        args.append(project.file_name)

        # Images
        for img_fn in img_fns:
            # xxx: why do we take the realpath?
            real_fn = os.path.realpath(img_fn)
            real_fn_base2full[os.path.basename(real_fn)] = img_fn
            project.add_image(real_fn, def_opt=True)

        project.save()
        print
        print
        print
        print project.get_text()
        print
        print
        print

        #(rc, output) = Execute.with_output('cpfind', args, print_output=self.print_output)
        print 'cpfind' + ' '.join(args)
        (rc, output) = exc_ret_istr('cpfind',
                                    args,
                                    print_out=self.print_output)

        print 'PanoCP: cpfind done'
        if not rc == 0:
            print
            print
            print
            print 'output:'
            print output
            print
            # Happens very rarely
            # 2018-01-24T04:00:18.720954: Exception: Bad rc: -11
            # Log it but consider it a known failure
            if rc == -11:
                return None
            raise Exception('Bad rc: %d' % rc)

        # Now run cpclean
        args = list()
        # output file
        args.append("-o")
        args.append(project.file_name)
        # input file
        args.append(project.file_name)

        (rc, output) = exc_ret_istr('cpclean',
                                    args,
                                    print_out=self.print_output)
        print 'PanoCP: cpclean done'
        if not rc == 0:
            print
            print
            print
            print 'output:'
            print output
            print
            raise Exception('Bad rc: %d' % rc)

        # Now run geocpset
        args = list()
        # output file
        args.append("-o")
        args.append(project.file_name)
        # input file
        args.append(project.file_name)

        (rc, output) = exc_ret_istr('geocpset',
                                    args,
                                    print_out=self.print_output)
        print 'PanoCP: geocpset done'
        if not rc == 0:
            print
            print
            print
            print 'output:'
            print output
            print
            raise Exception('Bad rc: %d' % rc)

        project.reopen()
        print 'Fixing image lines...'
        for il in project.image_lines:
            src = il.get_name()
            dst = real_fn_base2full[src.split('/')[-1]]
            print '  %s => %s' % (src, dst)
            il.set_name(dst)

        project.set_file_name(None)
        fn_obj = None

        # Will happen if failed to match
        # be optimistic: cpclean work will be wasted but avoids parsing project twice
        if len(project.get_control_point_lines()) == 0:
            print 'WARNING: failed'
            return None
        return project
Example #26
0
                arg_key = arg[2:]

            if arg_key == "help":
                help()
                sys.exit(0)
            else:
                arg_fatal("Unrecognized arg: %s" % arg)
        else:
            if arg.find(".pto") > 0:
                project_file_names.append(arg)
            elif os.path.isfile(arg) or os.path.isdir(arg):
                image_file_names.append(arg)
            else:
                arg_fatal("unrecognized arg: %s" % arg)

    project = PTOProject.from_file_name("out.pto")
    project.parse()

    reset_photometrics = True
    if reset_photometrics:
        # Overall exposure
        # *very* important
        project.panorama_line.set_variable("E", 1)
        # What about m's p and s?

        for image_line in project.image_lines:
            # Don't adjust exposure
            image_line.set_variable("Eev", 1)
            # blue and red white balance correction at normal levels
            image_line.set_variable("Eb", 1)
            image_line.set_variable("Er", 1)
Example #27
0
 def test_optimize_conversion(self):
     project = PTOProject.from_file_name('in.pto')
     pt = project.copy()
Example #28
0
    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'
Example #29
0
				arg_key = arg[2:]

			if arg_key == "help":
				help()
				sys.exit(0)
			else:
				arg_fatal('Unrecognized arg: %s' % arg)
		else:
			if arg.find('.pto') > 0:
				project_file_names.append(arg)
			elif os.path.isfile(arg) or os.path.isdir(arg):
				image_file_names.append(arg)
			else:
				arg_fatal('unrecognized arg: %s' % arg)

	project = PTOProject.from_file_name('out.pto')
	project.parse()
	
	
	
	# Overall exposure
	# *very* important
	project.panorama_line.set_variable('E', 1)
	# What about m's p and s?

	for image_line in project.image_lines:
		# Don't adjust exposure
		image_line.set_variable('Eev', 1)
		# blue and red white balance correction at normal levels
		image_line.set_variable('Eb', 1)
		image_line.set_variable('Er', 1)
Example #30
0
    def generate_core(self, img_fns):
        # cpfind (and likely cpclean) trashes absolute file names
        # we need to restore them so that tools recognize the file names
        real_fn_base2full = {}
        
        args = list()
        project = PTOProject.from_default2()
        fn_obj = ManagedTempFile.get(None, ".pto")
        project.set_file_name(fn_obj.file_name)
        
        # Start with cpfind
        args.append("--multirow")
        args.append("--fullscale")
        # output file
        args.append("-o")
        args.append(project.file_name)
        # input file
        args.append(project.file_name)
        
        # Images
        for img_fn in img_fns:
            # xxx: why do we take the realpath?
            real_fn = os.path.realpath(img_fn)
            real_fn_base2full[os.path.basename(real_fn)] = img_fn
            project.add_image(real_fn, def_opt=True)

        project.save()
        print
        print
        print
        print project.get_text()
        print
        print
        print
 
        #(rc, output) = Execute.with_output('cpfind', args, print_output=self.print_output)
        (rc, output) = exc_ret_istr('cpfind', args, print_out=self.print_output)
        
        print 'PanoCP: cpfind done'
        if not rc == 0:
            print
            print
            print
            print 'output:'
            print output
            print
            raise Exception('Bad rc: %d' % rc)
        
        
        # Now run cpclean
        args = list()
        # output file
        args.append("-o")
        args.append(project.file_name)
        # input file
        args.append(project.file_name)
        
        (rc, output) = exc_ret_istr('cpclean', args, print_out=self.print_output)
        print 'PanoCP: cpclean done'
        if not rc == 0:
            print
            print
            print
            print 'output:'
            print output
            print
            raise Exception('Bad rc: %d' % rc)


        project.reopen()
        print 'Fixing image lines...'
        for il in project.image_lines:
            src = il.get_name()
            dst = real_fn_base2full[src]
            print '  %s => %s' % (src, dst)
            il.set_name(dst)
        
        project.set_file_name(None)
        fn_obj = None

        # Will happen if failed to match
        # be optimistic: cpclean work will be wasted but avoids parsing project twice
        if len(project.get_control_point_lines()) == 0:
            print 'WARNING: failed'
            return None
        return project
Example #31
0
def ajpto2pto_text(pto_str, sub_image_0_file, sub_image_1_file, sub_image_0_x_delta, sub_image_0_y_delta, sub_to_real, load_images = True):
	'''Take in an old style autopanoaj project and return a .pto object'''

	# image index to subimage file name link (not symbolic link)
	index_to_sub_file_name = dict()
	imgfile_index = 0
	part_pair_index = 0
	
	ret = PTOProject.from_simple()
	
	#out = ''
	
	'''Convert .oto text (like from autopanoaj) to a .pto'''
	# Actually I think really is a .pto, just in a less common format
	for line in pto_str.split('\n'):
		if len(line) == 0:
			continue
		# This type of line is gen by autopano-sift-c
		elif line[0] == 'c':
			# c n0 N1 x1142.261719 y245.074757 X699.189408 Y426.042661 t0
		
			'''
			Okay def alphabetical issues
			# Not strictly related to this code, but close enough
			if not index_to_sub_file_name[0] == sub_image_0_file:
				print '0 index indicated file: %s, pair gen order expected %s' % (index_to_sub_file_name[0], sub_image_0_file)
				raise Exception('mismatch')
			if not index_to_sub_file_name[1] == sub_image_1_file:
				print '1 index indicated file: %s, pair gen order expected %s' % (index_to_sub_file_name[1], sub_image_1_file)
				raise Exception('mismatch')
			'''
		
			# Parse
			parts = line.split()
			if not parts[1] == 'n0':
				print parts[1]
				raise Exception('mismatch')
			if not parts[2] == 'N1':
				print parts[2]
				raise Exception('mismatch')
			
			x = float(parts[3][1:])								
			y = float(parts[4][1:])
			X = float(parts[5][1:])
			Y = float(parts[6][1:])

			#sub_image_1_x_end = image_1.width()
			#sub_image_1_y_end = image_1.height()

			# Adjust the image towards the upper left hand corner
			if index_to_sub_file_name[0] == sub_image_0_file.file_name:
				# normal adjustment
				x += sub_image_0_x_delta
				y += sub_image_0_y_delta
			elif index_to_sub_file_name[1] == sub_image_0_file.file_name:
				# they got flipped
				X += sub_image_0_x_delta
				Y += sub_image_0_y_delta
			else:
				print index_to_sub_file_name
				print 'index_to_sub_file_name[0]: %s' % repr(index_to_sub_file_name[0])
				print 'index_to_sub_file_name[1]: %s' % repr(index_to_sub_file_name[1])
				print 'sub_image_0_file: %s' % repr(sub_image_0_file)
				print 'sub_image_1_file: %s' % repr(sub_image_1_file)
				raise Exception("confused")

			# Write
			new_line = "c n0 N1 x%f y%f X%f Y%f t0" % (x, y, X, Y)
			#out += new_line + '\n'
			ret.add_control_point_line_by_text(new_line)
		# This type of line is generated by pto_merge
		elif line[0] == 'o':
			'''
			#-imgfile 1632 408 "/tmp/pr0ntools_6691335AD228382E.jpg"
			o f0 y+0.000000 r+0.000000 p+0.000000 u20 d0.000000 e0.000000 v70.000000 a0.000000 b0.000000 c0.000000
			to
			i w2816 h704 f0 a0 b-0.01 c0 d0 e0 p0 r0 v180 y0  u10 n"/tmp/pr0ntools_6691335AD228382E.jpg"
			'''
			new_line = ''
			new_line += 'i'
			# Deferred to end
			if 0:
				# panotools fails in very exciting ways if you don't set this
				new_line += ' w%d' % images[0].width()
				new_line += ' w%d' % images[0].height()
			# default FOV
			new_line += ' v51'
			
			orig_fn = index_to_sub_file_name[part_pair_index]
			new_fn = sub_to_real[orig_fn]
			print 'Replacing %s => %s' % (orig_fn, new_fn)
			new_line += ' n"%s"' % new_fn
			
			part_pair_index += 1
			print 'new line: %s' % new_line
			ret.add_image_line_by_text(new_line)
		# These lines are generated by autopanoaj
		# The comment line is literally part of the file format, some sort of bizarre encoding
		# #-imgfile 2816 704 "/tmp/pr0ntools_2D24DE9F6CC513E0/pr0ntools_6575AA69EA66B3C3.jpg"
		# o f0 y+0.000000 r+0.000000 p+0.000000 u20 d0.000000 e0.000000 v70.000000 a0.000000 b0.000000 c0.000000
		elif line.find('#-imgfile') == 0:
			# Replace pseudo file names with real ones
			new_line = line
			index_to_sub_file_name[imgfile_index] = line.split('"')[1]
			imgfile_index += 1
		elif line.find('#') == 0:
			pass
		else:
			#new_line = line
			print 'WARNING: discarding unknown line %s' % line
		#out += new_line + '\n'
	#else:
		#out += line + '\n'

	#ret = PTOProject.from_text(out)
	
	if load_images:
		print 'Fixing up image lines'
		fixup_image_dim(ret)
	
	return ret
Example #32
0
                arg_key = arg[2:]

            if arg_key == "help":
                help()
                sys.exit(0)
            else:
                arg_fatal('Unrecognized arg: %s' % arg)
        else:
            if arg.find('.pto') > 0:
                project_file_names.append(arg)
            elif os.path.isfile(arg) or os.path.isdir(arg):
                image_file_names.append(arg)
            else:
                arg_fatal('unrecognized arg: %s' % arg)

    project = PTOProject.from_file_name('panorama0.pto')
    project.parse()

    calc_centroid()
    sys.exit(1)

    project.regen()
    print
    print
    print
    print project.get_text()
    #project.save_as('out_reparsed.pto')
    print
    print
    print
Example #33
0
        _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()

    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)

    if args.hugin:
Example #34
0
    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
Example #35
0
    def generate_core(self, img_fns):
        # cpfind (and likely cpclean) trashes absolute file names
        # we need to restore them so that tools recognize the file names
        real_fn_base2full = {}

        args = list()
        project = PTOProject.from_default2()
        fn_obj = ManagedTempFile.get(None, ".pto")
        project.set_file_name(fn_obj.file_name)

        # Start with cpfind
        args.append("--multirow")
        args.append("--fullscale")
        # output file
        args.append("-o")
        args.append(project.file_name)
        # input file
        args.append(project.file_name)

        # Images
        for img_fn in img_fns:
            # xxx: why do we take the realpath?
            real_fn = os.path.realpath(img_fn)
            real_fn_base2full[os.path.basename(real_fn)] = img_fn
            project.add_image(real_fn, def_opt=True)

        project.save()
        print
        print
        print
        print project.get_text()
        print
        print
        print

        # (rc, output) = Execute.with_output('cpfind', args, print_output=self.print_output)
        (rc, output) = exc_ret_istr("cpfind", args, print_out=self.print_output)

        print "PanoCP: cpfind done"
        if not rc == 0:
            print
            print
            print
            print "output:"
            print output
            print
            raise Exception("Bad rc: %d" % rc)

        # Now run cpclean
        args = list()
        # output file
        args.append("-o")
        args.append(project.file_name)
        # input file
        args.append(project.file_name)

        (rc, output) = exc_ret_istr("cpclean", args, print_out=self.print_output)
        print "PanoCP: cpclean done"
        if not rc == 0:
            print
            print
            print
            print "output:"
            print output
            print
            raise Exception("Bad rc: %d" % rc)

        project.reopen()
        print "Fixing image lines..."
        for il in project.image_lines:
            src = il.get_name()
            dst = real_fn_base2full[src]
            print "  %s => %s" % (src, dst)
            il.set_name(dst)

        project.set_file_name(None)
        fn_obj = None

        # Will happen if failed to match
        # be optimistic: cpclean work will be wasted but avoids parsing project twice
        if len(project.get_control_point_lines()) == 0:
            print "WARNING: failed"
            return None
        return project
Example #36
0
	def test_center(self):
		project = PTOProject.from_file_name('in.pto')
		center(project)
		(ybar, xbar) = calc_center(project)
		print 'Final xbar %f, ybar %f' % (ybar, xbar)
		project.save()
Example #37
0
	def generate_core(self, image_file_names):
		command = "autopanoaj"
		args = list()
		final_project_file = ManagedTempFile.get(None, ".pto")
		temp_dir = ManagedTempDir.get()
		
		# default is .oto
		args.append("/project:hugin")
		# Use image args instead of dir
		
		# Images
		image_links = dict()
		for image_file_name in image_file_names:
			# args.append(image_file_name.replace("/tmp/", "Z:\\tmp\\"))
			image_file_name = os.path.realpath(image_file_name)

			link_file_name = os.path.join(temp_dir.file_name, os.path.basename(image_file_name))
			print 'Linking %s -> %s' % (link_file_name, image_file_name)
			os.symlink(image_file_name, link_file_name)

		#sys.exit(1)
		# go go go
		(rc, output) = Execute.with_output(command, args, temp_dir.file_name)
		print 'Finished control point pair execution'
		if not rc == 0:
			print
			print
			print
			print 'output:\n%s' % output

			if output.find('This application has requested the Runtime to terminate it in an unusual way'):
				print 'WARNING: skipping crash'
				return None
			
			raise Exception('Bad rc: %d' % rc)
		
		'''
		Doesn't like the match:
		PICTURE PAIRS VALIDATION 
		  Pair (  0,  1)
			Ransac (In : 21, Out : 4, Residu : 4.43799)
			REMOVED
		  Timing : 583.7 us
		'''
		if output.find('REMOVED') >= 0:
			print 'WARNING: RANSAC invalidated control points'
			return None
		
		output_file_name = os.path.join(temp_dir.file_name, "panorama0.pto")
		
		# This happens occassionally, not sure why
		if not os.path.exists(output_file_name):
			print 'WARNING: missing output pto file!'
			return None
		
		# We return PTO object, not string
		# Ditch the gen file because its unreliable
		shutil.move(output_file_name, final_project_file.file_name)
		f = open(final_project_file.file_name, 'r')
		project_text = f.read()
		# Under WINE, do fixup
		# #-imgfile 2816 704 "Z:\tmp\pr0ntools_471477ADA1679A2E\pr0ntools_3CD1C0B1BB218E40.jpg"
		project_text = project_text.replace('Z:\\', '/').replace('\\', '/')
		for image_file_name in image_file_names:
			link_file_name = os.path.join(temp_dir.file_name, os.path.basename(image_file_name))
			print 'Replacing %s -> %s' % (link_file_name, image_file_name)
			project_text = project_text.replace(link_file_name, image_file_name)

		if False:
			print
			print 'Raw control point project (after symbolic link and WINE file name substitution)'
			print
			print
			print project_text
			print
			print
			print
		#sys.exit(1)
		f.close()
		f = open(final_project_file.file_name, 'w')
		f.write(project_text)
		project = PTOProject.from_temp_file(final_project_file)
		return project
Example #38
0
    def test_optimize_conversion(self):
		project = PTOProject.parse_from_file_name('in.pto')
		pt = project.to_ptoptimizer()
Example #39
0
        _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()
    
    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)
        
    if args.hugin:
Example #40
0
	def run(self):
		if self.dry:
			print 'Dry run abort'
			return
	
		if not self.output_project_file_name and not self.output_image_file_name:
			raise Exception("need either project or image 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
		print 'output image file name: %s' % self.output_image_file_name
		
		#sys.exit(1)
		self.init_failures()

		# Generate control points and merge them into a master project
		self.control_point_gen = ControlPointGenerator()
		# 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()
	
			if False:
				self.photometric_optimizer = PhotometricOptimizer(self.project)
				self.photometric_optimizer.run()
	
			# Remove statistically unpleasant points
			if False:
				self.cleaner = PTOClean(self.project)
				self.cleaner.run()
			
			print 'Post stitch fixup...'
			optimize_xy_only(self.project)
			fixup_i_lines(self.project)
			fixup_p_lines(self.project)
			if 0:
				center_anchor(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
			
			if self.failures:
				print 'Writing failure JSON'
				cc = self.failures.critical_count()
				print '%d pairs failed to make %d images critical' % (self.failures.pair_count(), cc)
				if cc:
					print '******WARNING WARNING WARING******'
					print '%d images are not connected' % cc
					print '******WARNING WARNING WARING******'
				open('stitch_failures.json', 'w').write(str(self.failures))
				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)
			
			self.optimize = False
			if self.optimize:
				self.optimizer = optimizer.PTOptimizer(self.project)
				self.optimizer.run()
				center(self.project)
	
			# TODO: missing calc opt size/width/height/fov and crop
			
			# Did we request an actual stitch?
			if self.output_image_file_name:
				print 'Stitching...'
				self.remapper = Remapper(self.project)
				self.remapper.remap(self.output_image_file_name)
			else:
				print 'NOT stitching (common stitch)'
		except Exception as e:
			print
			print 'WARNING: stitch FAILED'
			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
Example #41
0
    def generate_core(self, img_fns):
        # cpfind (and likely cpclean) trashes absolute file names
        # we need to restore them so that tools recognize the file names
        real_fn_base2full = {}

        args = list()
        project = PTOProject.from_default2()
        fn_obj = ManagedTempFile.get(None, ".pto")
        project.set_file_name(fn_obj.file_name)

        # Start with cpfind
        args.append("--multirow")
        args.append("--fullscale")
        # output file
        args.append("-o")
        args.append(project.file_name)
        # input file
        args.append(project.file_name)

        # Images
        for img_fn in img_fns:
            # xxx: why do we take the realpath?
            real_fn = os.path.realpath(img_fn)
            real_fn_base2full[os.path.basename(real_fn)] = img_fn
            project.add_image(real_fn, def_opt=True)

        project.save()
        print
        print
        print
        print project.get_text()
        print
        print
        print

        #(rc, output) = Execute.with_output('cpfind', args, print_output=self.print_output)
        print 'cpfind' + ' '.join(args)
        (rc, output) = exc_ret_istr('cpfind', args, print_out=self.print_output)

        print 'PanoCP: cpfind done'
        if not rc == 0:
            print
            print
            print
            print 'output:'
            print output
            print
            # Happens very rarely
            # 2018-01-24T04:00:18.720954: Exception: Bad rc: -11
            # Log it but consider it a known failure
            if rc == -11:
                return None
            raise Exception('Bad rc: %d' % rc)


        # Now run cpclean
        args = list()
        # output file
        args.append("-o")
        args.append(project.file_name)
        # input file
        args.append(project.file_name)

        (rc, output) = exc_ret_istr('cpclean', args, print_out=self.print_output)
        print 'PanoCP: cpclean done'
        if not rc == 0:
            print
            print
            print
            print 'output:'
            print output
            print
            raise Exception('Bad rc: %d' % rc)


        project.reopen()
        print 'Fixing image lines...'
        for il in project.image_lines:
            src = il.get_name()
            dst = real_fn_base2full[src]
            print '  %s => %s' % (src, dst)
            il.set_name(dst)

        project.set_file_name(None)
        fn_obj = None

        # Will happen if failed to match
        # be optimistic: cpclean work will be wasted but avoids parsing project twice
        if len(project.get_control_point_lines()) == 0:
            print 'WARNING: failed'
            return None
        return project
Example #42
0
    args = parser.parse_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'
Example #43
0
    args = parser.parse_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'
Example #44
0
	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'
Example #45
0
 def test_load(self):
     project = PTOProject.from_file_name('in.pto')
     #self.assertTrue(project.text != None)
     self.assertEqual(len(project.image_lines), 4)
Example #46
0
 def test_center(self):
     project = PTOProject.from_file_name('in.pto')
     center(project)
     (ybar, xbar) = calc_center(project)
     print 'Final xbar %f, ybar %f' % (ybar, xbar)
     project.save()
Example #47
0
    def test_load(self):
		project = PTOProject.from_file_name('in.pto')
		#self.assertTrue(project.text != None)
		self.assertEqual(len(project.image_lines), 4)
Example #48
0
'''

import argparse
from pr0ntools.stitch.pto.project import PTOProject
from pr0ntools.stitch.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
Example #49
0
    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
Example #50
0
    def test_optimize_conversion(self):
		project = PTOProject.from_file_name('in.pto')
		pt = project.copy()
Example #51
0
def usage():
    print 'optimizer <file in> [file out]'
    print 'If file out is not given it will be file in'

if __name__ == "__main__":
    from pr0ntools.stitch.pto.project import PTOProject

    if len(sys.argv) < 2:
        usage()
        sys.exit(1)
    file_name_in = sys.argv[1]
    if len(sys.argv) > 2:
        file_name_out = sys.argv[2]
    else:
        file_name_out = file_name_in
    
    print 'Loading raw project...'
    project = PTOProject.from_file_name(file_name_in)
    print 'Creating optimizer...'
    optimizer = PTOptimizer(project)
    #self.assertTrue(project.text != None)
    print 'Running optimizer...'
    print 'Parsed main pre-run: %s' % str(project.parsed)
    optimizer.run()
    print 'Parsed main: %d' % project.parsed
    print 'Saving...'
    project.save_as(file_name_out)
    print 'Parsed main done: %s' % str(project.parsed)

Example #52
0
                   help='reference project to work on')
	parser.add_argument('images', metavar='images', type=str, nargs='+',
                   help='image files to put int output')
	parser.add_argument('--out', action='store', type=str, dest="pto_out", default="out.pto",
                   help='output file name (default: out.pto)')
	parser.add_argument('--allow-missing', action="store_true", dest="allow_missing", default=True, help='Allow missing images')
	parser.add_argument('--border', action="store_true", dest="border", 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)