{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Visual patterns from Hegde and Van Essen (2007)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Visual test patterns implemented by Jiri Machalek and James A. Bednar from:\n", "\n", "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\n", "\n", "\n", "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." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import imagen as ig\n", "import numpy as np\n", "import holoviews as hv\n", "hv.notebook_extension(\"matplotlib\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%output dpi=150 size=100\n", "%opts Layout [sublabel_format=\"\" vertical_spacing=0.05 horizontal_spacing=0.05] Image (cmap='gray') [show_xaxis=None show_yaxis=None show_frame=True]\n", "from imagen import *\n", "variants = 4 # Number of variants for each subclass" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "orientations = (i*np.pi/variants for i in range(variants)) \n", "frequencies = [2.0, 3.1, 4.2]\n", "sin = {(o, f): SineGrating(phase=np.pi/2, frequency=f,orientation=o)\n", " for o in orientations for f in frequencies}\n", "sinusoidal = hv.NdLayout({k:v[:] for k,v in sin.items()}, key_dimensions=['Orientation', 'Frequency']) \n", "sinusoidal.cols(6)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "size_thickness = zip([0.18, 0.27, 0.36], [0.015, 0.03, 0.04])\n", "orientations = (i*np.pi/(2*variants) for i in range(variants))\n", "hyp = {(s, t, o): HyperbolicGrating(size=s, thickness=t, orientation=o)\n", " for o in orientations for (s, t) in size_thickness}\n", "hyperbolic = hv.NdLayout({k:v[:] for k,v in hyp.items()}, key_dimensions=['Size', 'Thickness', 'Orientation'])\n", "hyperbolic.cols(6)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "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)]\n", "\n", "pol2 = [SpiralGrating(parts=(j+1)*2,turning=0.19+0.30*j,smoothing=0.110+0.015*j) for j in range(variants)]\n", "pol3 = [SpiralGrating(parts=(j+1)*2,turning=0.09+0.13*j,smoothing=0.050+0.006*j) for j in range(variants)]\n", "pol4 = [SpiralGrating(parts=(j+1)*2,turning=0.06+0.09*j,smoothing=0.035+0.006*j) for j in range(variants)]\n", "pol5 = [SpiralGrating(parts=(j+1)*2,turning=0.05+0.07*j,smoothing=0.030+0.003*j) for j in range(variants)]\n", "\n", "pol6 = [RadialGrating(parts=(j+1)*2) for j in range(variants)]\n", "\n", "polar = pol1 + pol2 + pol3 + pol4 + pol5 + pol6\n", "\n", "hv.Layout([p[:] for p in polar]).cols(8)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bar1 = [Rectangle(orientation=j*np.pi/4,smoothing=0.015,aspect_ratio=0.1,size=0.5)\n", " for j in range(variants)]\n", "bar2 = [Rectangle(orientation=j*np.pi/4,smoothing=0.015,aspect_ratio=0.2,size=0.25)\n", " for j in range(variants)]\n", "bar = bar1 + bar2\n", "hv.Layout([p[:] for p in bar]).cols(8)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "star1 = [Asterisk(parts=3, size=0.50, orientation=j*np.pi/2) for j in range(variants)]\n", "star2 = [Asterisk(parts=3, size=0.25, orientation=j*np.pi/2) for j in range(variants)]\n", "tristar = star1 + star2\n", "hv.Layout([p[:] for p in tristar]).cols(8)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "star3 = [Asterisk(parts=4, size=0.50, orientation=j*np.pi/8) for j in range(variants)]\n", "star4 = [Asterisk(parts=4, size=0.25, orientation=j*np.pi/8) for j in range(variants)]\n", "cross = star3 + star4\n", "hv.Layout([p[:] for p in cross]).cols(8)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "star5 = [Asterisk(parts=5, size=0.50, orientation=j*np.pi) for j in range(2)]\n", "star5+= [Asterisk(parts=6, size=0.50)]\n", "star5+= [Ring(smoothing=0.015,thickness=0.05,size=0.5)]\n", "star6 = [Asterisk(parts=5, size=0.25, orientation=j*np.pi) for j in range(2)]\n", "star6+= [Asterisk(parts=6, size=0.25)]\n", "star6+= [Ring(smoothing=0.015,thickness=0.05,size=0.25)]\n", "star = star5 + star6\n", "hv.Layout([p[:] for p in star]).cols(8)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ang1 = [Angle(size=0.50,angle=np.pi/8, orientation=j*2*np.pi/variants) for j in range(variants)]\n", "ang2 = [Angle(size=0.25,angle=np.pi/8, orientation=j*2*np.pi/variants) for j in range(variants)]\n", "acute = ang1 + ang2\n", "hv.Layout([p[:] for p in acute]).cols(8)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ang3 = [Angle(size=0.50,angle=np.pi/4, orientation=j*2*np.pi/variants) for j in range(variants)]\n", "ang4 = [Angle(size=0.25,angle=np.pi/4, orientation=j*2*np.pi/variants) for j in range(variants)]\n", "right = ang3 + ang4\n", "hv.Layout([p[:] for p in right]).cols(8)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ang5 = [Angle(size=0.50,angle=np.pi/3, orientation=j*2*np.pi/variants) for j in range(variants)]\n", "ang6 = [Angle(size=0.25,angle=np.pi/3, orientation=j*2*np.pi/variants) for j in range(variants)]\n", "obtuse = ang5 + ang6\n", "hv.Layout([p[:] for p in obtuse]).cols(8)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "arc1 = [ArcCentered(arc_length=np.pi/2,smoothing=0.015,thickness=0.05,size=0.50, orientation=i*2*np.pi/variants)\n", " for i in range(variants)]\n", "arc2 = [ArcCentered(arc_length=np.pi/2,smoothing=0.015,thickness=0.05,size=0.25,orientation=i*2*np.pi/variants)\n", " for i in range(variants)]\n", "quarter = arc1 + arc2\n", "hv.Layout([p[:] for p in quarter]).cols(8)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "arc3 = [ArcCentered(arc_length=np.pi,smoothing=0.015,thickness=0.05,size=0.5,orientation=i*2*np.pi/variants)\n", " for i in range(variants)]\n", "arc4 = [ArcCentered(arc_length=np.pi,smoothing=0.015,thickness=0.05,size=0.25,orientation=i*2*np.pi/variants)\n", " for i in range(variants)]\n", "semi = arc3 + arc4\n", "hv.Layout([p[:] for p in semi]).cols(8)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "arc5 = [ArcCentered(arc_length=3*np.pi/2,smoothing=0.015,thickness=0.05,size=0.50,orientation=i*2*np.pi/variants)\n", " for i in range(variants)]\n", "arc6 = [ArcCentered(arc_length=3*np.pi/2,smoothing=0.015,thickness=0.05,size=0.25,orientation=i*2*np.pi/variants)\n", " for i in range(variants)]\n", "threeqtrs = arc5 + arc6\n", "hv.Layout([p[:] for p in threeqtrs]).cols(8)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "concentric_like = pol1 + pol2[1:] + pol3[2:] + pol4[2:] + pol5[3:]\n", "radial_like = pol2[:1] + pol3[:2] + pol4[:2] + pol5[:3] + pol6\n", "\n", "grating_stimuli_subclasses = [list(sin.values()), list(hyp.values()), concentric_like, radial_like]\n", "grating_stimuli_subclasses_labels = ['sinusoidal''hyperbolic','concentric-like','radial-like']\n", "\n", "contour_stimuli_subclasses = [bar,tristar,cross,star,acute,right,obtuse,quarter,semi,threeqtrs]\n", "contour_stimuli_subclasses_labels = ['bar','tri-star','cross','star/circle','acute angle',\n", " 'right angle','obtuse angle','quarter arc','semi-circle','3/4 arc']\n", "\n", "all_stimuli_subclasses = grating_stimuli_subclasses + contour_stimuli_subclasses\n", "all_stimuli_subclasses_labels = grating_stimuli_subclasses_labels + contour_stimuli_subclasses_labels" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Can view all patterns at once if you wish:\n", "\n", "```python\n", "hv.Layout([p[:] for c in all_stimuli_subclasses for p in c]).cols(8)\n", "```" ] } ], "metadata": { "kernelspec": { "display_name": "Python [default]", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.13" } }, "nbformat": 4, "nbformat_minor": 1 }