示例#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)
示例#2
0
	def do_merge(self, others):
		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 self.file_name and os.path.exists(self.file_name):
			args.append(self.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
			raise Exception('failed pto_merge')
		return PTOProject.from_temp_file(pto_temp_file)
示例#3
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)
示例#4
0
	def do_get_a_file_name(self, prefix = None, postfix = None):
		'''If doesn't have a real file, create a temp file'''
		if self.file_name:
			return self.file_name
		if postfix is None:
			postfix = ".pto"
		self.temp_file = ManagedTempFile.get(prefix, postfix)
		self.file_name = self.temp_file.file_name
		return self.file_name
示例#5
0
    def get_a_file_name(self, prefix = None, postfix = None):
        '''Return a file name that has current .pto contents'''
        '''If doesn't have a real file, create a temp file'''
        if self.file_name:
            return self.file_name
        if postfix is None:
            postfix = ".pto"
        self.temp_file = ManagedTempFile.get(prefix, postfix)
        self.file_name = self.temp_file.file_name

        # hmmm...
        self.save()
        return self.file_name
示例#6
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)
示例#7
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)
示例#8
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)
示例#9
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)
示例#10
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)
示例#11
0
	def hugin_form(self):
		'''
		Something is causing pto_merge to hang, but NOT ptomerge
		Only occurs if I wrap my commands in a script...
		The script doesn't do any fancy I/O redirection			
			clear
			rm -rf /tmp/pr0ntools_*
			pr0nstitch *.jpg out.pto
		pto_merge produces nicer output than ptomerge
		While ptomerge produces the fields I need, it leaves some other junk
		I think pto_merge also calculates width/heigh attributes


		part of Hugin
		[mcmaster@gespenst first]$ pto_merge
		Warning: pto_merge requires at least 2 project files

		pto_merge: merges several project files
		pto_merge version 2010.4.0.854952d82c8f


		part of perl-Panotools-Script
		[mcmaster@gespenst first]$ ptomerge  --help
		cannot read-open --help at /usr/share/perl5/Panotools/Script.pm line 91.		
		man ptomerge
		...
		ptomerge infile1.pto infile2.pto infile3.pto [...] outfile.pto
		...
		'''
		
		# However, this tool also generates an archaic .pto format that pto can parse, but I don't want to
		# pretend to merge into an empty project to force Hugin to clean it up
		# pto_merge --output=temp.pto /dev/null temp.pto
		if False:
			args = list()
			args.append("%s" % self.get_a_file_name())
			args.append("%s" % self.get_a_file_name())
			args.append("%s" % self.get_a_file_name())
		
			(rc, output) = Execute.with_output("ptomerge", args)
		else:
			args = list()
			args.append("--output=%s" % self.get_a_file_name())
			args.append("%s" % self.get_a_file_name())
		
			if False:
				args.append("/dev/null")
			else:
				empty_file = ManagedTempFile.get(None, ".pto")
				open(empty_file.file_name, 'w').write('')
				args.append(empty_file.file_name)

			(rc, output) = Execute.with_output("pto_merge", args)
			
		if not rc == 0:
			print
			print
			print
			print 'output:%s' % output
			raise Exception('Bad rc: %d' % rc)
		
		self.reopen()		
示例#12
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
示例#13
0
    def try_supertile(self, st_bounds):
        '''x0/1 and y0/1 are global absolute coordinates'''
        # First generate all of the valid tiles across this area to see if we can get any useful work done?
        # every supertile should have at least one solution or the bounds aren't good
        x0, x1, y0, y1 = st_bounds

        bench = Benchmark()
        try:
            if self.st_dir:
                # nah...tiff takes up too much space
                dst = os.path.join(self.st_dir,
                                   'st_%06dx_%06dy.jpg' % (x0, y0))
                if os.path.exists(dst):
                    # normally this is a .tif so slight loss in quality
                    img = PImage.from_file(dst)
                    print 'supertile short circuit on already existing: %s' % (
                        dst, )
                    return img

            # st_081357x_000587y.jpg
            temp_file = ManagedTempFile.get(None,
                                            '.tif',
                                            prefix_mangle='st_%06dx_%06dy_' %
                                            (x0, y0))

            stitcher = PartialStitcher(self.pto,
                                       st_bounds,
                                       temp_file.file_name,
                                       self.i,
                                       self.running,
                                       pprefix=self.pprefix)
            stitcher.enblend_lock = self.enblend_lock
            stitcher.nona_args = self.nona_args
            stitcher.enblend_args = self.enblend_args

            if self.dry:
                print 'dry: skipping partial stitch'
                stitcher = None
            else:
                stitcher.run()

            print
            print 'phase 3: loading supertile image'
            if self.dry:
                print 'dry: skipping loading PTO'
                img_fn = None
            else:
                if self.st_dir:
                    self.st_fns.put(dst)

                    #shutil.copyfile(temp_file.file_name, dst)
                    args = [
                        'convert', '-quality', '90', temp_file.file_name, dst
                    ]
                    print 'going to execute: %s' % (args, )
                    subp = subprocess.Popen(args,
                                            stdout=None,
                                            stderr=None,
                                            shell=False)
                    subp.communicate()
                    if subp.returncode != 0:
                        raise Exception('Failed to copy stitched file')

                    # having some problems that looks like file isn't getting written to disk
                    # monitoring for such errors
                    # remove if I can root cause the source of these glitches
                    for i in xrange(30):
                        if os.path.exists(dst):
                            break
                        if i == 0:
                            print 'WARNING: soften missing strong blur dest file name %s, waiting a bit...' % (
                                dst, )
                        time.sleep(0.1)
                    else:
                        raise Exception(
                            'Missing soften strong blur output file name %s' %
                            dst)

                # FIXME: was passing loaded image object
                # Directory should delete on exit
                # otherwise parent can delete it
                #img = PImage.from_file(temp_file.file_name)
                img_fn = temp_file.file_name
                # prevent deletion
                temp_file.file_name = ''

                #print 'supertile width: %d, height: %d' % (img.width(), img.height())
                print 'Supertile done w/ fn %s' % (img_fn, )
            return img_fn
        except:
            print 'supertile failed at %s' % (bench, )
            raise
示例#14
0
	def try_supertile(self, x0, x1, y0, y1):
		'''x0/1 and y0/1 are global absolute coordinates'''
		# First generate all of the valid tiles across this area to see if we can get any useful work done?
		# every supertile should have at least one solution or the bounds aren't good
		
		bench = Benchmark()
		try:
			temp_file = ManagedTempFile.get(None, '.tif')

			bounds = [x0, x1, y0, y1]
			#out_name_base = "%s/r%03d_c%03d" % (self.out_dir, row, col)
			#print 'Working on %s' % out_name_base
			stitcher = PartialStitcher(self.pto, bounds, temp_file.file_name)
			if self.dry:
				print 'Dry: skipping partial stitch'
				stitcher = None
			else:
				stitcher.run()
		
			print
			print 'Phase 3: loading supertile image'
			if self.dry:
				print 'Dry: skipping loading PTO'
				img = None
			else:
				img = PImage.from_file(temp_file.file_name)
				print 'Supertile width: %d, height: %d' % (img.width(), img.height())
			new = 0
		
			
		
			'''
			A tile is valid if its in a safe location
			There are two ways for the location to be safe:
			-No neighboring tiles as found on canvas edges
			-Sufficiently inside the blend area that artifacts should be minimal
			'''
			gen_tiles = 0
			print
			# TODO: get the old info back if I miss it after yield refactor
			print 'Phase 4: chopping up supertile'
			self.msg('step(x: %d, y: %d)' % (self.tw, self.th), 3)
			#self.msg('x in xrange(%d, %d, %d)' % (xt0, xt1, self.tw), 3)
			#self.msg('y in xrange(%d, %d, %d)' % (yt0, yt1, self.th), 3)
		
			for (y, x) in self.gen_supertile_tiles(x0, x1, y0, y1):	
				# If we made it this far the tile can be constructed with acceptable enblend artifacts
				row = self.y2row(y)
				col = self.x2col(x)
			
				# Did we already do this tile?
				if self.is_done(row, col):
					# No use repeating it although it would be good to diff some of these
					print 'Rejecting tile x%d, y%d / r%d, c%d: already done' % (x, y, row, col)
					continue
			
				# note that x and y are in whole pano coords
				# we need to adjust to our frame
				# row and col on the other hand are used for global naming
				self.make_tile(img, x - x0, y - y0, row, col)
				gen_tiles += 1
			bench.stop()
			print 'Generated %d new tiles for a total of %d / %d in %s' % (gen_tiles, len(self.closed_list), self.net_expected_tiles, str(bench))
			if gen_tiles == 0:
				raise Exception("Didn't generate any tiles")
			# temp_file should be automatically deleted upon exit
		except:
			print 'Supertile failed at %s' % bench
			raise
示例#15
0
    def hugin_form(self):
        '''
        This is used when merging through fortify stitch
        
        Something is causing pto_merge to hang, but NOT ptomerge
        Only occurs if I wrap my commands in a script...
        The script doesn't do any fancy I/O redirection            
            clear
            rm -rf /tmp/pr0ntools_*
            pr0nstitch *.jpg out.pto
        pto_merge produces nicer output than ptomerge
        While ptomerge produces the fields I need, it leaves some other junk
        I think pto_merge also calculates width/heigh attributes


        part of Hugin
        [mcmaster@gespenst first]$ pto_merge
        Warning: pto_merge requires at least 2 project files

        pto_merge: merges several project files
        pto_merge version 2010.4.0.854952d82c8f


        part of perl-Panotools-Script
        [mcmaster@gespenst first]$ ptomerge  --help
        cannot read-open --help at /usr/share/perl5/Panotools/Script.pm line 91.        
        man ptomerge
        ...
        ptomerge infile1.pto infile2.pto infile3.pto [...] outfile.pto
        ...
        '''
        
        # However, this tool also generates an archaic .pto format that pto can parse, but I don't want to
        # pretend to merge into an empty project to force Hugin to clean it up
        # pto_merge --output=temp.pto /dev/null temp.pto
        if False:
            args = list()
            args.append("%s" % self.get_a_file_name())
            args.append("%s" % self.get_a_file_name())
            args.append("%s" % self.get_a_file_name())
        
            (rc, output) = Execute.with_output("ptomerge", args)
        else:
            args = list()
            args.append("--output=%s" % self.get_a_file_name())
            args.append("%s" % self.get_a_file_name())
        
            if False:
                args.append("/dev/null")
            else:
                empty_file = ManagedTempFile.get(None, ".pto")
                open(empty_file.file_name, 'w').write('')
                args.append(empty_file.file_name)

            (rc, output) = Execute.with_output("pto_merge", args)
            
        if not rc == 0:
            print
            print
            print
            if rc == 35072:
                # ex: empty projects seem to cause this
                print 'Out of memory, expect malformed project file'
            print 'output:%s' % output
            raise Exception('Bad rc: %d' % rc)
        
        self.reopen()        
示例#16
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
示例#17
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
示例#18
0
	def control_points_by_subimage(self, pair, pair_images):
		'''
		Just work on the overlap section, maybe even less
		'''
		overlap = 1.0 / 3.0
		
		images = [PImage.from_file(image_file_name) for image_file_name in pair_images]
		
		'''
		image_0 used as reference
		4 basic situations: left, right, up right
		8 extended: 4 basic + corners
		Pairs should be sorted, which simplifies the logic
		'''
		sub_image_0_x_delta = 0
		sub_image_0_y_delta = 0
		sub_image_1_x_end = images[1].width()
		sub_image_1_y_end = images[1].height()

		# image 0 left of image 1?
		if pair.first.col < pair.second.col:
			# Keep image 0 right, image 1 left
			sub_image_0_x_delta = int(images[0].width() * (1.0 - overlap))
			sub_image_1_x_end = int(images[1].width() * overlap)
		
		# image 0 above image 1?
		if pair.first.row < pair.second.row:
			# Keep image 0 top, image 1 bottom
			sub_image_0_y_delta = int(images[0].height() * (1.0 - overlap))
			sub_image_1_y_end = int(images[1].height() * overlap)
		
		'''
		print 'image 0 x delta: %d, y delta: %d' % (sub_image_0_x_delta, sub_image_0_y_delta)
		Note y starts at top in PIL
		'''
		sub_image_0 = images[0].subimage(sub_image_0_x_delta, None, sub_image_0_y_delta, None)
		sub_image_1 = images[1].subimage(None, sub_image_1_x_end, None, sub_image_1_y_end)
		sub_image_0_file = ManagedTempFile.get(None, '.jpg')
		sub_image_1_file = ManagedTempFile.get(None, '.jpg')
		print 'sub image 0: width=%d, height=%d, name=%s' % (sub_image_0.width(), sub_image_0.height(), sub_image_0_file.file_name)
		print 'sub image 1: width=%d, height=%d, name=%s' % (sub_image_1.width(), sub_image_1.height(), sub_image_0_file.file_name)
		#sys.exit(1)
		sub_image_0.image.save(sub_image_0_file.file_name)
		sub_image_1.image.save(sub_image_1_file.file_name)
		
		sub_pair_images = (sub_image_0_file.file_name, sub_image_1_file.file_name)
		# image index to subimage file name link (not symbolic link)
		index_to_sub_file_name = dict()
		imgfile_index = 0
		# subimage file name symbolic link to subimage file name
		# this should be taken care of inside of control point actually
		#sub_link_to_sub = dict()
		# subimage to the image it came from
		sub_to_real = dict()
		sub_to_real[sub_image_0_file.file_name] = pair_images[0]
		sub_to_real[sub_image_1_file.file_name] = pair_images[1]

		'''
		# Hugin project file
		# generated by Autopano

		# Panorama settings:
		p w8000 h1200 f2 v250 n"PSD_mask"

		# input images:
		#-imgfile 2816 704 "/tmp/pr0ntools_C21F246F52E9D691/AA9627DC60B39FC8.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
		#-imgfile 2816 704 "/tmp/pr0ntools_C21F246F52E9D691/EDE10C14171B2078.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

		# Control points:
		c n0 N1 x1024 y176 X555 Y119
		# Control Point No 0: 1.00000
		c n0 N1 x1047 y160 X578 Y105
		...




		autopano-sift-c style file
		
		# Hugin project file generated by APSCpp

		p f2 w3000 h1500 v360  n"JPEG q90"
		m g1 i0

		i w2816 h704 f0 a0 b-0.01 c0 d0 e0 p0 r0 v180 y0  u10 n"/tmp/pr0ntools_6691335AD228382E.jpg"
		i w2816 h938 f0 a0 b-0.01 c0 d0 e0 p0 r0 v180 y0  u10 n"/tmp/pr0ntools_64D97FF4621BC36E.jpg"

		v p1 r1 y1

		# automatically generated control points
		c n0 N1 x1142.261719 y245.074757 X699.189408 Y426.042661 t0
		c n0 N1 x887.417450 y164.602097 X1952.346197 Y921.975829 t0
		...
		c n0 N1 x823.803714 y130.802771 X674.596763 Y335.994699 t0
		c n0 N1 x1097.192159 y121.170416 X937.394996 Y329.998934 t0

		# :-)
		'''
		fast_pair_project = self.control_point_gen.generate_core(sub_pair_images)
		if fast_pair_project is None:
			print 'WARNING: failed to gen control points @ %s' % repr(pair)
			return None
		out = ''
		part_pair_index = 0
		for line in fast_pair_project.__repr__().split('\n'):
			if len(line) == 0:
				new_line = ''
			# 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'
			# This type of line is generated by pto_merge
			elif line[0] == 'i':
				# i w2816 h704 f0 a0 b-0.01 c0 d0 e0 p0 r0 v180 y0  u10 n"/tmp/pr0ntools_6691335AD228382E.jpg"
				new_line = ''
				for part in line.split():
					t = part[0]
					if t == 'i':
						new_line += 'i'
					elif t == 'w':
						new_line += ' w%d' % images[0].width()
					elif t == 'h':
						new_line += ' w%d' % images[0].height()
					elif t == 'n':
						new_line += ' n%s' % pair_images[part_pair_index]
						part_pair_index += 1
					else:
						new_line += ' %s' % part
				print 'new line: %s' % 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
			else:
				new_line = line
			out += new_line + '\n'
		else:
			out += line + '\n'

		
		for k in sub_to_real:
			v = sub_to_real[k]
			print 'Replacing %s => %s' % (k, v)
			out = out.replace(k, v)

		final_pair_project = PTOProject.from_text(out)
		return final_pair_project
示例#19
0
    def try_supertile(self, st_bounds):
        '''x0/1 and y0/1 are global absolute coordinates'''
        # First generate all of the valid tiles across this area to see if we can get any useful work done?
        # every supertile should have at least one solution or the bounds aren't good
        x0, x1, y0, y1 = st_bounds

        bench = Benchmark()
        try:
            if self.st_dir:
                # nah...tiff takes up too much space
                dst = os.path.join(self.st_dir, 'st_%06dx_%06dy.jpg' % (x0, y0))
                if os.path.exists(dst):
                    # normally this is a .tif so slight loss in quality
                    print 'supertile short circuit on already existing: %s' % (dst,)
                    return dst
                
            # st_081357x_000587y.jpg
            temp_file = ManagedTempFile.get(None, '.tif', prefix_mangle='st_%06dx_%06dy_' % (x0, y0))

            stitcher = PartialStitcher(self.pto, st_bounds, temp_file.file_name, self.i, self.running, pprefix=self.pprefix)
            stitcher.enblend_lock = self.enblend_lock
            stitcher.nona_args = self.nona_args
            stitcher.enblend_args = self.enblend_args

            if self.dry:
                print 'dry: skipping partial stitch'
                stitcher = None
            else:
                stitcher.run()
        
            print
            print 'phase 3: loading supertile image'
            if self.dry:
                print 'dry: skipping loading PTO'
                img_fn = None
            else:
                if self.st_dir:
                    self.st_fns.put(dst)
                    
                    #shutil.copyfile(temp_file.file_name, dst)
                    args = ['convert',
                            '-quality', '90', 
                            temp_file.file_name, dst]                    
                    print 'going to execute: %s' % (args,)
                    subp = subprocess.Popen(args, stdout=None, stderr=None, shell=False)
                    subp.communicate()
                    if subp.returncode != 0:
                        raise Exception('Failed to copy stitched file')

                    # having some problems that looks like file isn't getting written to disk
                    # monitoring for such errors
                    # remove if I can root cause the source of these glitches
                    for i in xrange(30):
                        if os.path.exists(dst):
                            break
                        if i == 0:
                            print 'WARNING: soften missing strong blur dest file name %s, waiting a bit...' % (dst,)
                        time.sleep(0.1)
                    else:
                        raise Exception('Missing soften strong blur output file name %s' % dst)

                # FIXME: was passing loaded image object
                # Directory should delete on exit
                # otherwise parent can delete it
                #img = PImage.from_file(temp_file.file_name)
                img_fn = temp_file.file_name
                # prevent deletion
                temp_file.file_name = ''
                
                #print 'supertile width: %d, height: %d' % (img.width(), img.height())
                print 'Supertile done w/ fn %s' % (img_fn,)
            return img_fn
        except:
            print 'supertile failed at %s' % (bench,)
            raise
示例#20
0
	def control_points_by_subimage(self, pair, image_fn_pair, subimage_factor = None):
		'''Stitch two images together by cropping to restrict overlap'''
		
		# subimage_factor: (y, x) overlap percent tuple or none for default
		# pair: pair of row/col or coordinate positions (used to determine relative positions)
		# (0, 0) at upper left
		# image_fn_pair: pair of image file names
		
		print 'Preparing subimage stitch on %s:%s' % (image_fn_pair[0], image_fn_pair[1])
		'''
		Just work on the overlap section, maybe even less
		'''
		
		images = [PImage.from_file(image_file_name) for image_file_name in image_fn_pair]
		
		'''
		image_0 used as reference
		4 basic situations: left, right, up right
		8 extended: 4 basic + corners
		Pairs should be sorted, which simplifies the logic
		'''
		sub_image_0_x_delta = 0
		sub_image_0_y_delta = 0
		sub_image_1_x_end = images[1].width()
		sub_image_1_y_end = images[1].height()

		if subimage_factor:
			y_overlap = subimage_factor[0]
			x_overlap = subimage_factor[1]
		else:
			x_overlap = self.x_overlap
			y_overlap = self.y_overlap

		# image 0 left of image 1?
		if pair.first.col < pair.second.col:
			# Keep image 0 right, image 1 left
			sub_image_0_x_delta = int(images[0].width() * (1.0 - x_overlap))
			sub_image_1_x_end = int(images[1].width() * x_overlap)
		
		# image 0 above image 1?
		if pair.first.row < pair.second.row:
			# Keep image 0 top, image 1 bottom
			sub_image_0_y_delta = int(images[0].height() * (1.0 - y_overlap))
			sub_image_1_y_end = int(images[1].height() * y_overlap)
		
		'''
		print 'image 0 x delta: %d, y delta: %d' % (sub_image_0_x_delta, sub_image_0_y_delta)
		Note y starts at top in PIL
		'''
		sub_image_0 = images[0].subimage(sub_image_0_x_delta, None, sub_image_0_y_delta, None)
		sub_image_1 = images[1].subimage(None, sub_image_1_x_end, None, sub_image_1_y_end)
		sub_image_0_file = ManagedTempFile.get(None, '.jpg')
		sub_image_1_file = ManagedTempFile.get(None, '.jpg')
		print 'sub image 0: width=%d, height=%d, name=%s' % (sub_image_0.width(), sub_image_0.height(), sub_image_0_file.file_name)
		print 'sub image 1: width=%d, height=%d, name=%s' % (sub_image_1.width(), sub_image_1.height(), sub_image_0_file.file_name)
		#sys.exit(1)
		sub_image_0.image.save(sub_image_0_file.file_name)
		sub_image_1.image.save(sub_image_1_file.file_name)
		
		sub_image_fn_pair = (sub_image_0_file.file_name, sub_image_1_file.file_name)
		# subimage file name symbolic link to subimage file name
		# this should be taken care of inside of control point actually
		#sub_link_to_sub = dict()
		# subimage to the image it came from
		sub_to_real = dict()
		sub_to_real[sub_image_0_file.file_name] = image_fn_pair[0]
		sub_to_real[sub_image_1_file.file_name] = image_fn_pair[1]

		# Returns a pto project object
		fast_pair_project = self.control_point_gen.generate_core(sub_image_fn_pair)
		if fast_pair_project is None:
			print 'WARNING: failed to gen control points @ %s' % repr(pair)
			return None
		oto_text = str(fast_pair_project)
		if 0:
			print oto_text
		# are we actually doing anything useful here?
		# The original intention was to make dead sure we had the right file order
		# but I'm pretty sure its consistent and we don't need to parse the comments
		final_pair_project = ajpto2pto_text(oto_text, sub_image_0_file, sub_image_1_file, sub_image_0_x_delta, sub_image_0_y_delta, sub_to_real)
		
		# Filenames become absolute
		#sys.exit(1)
		return final_pair_project
示例#21
0
    def control_points_by_subimage(self,
                                   pair,
                                   image_fn_pair,
                                   subimage_factor=None):
        '''Stitch two images together by cropping to restrict overlap'''

        # subimage_factor: (y, x) overlap percent tuple or none for default
        # pair: pair of row/col or coordinate positions (used to determine relative positions)
        # (0, 0) at upper left
        # image_fn_pair: pair of image file names

        print 'Preparing subimage stitch on %s:%s' % (image_fn_pair[0],
                                                      image_fn_pair[1])
        '''
        Just work on the overlap section, maybe even less
        '''

        images = [
            PImage.from_file(image_file_name)
            for image_file_name in image_fn_pair
        ]
        '''
        image_0 used as reference
        4 basic situations: left, right, up right
        8 extended: 4 basic + corners
        Pairs should be sorted, which simplifies the logic
        '''
        sub_image_0_x_delta = 0
        sub_image_0_y_delta = 0
        sub_image_1_x_end = images[1].width()
        sub_image_1_y_end = images[1].height()

        if subimage_factor:
            y_overlap = subimage_factor[0]
            x_overlap = subimage_factor[1]
        else:
            x_overlap = self.x_overlap
            y_overlap = self.y_overlap

        # image 0 left of image 1?
        if pair.first.col < pair.second.col:
            # Keep image 0 right, image 1 left
            sub_image_0_x_delta = int(images[0].width() * (1.0 - x_overlap))
            sub_image_1_x_end = int(images[1].width() * x_overlap)

        # image 0 above image 1?
        if pair.first.row < pair.second.row:
            # Keep image 0 top, image 1 bottom
            sub_image_0_y_delta = int(images[0].height() * (1.0 - y_overlap))
            sub_image_1_y_end = int(images[1].height() * y_overlap)
        '''
        print 'image 0 x delta: %d, y delta: %d' % (sub_image_0_x_delta, sub_image_0_y_delta)
        Note y starts at top in PIL
        '''
        sub_image_0 = images[0].subimage(sub_image_0_x_delta, None,
                                         sub_image_0_y_delta, None)
        sub_image_1 = images[1].subimage(None, sub_image_1_x_end, None,
                                         sub_image_1_y_end)
        sub_image_0_file = ManagedTempFile.get(None, '.jpg')
        sub_image_1_file = ManagedTempFile.get(None, '.jpg')
        print 'sub image 0: width=%d, height=%d, name=%s' % (sub_image_0.width(
        ), sub_image_0.height(), sub_image_0_file.file_name)
        print 'sub image 1: width=%d, height=%d, name=%s' % (sub_image_1.width(
        ), sub_image_1.height(), sub_image_0_file.file_name)
        #sys.exit(1)
        sub_image_0.image.save(sub_image_0_file.file_name)
        sub_image_1.image.save(sub_image_1_file.file_name)

        sub_image_fn_pair = (sub_image_0_file.file_name,
                             sub_image_1_file.file_name)
        # subimage file name symbolic link to subimage file name
        # this should be taken care of inside of control point actually
        #sub_link_to_sub = dict()
        # subimage to the image it came from
        sub_to_real = dict()
        sub_to_real[sub_image_0_file.file_name] = image_fn_pair[0]
        sub_to_real[sub_image_1_file.file_name] = image_fn_pair[1]

        # Returns a pto project object
        pair_project = self.control_point_gen.generate_core(sub_image_fn_pair)
        if pair_project is None:
            print 'WARNING: failed to gen control points @ %s' % repr(pair)
            return None

        # all we need to do is adjust xy positions
        # afaik above is way overcomplicated
        final_pair_project = pto_unsub(
            pair_project, (sub_image_0_file, sub_image_1_file),
            (sub_image_0_x_delta, sub_image_0_y_delta), sub_to_real)

        # Filenames become absolute
        #sys.exit(1)
        return final_pair_project
示例#22
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
示例#23
0
    def control_points_by_subimage(self, pair, image_fn_pair):
        '''Stitch two images together by cropping to restrict overlap'''

        # subimage_factor: (y, x) overlap percent tuple or none for default
        # pair: pair of row/col or coordinate positions (used to determine relative positions)
        # (0, 0) at upper left
        # image_fn_pair: pair of image file names

        print 'Preparing subimage stitch on %s:%s' % (image_fn_pair[0], image_fn_pair[1])
        '''
        Just work on the overlap section, maybe even less
        '''

        images = [PImage.from_file(image_file_name) for image_file_name in image_fn_pair]

        '''
        image_0 used as reference
        4 basic situations: left, right, up right
        8 extended: 4 basic + corners
        Pairs should be sorted, which simplifies the logic
        '''
        sub_image_0_x_delta = 0
        sub_image_0_y_delta = 0
        sub_image_1_x_end = images[1].width()
        sub_image_1_y_end = images[1].height()

        # Add some backlash margin
        # "more overlap" means will try a slightly larger area
        #margin = 0.05
        x_overlap = self.x_overlap
        y_overlap = self.y_overlap

        # image 0 left of image 1?
        if pair.first.col < pair.second.col:
            # Keep image 0 right, image 1 left
            sub_image_0_x_delta = int(images[0].width() * x_overlap)
            sub_image_1_x_end = int(round(images[1].width() * (1.0 - x_overlap)))

        # image 0 above image 1?
        if pair.first.row < pair.second.row:
            # Keep image 0 top, image 1 bottom
            sub_image_0_y_delta = int(images[0].height() * y_overlap)
            sub_image_1_y_end = int(round(images[1].height() * (1.0 - y_overlap)))

        '''
        print 'image 0 x delta: %d, y delta: %d' % (sub_image_0_x_delta, sub_image_0_y_delta)
        Note y starts at top in PIL
        '''
        sub_image_0 = images[0].subimage(sub_image_0_x_delta, None, sub_image_0_y_delta, None)
        sub_image_1 = images[1].subimage(None, sub_image_1_x_end, None, sub_image_1_y_end)
        sub_image_0_file = ManagedTempFile.get(None, '.jpg')
        sub_image_1_file = ManagedTempFile.get(None, '.jpg')
        print 'sub image 0: width=%d, height=%d, name=%s' % (sub_image_0.width(), sub_image_0.height(), sub_image_0_file.file_name)
        print 'sub image 1: width=%d, height=%d, name=%s' % (sub_image_1.width(), sub_image_1.height(), sub_image_1_file.file_name)
        #sys.exit(1)
        sub_image_0.image.save(sub_image_0_file.file_name)
        sub_image_1.image.save(sub_image_1_file.file_name)

        sub_image_fn_pair = (sub_image_0_file.file_name, sub_image_1_file.file_name)
        # subimage file name symbolic link to subimage file name
        # this should be taken care of inside of control point actually
        #sub_link_to_sub = dict()
        # subimage to the image it came from
        sub_to_real = dict()
        sub_to_real[sub_image_0_file.file_name] = image_fn_pair[0]
        sub_to_real[sub_image_1_file.file_name] = image_fn_pair[1]

        # Returns a pto project object
        pair_project = self.control_point_gen.generate_core(sub_image_fn_pair)
        if pair_project is None:
            print 'WARNING: failed to gen control points @ %s' % repr(pair)
            return None

        # all we need to do is adjust xy positions
        # afaik above is way overcomplicated
        final_pair_project = pto_unsub(pair_project, (sub_image_0_file, sub_image_1_file), (sub_image_0_x_delta, sub_image_0_y_delta), sub_to_real)

        # Filenames become absolute
        #sys.exit(1)
        return final_pair_project
示例#24
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