Skip to content

Commit

Permalink
adapted cornsweet illusion and added mask
Browse files Browse the repository at this point in the history
  • Loading branch information
LynnSchmittwilken committed Jun 14, 2022
1 parent 1387f2c commit 821263d
Showing 1 changed file with 38 additions and 32 deletions.
70 changes: 38 additions & 32 deletions stimuli/illusions/cornsweet.py
@@ -1,62 +1,68 @@
import numpy as np
from stimuli.Stimulus import Stimulus


def cornsweet(size=(10,10), ppd=10, contrast=0.5, ramp_width=2, exponent=2.75,
mean_lum=.5):
#TODO: the parameters aren't analogous to the other stimuli
def cornsweet(size=(10.,10.), ppd=10., vmax=1., vmin=0., vtarget=0.5, ramp_width=2., exponent=2.75):
"""
Create a matrix containing a rectangular Cornsweet edge stimulus.
The 2D luminance profile of the stimulus is defined as
L = L_mean +/- (1 - X / w) ** a * L_mean * C/2 for the ramp and
L = L_mean for the area beyond the ramp.
Left side:
v = vtarget + (1 - X / w) ** a * (vmax-vtarget) for the ramp and v = vtarget beyond.
Right side:
v = vtarget - (1 - X / w) ** a * (vmin-vtarget) for the ramp and v = vtarget beyond.
X is the distance to the edge, w is the width of the ramp, a is a variable
determining the steepness of the ramp, and C is the contrast at the edge,
defined as C = (L_max-L_min) / L_mean.
determining the steepness of the ramp, vtarget is the luminance of the targets and
vmax/vmin are the max/min luminances.
Parameters
----------
size : tuple of 2 numbers
the size of the matrix in degrees of visual angle
ppd : number
the number of pixels in one degree of visual angle
contrast : float, in [0,1]
the contrast at the Cornsweet edge, defined as Michelson contrast
(max_luminance - min_luminance) / (max_luminance + min_luminance)
ramp_width : number (optional)
the width of the luminance ramp in degrees of visual angle.
Default is 3.
exponent : number (optional)
Determines the steepness of the ramp. Default is 2.75. An
exponent value of 0 leads to a stimulus with uniform flanks.
mean_lum : number
The mean luminance of the stimulus, i.e. the value outside of
the ramp area.
size in degrees of visual angle
ppd : float
number of pixels in one degree of visual angle
vmax : float
maximum luminance value
vmin : float
minimum luminance value
vtarget : float
luminance value of targets (=plateaus)
ramp_width : float
width of luminance ramp in degrees of visual angle
exponent : float
determines steepness of ramp (default is 2.75. 1 would be linear)
Returns
-------
Dictionary with img: ndarray (2D) and empty mask
Dictionary with img: ndarray (2D) and mask
References
----------
The formula and default values are taken from Boyaci, H., Fang, F., Murray,
The formula and default values are adapted from Boyaci, H., Fang, F., Murray,
S.O., Kersten, D. (2007). Responses to Lightness Variations in Early Human
Visual Cortex. Current Biology 17, 989-993.
"""

size = [int(size[0]*ppd), int(size[1]*ppd)]
img = np.ones(size) * mean_lum
ramp_width = int(ramp_width*ppd)
img = np.ones(size) * vtarget
mask = np.zeros(size)

# Create ramp profiles individually for left and right side
dist = np.arange(size[1] / 2.)
dist = dist / (ramp_width*ppd)
dist = dist / ramp_width
dist[dist > 1.] = 1.
profile = (1. - dist) ** exponent * mean_lum * contrast
img[:, :int(np.ceil(size[1]/2.))] += profile[::-1]
img[:, size[1] // 2:] -= profile
mask = None
profile1 = (1. - dist) ** exponent * (vmax-vtarget)
profile2 = (1. - dist) ** exponent * (vmin-vtarget)
img[:, :int(size[1]/2.)] += profile1[::-1]
img[:, size[1] // 2:] += profile2

# Generate the target mask
mask[:, 0:int(size[1]/2. - ramp_width - 1)] = 1
mask[:, int(size[1]/2. + ramp_width+1)::] = 2
return {"img": img, "mask": mask}


if __name__ == '__main__':
import matplotlib.pyplot as plt
stim = cornsweet()
plt.imshow(stim, cmap='gray')
plt.imshow(stim['img'], cmap='gray')
plt.show()

0 comments on commit 821263d

Please sign in to comment.