I would actually like to define the colour of the abovementioned visual. functions. But currently, the ‘color’ setting for these functions can only be applied to one of the rings/gratings and the color of the other, the direct opposite. Is there a way that I can specifically control the colour of the second ring/grating?
(ie. If I were to set the color as red, the default opponent color is blue. I would like to make it say, red and green instead.)
Edit: I’ve found the solution for a non-radial stimulus at Creating a grating with a only one color. However, the psychopy.filters.makeGrating function hasn’t got a ‘tex’ setting where I could change it away from the default sin texture. Secondly, I’m still not quite sure how to do the same to a circular radial stimulus?
Thanks @djmannion . That worked for a squarish grating, which is one thing that I needed. However for the radial stimulus, is filter.makeGrating able to come out with something like this instead?
I was trying to wrap my head around the massive number of lists within ‘blue_grating’ here and can’t quite figure out how this actually makes the grating blue. If I want to make this red, green or even maroon, what variable here do I have to manipulate to get it to change to the respective colours?
The blue_grating variable is a 256x256x3 array, where the last dimension indexes the red, green, and blue colour channels. The line blue_grating[…, -1] = grating is setting the blue channel (the -1 indexes the last channel) to vary its intensity according to the grating.
To make it be different colours, the RGB space might not be easiest. Instead, you can define your stimulus in HSV space (with the grating in the V channel) and then convert it into RGB. That way, you only need to change the H channel to vary the hue (though other aspects change with hue also).
For example:
import numpy as np
import psychopy.visual
import psychopy.event
import psychopy.colors
win = psychopy.visual.Window()
grating_res = 256
grating = psychopy.visual.filters.makeGrating(res=grating_res, cycles=5.0)
hsv_tex = np.ones((grating_res, grating_res, 3))
# set the value channel to the grating
hsv_tex[..., 2] = (grating + 1) / 2.0
stim = psychopy.visual.RadialStim(
win=win,
units="pix",
size=(grating_res, grating_res)
)
# loop over hues
for angle in range(0, 360, 10):
hsv_tex[..., 0] = angle
stim.tex = psychopy.colors.hsv2rgb(hsv_tex)
stim.draw()
win.flip()
psychopy.event.waitKeys()
win.close()
I see, thanks for all these. It seems though, that the colour is dependent on having a black background. Does it have to be that way? (Ie. I can’t have a non-black colour pair like yellow and brown?)
No, it doesn’t have to be that way. You can make the value channel not go all the way to 0 to get yellow-brown. I’d suggest experimenting with the different ways of manipulating hsv_tex - you can make it look pretty much however you want.
blue_grating1 = np.ones((grating_res, grating_res, 3))* -1.0 # initialise a ‘black’ texture
blue_grating1[…, 0] = grating1 # replace the red channel with the grating
Conversely, could I overlay two gabor patches and make one of the colors transparent, but this seems trickier. As soon as I make one color transparent, for example setting the opacity to 0, the entire patch unsurprisingly disappears. (reference: https://groups.google.com/g/psychopy-users/c/IlhiS-7XMNg).
I have successfully recreated a grating stimulus with the colors you use, but I don’t understand how to manipulate them to what I need (red-green and blue-yellow).
Ultimately, I hope to keep red (or yellow) a constant luminance and ask the participant to modulate green (or blue) luminance to achieve perceptual isoluminance, but I think I can do this once I know how to manipulate colors using the numpy array.