Reputation: 141
for a binocular rivalry experiment using color blobs (created with GratingStim using a gaussian mask), I need to draw a fake rivalry stimulus. That is, I need a round color blob that has one color for example on the top (25% of the color blob) and another color below (75% of the color blob). Additionally, I would like the twocolored fake rivalry blob to have a gaussian mask as my real rivalry stimuli do. Also it would be good to have a fuzzy color transition in the fake rivalry stimulus. I hope it's clear what I mean.
One solution I thought of was to draw two rectangles with blurred edges and then lay a gaussian alpha mask over them. In order to get the color proportions right, I would only have to move the two rectangles behind the mask. Is there a way to put a alpha-maks over an entire window?
Another solution would be to use ShapeStim as is suggested in this post explaining how to draw a semi circle : https://groups.google.com/forum/#!msg/psychopy-users/L9TYIrf9eJk/m0zIj0N23bMJ I would have to play around with the vertices, but I think it should work. The only thing that worries me here is that ShapeStim has no mask attribute to blur the edges.
Can you think of a way to do it? Thank you very much!
Lilla
System specifications: Psychopy v1.83.01 running on iOS 10.11.1
Upvotes: 1
Views: 211
Reputation: 141
second update, even nicer result:
# Set up stimuli
from psychopy import visual, event
import numpy as np
from scipy.stats import gaussian_kde
win = visual.Window([500,500])
win2 = visual.Window([500,500])
#magic numpy stuff /scipy stuff, adapted from http://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.stats.gaussian_kde.html
mean1 = [0, 0]
#the smaller the value, the bigger the visible blob
cov1 = [[0.03, 0], [0, 0.09]] #in this mask, it should be 50/50
cov2 = [[0.05,0],[0,0.4]] #in this mask, the color with this mask is the smaller one
m1, m2 = np.random.multivariate_normal(mean1, cov1, 2000).T# * np.random.multivariate_normal(mean2, cov2, 5000).T
for i in xrange(len(m2)):
if m2[i] >= 0:
m2[i] = m2[i]* 0.5#np.random.multivariate_normal(mean2, cov2,1).T[0]
values = np.vstack([m1, m2])
kernel = gaussian_kde(values)
xmin = m1.min()
xmax = m1.max()
ymin = m2.min()
ymax = m2.max()
X, Y = np.mgrid[xmin:xmax:128j, ymin:ymax:128j]
positions = np.vstack([X.ravel(), Y.ravel()])
values = np.vstack([m1, m2])
kernel = gaussian_kde(values)
Z = np.reshape(kernel(positions).T, X.shape) #this array will be the mask
Z = Z - 1
for i in xrange(128):
for j in xrange(128): #it will neverbe smaller than -1
if Z[i][j] > 1:
Z[i][j] = 1
# Draw them on top of each other
perc75 = visual.GratingStim(win, sf=0, size=250, color='green',pos=(0.0, 0.0), mask =Z)
perc25 = visual.GratingStim(win, sf=0, size=250, color='red',pos=(0.0, 0.0), mask = 'raisedCos', maskParams={'fringeWidth':0.8})
perc25.setAutoDraw(True)
perc75.setAutoDraw(True)
win.flip()
event.waitKeys()
Upvotes: 1
Reputation: 141
Update on my question: the following exemplar code solves the problem:
# -*- coding: utf-8 -*-
# adapted from https://groups.google.com/forum/#!msg/psychopy-users/69p-aAWiDGI/e4iT43cHDeEJ
from psychopy import visual, event
win = visual.Window([500,500])
#stimuli
perc25 = visual.GratingStim(win, sf=0, size=1, color='RED',pos=(0.0, 0.0), mask = 'raisedCos', maskParams={'fringeWidth':0.8})
perc75 = visual.GratingStim(win, sf=0, size=0.8, color='green',pos=(0.0, -0.15), mask = 'raisedCos', maskParams={'fringeWidth':0.6})
#prepare for the screenshot
Stimlist = [perc25, perc75]
delta = .5# larger is bigger, slower
dx = delta * win.size[1]/win.size[0]
dy = delta
rect = (-dx, +dy, +dx, -dy)#size of the screenshot
screenshot = visual.BufferImageStim(win, stim=Stimlist,rect = rect, mask = 'gauss', pos=(0.0, 0.0)) # mask can also be 'raisedCos' with a smaller delta, for exmple .2
screenshot.draw()
win.flip()
event.waitKeys()
Upvotes: 0
Reputation: 5683
Would this work? You can then locate the blobs where you want, e.g. for one eye. No need to do whole-window stuff.
# Set up stimuli
from psychopy import visual, event
win = visual.Window([500,500])
blob_large = visual.GratingStim(win, sf=0, mask='gauss', size=1, color='red')
blob_small = visual.GratingStim(win, sf=0, mask='gauss', size=0.5, color='green', maskParams={'sd':6})
# Draw them on top of each other
blob_large.draw()
blob_small.draw()
win.flip()
# Wait for keyboard before quitting.
event.waitKeys()
Upvotes: 0