Пример #1
0
	def __init__(self) :

		def addSpin(name, minimum, default, maximum, slot) :
			topLayout.addWidget(QtGui.QLabel(name+":"))
			spin = QtGui.QSpinBox()
			spin.setMinimum(minimum)
			spin.setMaximum(maximum)
			spin.setValue(default)
			spin.valueChanged.connect(slot)
			topLayout.addWidget(spin)
			return spin

		def addButton(layout, name, slot) :
			button = QtGui.QPushButton(name)
			button.clicked.connect(slot)
			layout.addWidget(button)


		QtGui.QWidget.__init__(self)
		self.shProjections = np.array([[[[]]]])
		self._editing = False
		self.setLayout(QtGui.QHBoxLayout())
		leftPanel = QtGui.QVBoxLayout()
		self.layout().addLayout(leftPanel)
		self._shknobs = SphericalHarmonicsKnobs()
		topLayout = QtGui.QHBoxLayout()
		self._parallelsSpin = addSpin("Parallels", 4, 50, 400, self.updateResolution)
		topLayout.addStretch(1)
		self._meridiansSpin = addSpin("Meridians", 4, 80, 400, self.updateResolution)

		addButton(topLayout, "Reset", self._shknobs.reset)
		addButton(topLayout, "Negate", self._shknobs.negate)
		addButton(topLayout, "Resynth", self.resynthesize)
		presetLayout1 = QtGui.QHBoxLayout()
		presetLayout2 = QtGui.QHBoxLayout()
		addButton(presetLayout1, "Front", self.sample_frontPoint)
		addButton(presetLayout1, "Back", self.sample_backPoint)
		addButton(presetLayout1, "Top", self.sample_topPoint)
		addButton(presetLayout1, "Down", self.sample_downPoint)
		addButton(presetLayout1, "Left", self.sample_leftPoint)
		addButton(presetLayout1, "Right", self.sample_rightPoint)
		addButton(presetLayout2, "Omni", self.sample_omni)
		addButton(presetLayout2, "Equator", self.sample_equator)
		addButton(presetLayout2, "Greenwitch", self.sample_greenwitch)
		addButton(presetLayout2, "Map", self.sample_map)

		leftPanel.addLayout(topLayout)
		leftPanel.addLayout(presetLayout1)
		leftPanel.addLayout(presetLayout2)
		leftPanel.addWidget(self._shknobs)


		rightPanel = QtGui.QVBoxLayout()
		self.layout().addLayout(rightPanel)

		self.blobView = BlobView()
		rightPanel.addWidget(self.blobView)

		self.synthetizedFunction = ColorField(width, height)
		rightPanel.addWidget(self.synthetizedFunction)

		self.targetFunction = ColorField(width, height)
		rightPanel.addWidget(self.targetFunction)

		rightPanel.setStretch(0,3)
		rightPanel.setStretch(1,1)
		rightPanel.setStretch(2,1)
		self.layout().setStretch(0,1)
		self.layout().setStretch(1,1)
		self._shknobs.functionChanged.connect(self.reloadData)
Пример #2
0
class SphereLab(QtGui.QWidget) :

	def __init__(self) :

		def addSpin(name, minimum, default, maximum, slot) :
			topLayout.addWidget(QtGui.QLabel(name+":"))
			spin = QtGui.QSpinBox()
			spin.setMinimum(minimum)
			spin.setMaximum(maximum)
			spin.setValue(default)
			spin.valueChanged.connect(slot)
			topLayout.addWidget(spin)
			return spin

		def addButton(layout, name, slot) :
			button = QtGui.QPushButton(name)
			button.clicked.connect(slot)
			layout.addWidget(button)


		QtGui.QWidget.__init__(self)
		self.shProjections = np.array([[[[]]]])
		self._editing = False
		self.setLayout(QtGui.QHBoxLayout())
		leftPanel = QtGui.QVBoxLayout()
		self.layout().addLayout(leftPanel)
		self._shknobs = SphericalHarmonicsKnobs()
		topLayout = QtGui.QHBoxLayout()
		self._parallelsSpin = addSpin("Parallels", 4, 50, 400, self.updateResolution)
		topLayout.addStretch(1)
		self._meridiansSpin = addSpin("Meridians", 4, 80, 400, self.updateResolution)

		addButton(topLayout, "Reset", self._shknobs.reset)
		addButton(topLayout, "Negate", self._shknobs.negate)
		addButton(topLayout, "Resynth", self.resynthesize)
		presetLayout1 = QtGui.QHBoxLayout()
		presetLayout2 = QtGui.QHBoxLayout()
		addButton(presetLayout1, "Front", self.sample_frontPoint)
		addButton(presetLayout1, "Back", self.sample_backPoint)
		addButton(presetLayout1, "Top", self.sample_topPoint)
		addButton(presetLayout1, "Down", self.sample_downPoint)
		addButton(presetLayout1, "Left", self.sample_leftPoint)
		addButton(presetLayout1, "Right", self.sample_rightPoint)
		addButton(presetLayout2, "Omni", self.sample_omni)
		addButton(presetLayout2, "Equator", self.sample_equator)
		addButton(presetLayout2, "Greenwitch", self.sample_greenwitch)
		addButton(presetLayout2, "Map", self.sample_map)

		leftPanel.addLayout(topLayout)
		leftPanel.addLayout(presetLayout1)
		leftPanel.addLayout(presetLayout2)
		leftPanel.addWidget(self._shknobs)


		rightPanel = QtGui.QVBoxLayout()
		self.layout().addLayout(rightPanel)

		self.blobView = BlobView()
		rightPanel.addWidget(self.blobView)

		self.synthetizedFunction = ColorField(width, height)
		rightPanel.addWidget(self.synthetizedFunction)

		self.targetFunction = ColorField(width, height)
		rightPanel.addWidget(self.targetFunction)

		rightPanel.setStretch(0,3)
		rightPanel.setStretch(1,1)
		rightPanel.setStretch(2,1)
		self.layout().setStretch(0,1)
		self.layout().setStretch(1,1)
		self._shknobs.functionChanged.connect(self.reloadData)

	def updateResolution(self) :
		self.reloadData()

	def sphericalHarmonicsMatrix(self) :
		return self._shknobs.sphericalHarmonicsMatrix()

	def setSphericalHarmonicsMatrix(self, array) :
		self._shknobs.setSphericalHarmonicsMatrix(array)

	def loadFromSamples(self, image) :
		h,w = image.shape
		print "Display data..."
		self.targetFunction.format(w, h, ColorField.signedScale)
		self.targetFunction.data()[:] = 127 + image*127./(max(1.,abs(image.max())))
		self.targetFunction.reload()

		print "Project to SH..."
		imageInSH = projectImageToSH(image)
		imageInSH *= orthonormalization

		print "Upload SH components to knobs..."
		self.setSphericalHarmonicsMatrix(imageInSH)
		print "Reloading..."
		self.reloadData()

	def reloadData(self) :
		nelevations = self._parallelsSpin.value()
		nazimuths = self._meridiansSpin.value()
		if self.shProjections.shape[:2] != (nelevations, nazimuths) :
			print "Reshaping %ix%x..."%(nelevations, nazimuths)
			self.elevations, self.azimuths, self.shProjections = shGrid(nelevations, nazimuths)
			self.shProjections *= orthonormalization
			print "Reshape outputs..."
			self.sphericalPoints = np.array([
				[self.elevations[ei], self.azimuths[ai], 0 ]
				for ei in xrange(nelevations)
				for ai in xrange(nazimuths)
				])
			self.indexes = np.array(
				[[
					[i+nazimuths*j,i+nazimuths*(j+1)]
					for i in xrange(nazimuths) ]
					for j in xrange(nelevations-1) ]
				).flatten()

		# taking coeficients from the knobs
		shMatrix = self.sphericalHarmonicsMatrix()

		self.data = self.shProjections.reshape(nazimuths*nelevations, shMatrix.size).dot(
			shMatrix.reshape(shMatrix.size )
			).reshape(self.shProjections.shape[:2])

		self.sphericalPoints[:,2] = (5*self.data).reshape(nelevations*nazimuths)

		self.blobView.setEadPoints(self.sphericalPoints)
		xyzs = np.array([ead2xyz(e,a,abs(d)) for e,a,d in self.sphericalPoints])
		self.blobView.scene()._vertices = xyzs
		self.blobView.scene()._normals = xyzs
		self.blobView.scene()._meshColors = np.array([
			[1.,.0,.0, .6] if d<0 else [0.,0.,1., .9]
			for e,a,d in self.sphericalPoints])
		self.blobView.scene()._indexes = self.indexes
		self.blobView.update()

		maxValue = abs(self.data).max()
		if maxValue > 1 : self.data /= maxValue
		self.synthetizedFunction.format(nazimuths, nelevations, ColorField.signedScale)
		self.synthetizedFunction.data()[:] = self.data/(2/255.)+127
		self.synthetizedFunction.reload()


	# Sphere sampling resolution for the synthetic data sets
	sampleResolution = 36*4, 18*4

	def resynthesize(self) :
		w,h = self.sampleResolution
		image = self.data
		self.loadFromSamples(image)

	def sample_map(self) :
		w,h = self.sampleResolution
		image = imageData("16bit_world_height.png", w, h)
		max = float(image.max())
		min = float(image.min())
		image = (image-min)/(max-min)
		self.loadFromSamples(image)

	def sample_omni(self) :
		w,h = self.sampleResolution
		image = np.ones((h,w))
		self.loadFromSamples(image)

	def sample_frontPoint(self) :
		w,h = self.sampleResolution
		image = np.zeros((h,w))
		image[h/2,w/2] = +1
		self.loadFromSamples(image)

	def sample_frontNegativePoint(self) :
		w,h = self.sampleResolution
		image = np.zeros((h,w))
		image[h/2,w/2] = -1
		self.loadFromSamples(image)

	def sample_backNegativePoint(self) :
		w,h = self.sampleResolution
		image = np.zeros((h,w))
		image[h/2,0] = -1
		self.loadFromSamples(image)

	def sample_backPoint(self) :
		w,h = self.sampleResolution
		image = np.zeros((h,w))
		image[h/2,0] = +1
		self.loadFromSamples(image)

	def sample_rightPoint(self) :
		w,h = self.sampleResolution
		image = np.zeros((h,w))
		image[h/2,w/4] = +1
		self.loadFromSamples(image)

	def sample_leftPoint(self) :
		w,h = self.sampleResolution
		image = np.zeros((h,w))
		image[h/2,3*w/4] = +1
		self.loadFromSamples(image)

	def sample_topPoint(self) :
		w,h = self.sampleResolution
		image = np.zeros((h,w))
		image[1,:] = +1 # north pole
		self.loadFromSamples(image)

	def sample_downPoint(self) :
		w,h = self.sampleResolution
		image = np.zeros((h,w))
		image[-2,:] = +1 # south pole
		self.loadFromSamples(image)

	def sample_equator(self) :
		w,h = self.sampleResolution
		image = np.zeros((h,w))
		image[h/2,:] = +1 # equator
		self.loadFromSamples(image)

	def sample_greenwitch(self) :
		w,h = self.sampleResolution
		image = np.zeros((h,w))
		image[:,w/2] = +1 # Grenwitch
		self.loadFromSamples(image)