hegde cc07ΒΆ

Visual patterns from Hegde and Van Essen (2007)

Visual test patterns implemented by Jiri Machalek and James A. Bednar from:

J. Hegde and D. Van Essen, A comparative study of shape representation in macaque visual areas V2 and V4, Cerebral Cortex (2007) 17:1100-1116. http://dx.doi.org/10.1093/cercor/bhl020

Includes various grating and contour stimuli subclasses. Stimuli from one subclass have common shape characteristics but vary in orientation, size and/or spatial frequency. Patterns have not been matched bit for bit to the originals, but should be reasonably equivalent.

In [1]:
import imagen as ig
import holoviews as hv
import numpy as np
%load_ext holoviews.ipython
In [2]:
%output dpi=150 size=100
%opts Layout [sublabel_format="" vertical_spacing=0.05 horizontal_spacing=0.05] Image (cmap='gray') [show_xaxis=None show_yaxis=None show_frame=True]
from imagen import *
variants = 4 # Number of variants for each subclass
In [3]:
orientations = (i*np.pi/variants for i in range(variants)) 
frequencies = [2.0, 3.1, 4.2]
sin = {(o, f): SineGrating(phase=np.pi/2, frequency=f,orientation=o)
       for o in orientations for f in frequencies}
sinusoidal = hv.NdLayout({k:v[:] for k,v in sin.items()}, key_dimensions=['Orientation', 'Frequency']) 
sinusoidal.cols(6)
Out[3]:
In [4]:
size_thickness = zip([0.18, 0.27, 0.36], [0.015, 0.03, 0.04])
orientations = (i*np.pi/(2*variants) for i in range(variants))
hyp = {(s, t, o): HyperbolicGrating(size=s, thickness=t, orientation=o)
       for o in orientations for (s, t) in size_thickness}
hyperbolic = hv.NdLayout({k:v[:] for k,v in hyp.items()}, key_dimensions=['Size', 'Thickness', 'Orientation'])
hyperbolic.cols(6)
Out[4]:
In [5]:
pol1 = [ConcentricRings(size=0.35/(1+j*0.5),thickness=0.05/(1+j*0.35),smoothing=0.05/(1+j*0.15)) for j in range(variants)]

pol2 = [SpiralGrating(parts=(j+1)*2,turning=0.19+0.30*j,smoothing=0.110+0.015*j) for j in range(variants)]
pol3 = [SpiralGrating(parts=(j+1)*2,turning=0.09+0.13*j,smoothing=0.050+0.006*j) for j in range(variants)]
pol4 = [SpiralGrating(parts=(j+1)*2,turning=0.06+0.09*j,smoothing=0.035+0.006*j) for j in range(variants)]
pol5 = [SpiralGrating(parts=(j+1)*2,turning=0.05+0.07*j,smoothing=0.030+0.003*j) for j in range(variants)]

pol6 = [RadialGrating(parts=(j+1)*2) for j in range(variants)]

polar = pol1 + pol2 + pol3 + pol4 + pol5 + pol6

np.sum([p[:] for p in polar]).cols(8)
Out[5]:
In [6]:
bar1 = [Rectangle(orientation=j*np.pi/4,smoothing=0.015,aspect_ratio=0.1,size=0.5)
        for j in range(variants)]
bar2 = [Rectangle(orientation=j*np.pi/4,smoothing=0.015,aspect_ratio=0.2,size=0.25)
        for j in range(variants)]
bar = bar1 + bar2
np.sum([p[:] for p in bar]).cols(8)
Out[6]:
In [7]:
star1 = [Asterisk(parts=3, size=0.50, orientation=j*np.pi/2) for j in range(variants)]
star2 = [Asterisk(parts=3, size=0.25, orientation=j*np.pi/2) for j in range(variants)]
tristar = star1 + star2
np.sum([p[:] for p in tristar]).cols(8)
Out[7]:
In [8]:
star3 = [Asterisk(parts=4, size=0.50, orientation=j*np.pi/8) for j in range(variants)]
star4 = [Asterisk(parts=4, size=0.25, orientation=j*np.pi/8) for j in range(variants)]
cross = star3 + star4
np.sum([p[:] for p in cross]).cols(8)
Out[8]:
In [9]:
star5 = [Asterisk(parts=5, size=0.50, orientation=j*np.pi) for j in range(2)]
star5+= [Asterisk(parts=6, size=0.50)]
star5+= [Ring(smoothing=0.015,thickness=0.05,size=0.5)]
star6 = [Asterisk(parts=5, size=0.25, orientation=j*np.pi) for j in range(2)]
star6+= [Asterisk(parts=6, size=0.25)]
star6+= [Ring(smoothing=0.015,thickness=0.05,size=0.25)]
star = star5 + star6
np.sum([p[:] for p in star]).cols(8)
Out[9]:
In [10]:
ang1 = [Angle(size=0.50,angle=np.pi/8, orientation=j*2*np.pi/variants) for j in range(variants)]
ang2 = [Angle(size=0.25,angle=np.pi/8, orientation=j*2*np.pi/variants) for j in range(variants)]
acute = ang1 + ang2
np.sum([p[:] for p in acute]).cols(8)
Out[10]:
In [11]:
ang3 = [Angle(size=0.50,angle=np.pi/4, orientation=j*2*np.pi/variants) for j in range(variants)]
ang4 = [Angle(size=0.25,angle=np.pi/4, orientation=j*2*np.pi/variants) for j in range(variants)]
right = ang3 + ang4
np.sum([p[:] for p in right]).cols(8)
Out[11]:
In [12]:
ang5 = [Angle(size=0.50,angle=np.pi/3, orientation=j*2*np.pi/variants) for j in range(variants)]
ang6 = [Angle(size=0.25,angle=np.pi/3, orientation=j*2*np.pi/variants) for j in range(variants)]
obtuse = ang5 + ang6
np.sum([p[:] for p in obtuse]).cols(8)
Out[12]:
In [13]:
arc1 = [ArcCentered(arc_length=np.pi/2,smoothing=0.015,thickness=0.05,size=0.50, orientation=i*2*np.pi/variants)
        for i in range(variants)]
arc2 = [ArcCentered(arc_length=np.pi/2,smoothing=0.015,thickness=0.05,size=0.25,orientation=i*2*np.pi/variants)
        for i in range(variants)]
quarter = arc1 + arc2
np.sum([p[:] for p in quarter]).cols(8)
Out[13]:
In [14]:
arc3 = [ArcCentered(arc_length=np.pi,smoothing=0.015,thickness=0.05,size=0.5,orientation=i*2*np.pi/variants)
        for i in range(variants)]
arc4 = [ArcCentered(arc_length=np.pi,smoothing=0.015,thickness=0.05,size=0.25,orientation=i*2*np.pi/variants)
        for i in range(variants)]
semi = arc3 + arc4
np.sum([p[:] for p in semi]).cols(8)
Out[14]:
In [15]:
arc5 = [ArcCentered(arc_length=3*np.pi/2,smoothing=0.015,thickness=0.05,size=0.50,orientation=i*2*np.pi/variants)
        for i in range(variants)]
arc6 = [ArcCentered(arc_length=3*np.pi/2,smoothing=0.015,thickness=0.05,size=0.25,orientation=i*2*np.pi/variants)
        for i in range(variants)]
threeqtrs = arc5 + arc6
np.sum([p[:] for p in threeqtrs]).cols(8)
Out[15]:
In [16]:
concentric_like = pol1 + pol2[1:] + pol3[2:] + pol4[2:] + pol5[3:]
radial_like = pol2[:1] + pol3[:2] + pol4[:2] + pol5[:3] + pol6

grating_stimuli_subclasses = [list(sin.values()), list(hyp.values()), concentric_like, radial_like]
grating_stimuli_subclasses_labels = ['sinusoidal''hyperbolic','concentric-like','radial-like']

contour_stimuli_subclasses = [bar,tristar,cross,star,acute,right,obtuse,quarter,semi,threeqtrs]
contour_stimuli_subclasses_labels = ['bar','tri-star','cross','star/circle','acute angle',
                                     'right angle','obtuse angle','quarter arc','semi-circle','3/4 arc']

all_stimuli_subclasses = grating_stimuli_subclasses + contour_stimuli_subclasses
all_stimuli_subclasses_labels = grating_stimuli_subclasses_labels + contour_stimuli_subclasses_labels

Can view all patterns at once if you wish:

np.sum([p[:] for c in all_stimuli_subclasses for p in c]).cols(8)

Download this notebook from GitHub (right-click to download).

ImaGen

Table Of Contents

This Page