Beispiel #1
0
	def run(self):
		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 'output project file name: %s' % self.output_project_file_name
		print 'output image file name: %s' % self.output_image_file_name
		
		#sys.exit(1)
		'''
		Generate control points
		Generate to all neighbors to start with
		'''
		# 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

		temp_projects = list()

		'''
		for pair in self.coordinate_map.gen_pairs(1, 1):
			print 'pair raw: ' + repr(pair)
			pair_images = self.coordinate_map.get_images_from_pair(pair)
			print 'pair images: ' + repr(pair_images)
		'''
		print
		print '***Pairs: %d***' % len([x for x in self.coordinate_map.gen_pairs(1, 1)])
		print
		for pair in self.coordinate_map.gen_pairs(1, 1):				
			print 'pair raw: ' + repr(pair)
			# Image file names as list
			pair_images = self.coordinate_map.get_images_from_pair(pair)
			print 'pair images: ' + repr(pair_images)


			final_pair_project = self.generate_control_points(pair, pair_images)
			
			if not final_pair_project:
				print 'WARNING: bad project @ %s, %s' % (repr(pair), repr(pair_images))
				continue
			
			if False:
				print
				print 'Final pair project'
				print final_pair_project.get_a_file_name()
				print
				print
				print final_pair_project
				print
				print
				print
				#sys.exit(1)
			
			temp_projects.append(final_pair_project)
			
		print 'pairs done, found %d' % len(temp_projects)
		
		self.project.merge_into(temp_projects)
		self.project.save()
		print 'Sub projects (full image):'
		for project in temp_projects:
			# prefix so I can grep it for debugging
			print '\tSUB: ' + project.file_name
		print
		print
		print 'Master project file: %s' % self.project.file_name		
		print
		print
		print self.project.text
		print
		print

		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()
		
		self.project.optimize_xy_only()
		

		print 'Fixing up i (image attributes) lines...'
		new_project_text = ''
		new_lines = ''
		for line in self.project.text.split('\n'):
			if line == '':
				new_project_text += '\n'				
			elif line[0] == 'i':
				# before replace
				# i Eb1 Eev0 Er1 Ra0.0111006880179048 Rb-0.00838561356067657 Rc0.0198899246752262 Rd0.0135543448850513 Re-0.0435801632702351 Va1 Vb0.366722181378024 Vc-1.14825880321425 Vd0.904996105280657 Vm5 Vx0 Vy0 a0 b0 c0 d0 e0 f0 g0 h2112 n"x00000_y00033.jpg" p0 r0 t0 v70 w2816 y0
				new_line = ''
				for part in line.split():
					if part[0] == 'i':
						new_line += part
						# Force lense type 0 (rectilinear)
						# Otherwise, it gets added as -2 if we are unlucky ("Error on line 6")
						# or 2 (fisheye) if we are lucky (screwed up image)
						new_line += ' f0'
					# Keep image file name
					elif part[0] == 'n':
						new_line += ' ' + part
					# Script is getting angry, try to slim it up
					else:
						print 'Skipping unknown garbage: %s' % part
				new_project_text += new_line + '\n'
			else:
				new_project_text += line + '\n'
		self.project.text = new_project_text
		print
		print
		print self.project.text
		print
		print

		'''
		f0: rectilinear
		f2: equirectangular
		# p f2 w8000 h24 v179  E0 R0 n"TIFF_m c:NONE"
		# p f0 w8000 h24 v179  E0 R0 n"TIFF_m c:NONE"
		'''
		print 'Fixing up single lines'
		new_project_text = ''
		for line in self.project.text.split('\n'):
			if line == '':
				new_project_text += '\n'				
			elif line[0] == 'p':
				new_line = ''
				for part in line.split():
					if part[0] == 'p':
						new_line += 'p'
					elif part[0] == 'f':
						new_line += ' f0'
					else:
						new_line += ' ' + part

				new_project_text += new_line + '\n'
			else:
				new_project_text += line + '\n'
		self.project.text = new_project_text
		print
		print
		print self.project.text
		print
		print
		
		
		print
		print '***PTO project final (%s / %s)***' % (self.project.file_name, self.output_project_file_name)
		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)
		
		# Did we request an actual stitch?
		if self.output_image_file_name:
			print 'Stitching...'
			self.remapper = Remapper(self.project, self.output_image_file_name)
			self.remapper.run()
		else:
			print 'NOT stitching'
Beispiel #2
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