def dkl2rgb(dkl_Nx3, conversionMatrix=None): #Convert from DKL color space (cone-opponent space from Derrington, #Krauskopf & Lennie) to RGB. #Requires a conversion matrix, which will be generated from generic #Sony Trinitron phosphors if not supplied (note that this will not be #an accurate representation of the color space unless you supply a #conversion matrix # #usage: #rgb(Nx3) = dkl2rgb(dkl_Nx3(el,az,radius), conversionMatrix) dkl_3xN = numpy.transpose(dkl_Nx3)#its easier to use in the other orientation! if numpy.size(dkl_3xN)==3: RG, BY, LUM = sph2cart(dkl_3xN[0],dkl_3xN[1],dkl_3xN[2]) else: RG, BY, LUM = sph2cart(dkl_3xN[0,:],dkl_3xN[1,:],dkl_3xN[2,:]) dkl_cartesian = numpy.asarray([LUM, RG, BY]) if conversionMatrix==None: conversionMatrix = numpy.asarray([ \ #LUMIN %L-M %L+M-S (note that dkl has to be in cartesian coords first!) [1.0000, 1.0000, -0.1462], #R [1.0000, -0.3900, 0.2094], #G [1.0000, 0.0180, -1.0000]]) #B #rgb = numpy.dot(dkl_cartesian,numpy.transpose(conversionMatrix)) rgb = numpy.dot(conversionMatrix, dkl_cartesian) return numpy.transpose(rgb)#return in the shape we received it
def dkl2rgb(dkl, conversionMatrix=None): """Convert from DKL color space (cone-opponent space from Derrington, Krauskopf & Lennie) to RGB. Requires a conversion matrix, which will be generated from generic Sony Trinitron phosphors if not supplied (note that this will not be an accurate representation of the color space unless you supply a conversion matrix). usage:: rgb(Nx3) = dkl2rgb(dkl_Nx3(el,az,radius), conversionMatrix) """ if conversionMatrix==None: conversionMatrix = numpy.asarray([ \ #LUMIN %L-M %L+M-S (note that dkl has to be in cartesian coords first!) [1.0000, 1.0000, -0.1462],#R [1.0000, -0.3900, 0.2094],#G [1.0000, 0.0180, -1.0000]])#B logging.warning('This monitor has not been color-calibrated. Using default DKL conversion matrix.') if len(dkl.shape)==3: dkl_NxNx3 = dkl """convert a 2D (image) of Spherical DKL colours to RGB space""" origShape = dkl_NxNx3.shape#remember for later NxN = origShape[0]*origShape[1]#find nPixels dkl = np.reshape(dkl_NxNx3,[NxN,3])#make Nx3 rgb = dkl2rgb(dkl,conversionMatrix)#convert return np.reshape(rgb,origShape)#reshape and return if len(dkl.shape)==2: dkl_Nx3=dkl dkl_3xN = numpy.transpose(dkl_Nx3)#its easier to use in the other orientation! if numpy.size(dkl_3xN)==3: RG, BY, LUM = misc.sph2cart(dkl_3xN[0],dkl_3xN[1],dkl_3xN[2]) else: RG, BY, LUM = misc.sph2cart(dkl_3xN[0,:],dkl_3xN[1,:],dkl_3xN[2,:]) dkl_cartesian = numpy.asarray([LUM, RG, BY]) rgb = numpy.dot(conversionMatrix, dkl_cartesian) return numpy.transpose(rgb)#return in the shape we received it
def dkl2rgb2d(dkl, conversionMatrix=None): if conversionMatrix==None: conversionMatrix = numpy.asarray([ \ #LUMIN %L-M %L+M-S (note that dkl has to be in cartesian coords first!) [1.0000, 1.0000, -0.1462],#R [1.0000, -0.3900, 0.2094],#G [1.0000, 0.0180, -1.0000]])#B logging.warning('This monitor has not been color-calibrated. Using default DKL conversion matrix.') if len(dkl.shape)==3: origShape = dkl.shape elevation = dkl[:,:,0] azimuth = dkl[:,:,1] radius = dkl[:,:,2] dkl = numpy.asarray([elevation.reshape([-1]), azimuth.reshape([-1]), radius.reshape([-1])]) LM, S, Lum = misc.sph2cart(elevation, azimuth, radius) rgb = misc.dklCart2rgb(LUM = Lum, LM = LM, S = S, conversionMatrix = conversionMatrix) rgb.reshape(origShape)
from psychopy import visual, misc import numpy nDots = 1000 angVelocity = 1 # deg rotation per frame win = visual.Window((600, 600)) myStim = visual.ElementArrayStim(win, elementTex=None, elementMask="circle", texRes=64, nElements=nDots, sizes=0.01) # starting spherical coordinates for our dots azims = numpy.random.random(nDots) * 360 elevs = numpy.random.random(nDots) * 180 - 90 radii = 0.5 for frameN in range(1000): azims += angVelocity # add angVel to the azimuth of the dots x, y, z = misc.sph2cart(elevs, azims, radii) xy = numpy.transpose(numpy.vstack([x, z])) myStim.setXYs(xy) myStim.draw() win.flip()
win = visual.Window((600, 600)) #Ideally, we should subclass DotStim and override the _updateDots method to #what we want with the spherical rotation. But we'll just set speed and dotLife #so that they won't update (?) myStim = visual.DotStim(win, nDots=nDots, speed=0, fieldSize=[500, 500], dotLife=-1) #this is a hack #starting spherical coordinates for our dots azims = numpy.random.random(nDots) * 360 elevs = numpy.random.random(nDots) * 180 - 90 radii = 0.5 win.setRecordFrameIntervals() for frameN in range(1000): azims += angVelocity #add angVel to the azimuth of the dots x, y, z = misc.sph2cart(elevs, azims, radii) myStim._dotsXY[:, 0] = x myStim._dotsXY[:, 1] = z #?! myStim._calcDotsXYRendered() myStim.draw() win.flip() print win.fps()