
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples\stimuli\plot_image_stim.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_stimuli_plot_image_stim.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_stimuli_plot_image_stim.py:


===============================================================================
Generating a stimulus from an image
===============================================================================

*This example shows how to use images as input stimuli for a retinal implant.*

In addition to built-in stimuli such as
:py:class:`~pulse2percept.stimuli.BiphasicPulse` and
:py:class:`~pulse2percept.stimuli.BiphasicPulseTrain`,
you can also load conventional images and convert them to stimuli using
:py:class:`~pulse2percept.stimuli.ImageStimulus`.

Loading an image
----------------

An image can be loaded as follows:

.. code:: python

    stim = ImageStimulus('path-to-image.png')

By default, each pixel in the image is assigned to an electrode, and its
grayscale value is encoded as an amplitude.
If the image has more than 1 channel (e.g., RGB, RGBA), the image is flattened
before each pixel/channel is assigned a different electrode.
You can specify names for the electrodes, but the number of electrodes must
match the number of pixels. By default, electrodes are labeled 1...N.

A number of images come pre-installed with pulse2percept, such as the logo of
the Bionic Vision Lab (BVL) at UC Santa Barbara:

.. GENERATED FROM PYTHON SOURCE LINES 35-42

.. code-block:: Python


    import pulse2percept as p2p
    import numpy as np

    logo = p2p.stimuli.LogoBVL()
    print(logo)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    LogoBVL(data=[[1.], [1.], [1.], ..., [1.], [1.], [0.]], 
            dt=0.001, electrodes=ElectrodeNames, 
            img_shape=(576, 720, 4), is_charge_balanced=None, 
            metadata=dict, shape=(1658880, 1), time=None)




.. GENERATED FROM PYTHON SOURCE LINES 44-98

Inspecting the ``LogoBVL`` object, we can see that gray levels are converted
to floats in the range [0, 1], and that the original 576x720x4 image is
flattened so that each pixel can be assigned to an electrode.

We also notice that ``time=None``, indicating that the stimulus does not have
a time component. Thus we cannot apply temporal models to it.

``LogoBVL`` can be assigned to a stimulus and used in conjunction with a
phosphene model, just like any other
:py:class:`~pulse2percept.stimuli.Stimulus` object.

Preprocessing an image
----------------------

:py:class:`~pulse2percept.stimuli.ImageStimulus` objects come with a number
of methods to process an image before it is passed to an implant. We can:

-  :py:meth:`~pulse2percept.stimuli.ImageStimulus.invert` the
   polarity of the image (applied to all channels except the alpha channel),
-  convert RGB and RGBA images to grayscale using
   :py:meth:`~pulse2percept.stimuli.ImageStimulus.rgb2gray`
   (note that a change in the number of pixels also means a change in the
   number of electrodes),
-  :py:meth:`~pulse2percept.stimuli.ImageStimulus.resize` the image
   to a new height x width (optionally using anti-aliasing),
-  :py:meth:`~pulse2percept.stimuli.ImageStimulus.scale`,
   :py:meth:`~pulse2percept.stimuli.ImageStimulus.shift`, and
   :py:meth:`~pulse2percept.stimuli.ImageStimulus.rotate` the image
   foreground (i.e., anything that's not black),
-  :py:meth:`~pulse2percept.stimuli.ImageStimulus.trim` any black borders
   around the image.
-  :py:meth:`~pulse2percept.stimuli.ImageStimulus.threshold` the image using
   a number of commonly used techniques (e.g., Otsu's method, adaptive
   thresholding, ISODATA),
-  :py:meth:`~pulse2percept.stimuli.ImageStimulus.filter` the image and
   extract edges (e.g., Sobel, Scharr, Canny, median filter),
-  :py:meth:`~pulse2percept.stimuli.ImageStimulus.apply` any input-output
   function not covered above (must accept an image as input and return
   another image of the same size).

Collectively, these methods should support arbitrarily complex image
preprocessing strategies, including the ones commonly used by implants such
as Argus II and Alpha-AMS.

Let's look at a concrete example.
To get the BVL logo into proper shape, we need to convert the 4-channel RGBA
image to grayscale. This can be done with
:py:meth:`~pulse2percept.stimuli.ImageStimulus.rgb2gray`.
In addition, since grayscale values will be mapped to current ampltiudes,
we may want to :py:meth:`~pulse2percept.stimuli.ImageStimulus.invert` the
image so that image edges appear bright on a dark background.

We can perform both actions in one line, and plot the result side-by-side
with the original image:

.. GENERATED FROM PYTHON SOURCE LINES 98-106

.. code-block:: Python


    logo_gray = logo.invert().rgb2gray()

    import matplotlib.pyplot as plt
    fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4))
    logo.plot(ax=ax1)
    logo_gray.plot(ax=ax2)




.. image-sg:: /examples/stimuli/images/sphx_glr_plot_image_stim_001.png
   :alt: plot image stim
   :srcset: /examples/stimuli/images/sphx_glr_plot_image_stim_001.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <Axes: >



.. GENERATED FROM PYTHON SOURCE LINES 107-114

As demonstrated above, multiple image processing steps can be performed in
one line. This is possible because each method returns a copy of the
processed image (without altering the original).

The following example takes the grayscale logo, shrinks it to 75% of its
original size, rotates it by 30 degrees (counter-clockwise), and trims the
black border around the image:

.. GENERATED FROM PYTHON SOURCE LINES 114-117

.. code-block:: Python


    logo_gray.scale(0.75).rotate(30).trim().plot()




.. image-sg:: /examples/stimuli/images/sphx_glr_plot_image_stim_002.png
   :alt: plot image stim
   :srcset: /examples/stimuli/images/sphx_glr_plot_image_stim_002.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <Axes: >



.. GENERATED FROM PYTHON SOURCE LINES 118-135

As mentioned in the introduction above, the
:py:meth:`~pulse2percept.stimuli.ImageStimulus.filter` method provides
a number of popular techniques to extract edges from the image, such as:

-  ``'sobel'`` to extract edges using the `Sobel operator
   <https://scikit-image.org/docs/stable/api/skimage.filters.html#skimage.filters.sobel>`_,
-  ``'scharr'`` to extract edges using the `Scharr operator
   <https://scikit-image.org/docs/stable/api/skimage.filters.html#skimage.filters.scharr>`_,
   and
-  ``'canny'`` to extract edges using the `Canny algorithm
   <https://scikit-image.org/docs/stable/api/skimage.feature.html#skimage.feature.canny>`_.

Additional parameters (e.g., the standard deviation of the Gaussian filter
for the Canny algorithm) can be passed as keyword arguments (e.g.,
``filter('canny', sigma=3)``).

For example, we can use the Scharr operator as follows:

.. GENERATED FROM PYTHON SOURCE LINES 135-138

.. code-block:: Python


    logo_edge = logo_gray.filter('scharr')








.. GENERATED FROM PYTHON SOURCE LINES 139-147

If more advanced image processing methods are required, we can use the
:py:meth:`~pulse2percept.stimuli.ImageStimulus.apply` method to apply
literally any function to the image. The only requirement is that the
function return an image of the same size.

For example, we can thicken the edges in the image by using a morphological
operator (i.e., dilation) provided by
`scikit-image <https://scikit-image.org>`_:

.. GENERATED FROM PYTHON SOURCE LINES 147-157

.. code-block:: Python


    from skimage.morphology import dilation
    logo_dilate = logo_edge.apply(dilation)

    fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4))
    # Edges extracted with the Scharr operator:
    logo_edge.plot(ax=ax1)
    # Edges thickened with dilation:
    logo_dilate.plot(ax=ax2)




.. image-sg:: /examples/stimuli/images/sphx_glr_plot_image_stim_003.png
   :alt: plot image stim
   :srcset: /examples/stimuli/images/sphx_glr_plot_image_stim_003.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <Axes: >



.. GENERATED FROM PYTHON SOURCE LINES 158-159

We can also save the processed stimulus as an image:

.. GENERATED FROM PYTHON SOURCE LINES 159-162

.. code-block:: Python


    logo_dilate.save('dilated_logo.png')








.. GENERATED FROM PYTHON SOURCE LINES 163-173

Using the image as input to a retinal implant
---------------------------------------------

:py:class:`~pulse2percept.stimuli.ImageStimulus` can be used in
combination with any :py:meth:`~pulse2percept.implants.ProsthesisSystem`.
We just have to resize the image first so that the number of pixels in the
image matches the number of electrodes in the implant.

But let's start from the top. The first two steps are to create a model and
choose an implant:

.. GENERATED FROM PYTHON SOURCE LINES 173-185

.. code-block:: Python


    # Simulate only what we need (14x14 deg sampled at 0.1 deg):
    model = p2p.models.ScoreboardModel(xrange=(-7, 7), yrange=(-7, 7), step=0.1)
    model.build()

    from pulse2percept.implants import AlphaAMS
    implant = AlphaAMS()

    # Show the visual field we're simulating (dashed lines) atop the implant:
    model.plot()
    implant.plot()




.. image-sg:: /examples/stimuli/images/sphx_glr_plot_image_stim_004.png
   :alt: plot image stim
   :srcset: /examples/stimuli/images/sphx_glr_plot_image_stim_004.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <Axes: xlabel='x (microns)', ylabel='y (microns)'>



.. GENERATED FROM PYTHON SOURCE LINES 186-189

Since :py:class:`~pulse2percept.implants.AlphaAMS` is a 2D electrode grid,
all we need to do is downscale the image to the size of the grid, and then
*encode* it:

.. GENERATED FROM PYTHON SOURCE LINES 189-192

.. code-block:: Python


    implant.stim = logo_gray.resize(implant.shape).encode()








.. GENERATED FROM PYTHON SOURCE LINES 193-216

The downscaling assigns the pixels of the image to the electrodes in
row-by-row order (i.e., we don't need to specify the actual electrode names).

The encoding is what turns those pixels into stimulation. A gray level is
not a current, and a model reads current, so something has to say how much
current a gray level stands for --
:py:meth:`~pulse2percept.stimuli.ImageStimulus.encode` is that something. By
default it maps gray levels in [0, 1] onto a 20 Hz train of
:py:class:`~pulse2percept.stimuli.BiphasicPulse` with amplitudes in
[0, 50] uA; the section below shows how to change that. Handing the model an
un-encoded image raises a
:py:class:`~pulse2percept.units.DimensionMismatchError`.

.. note ::

   If the implant is not a proper 2D grid, you will have to manually specify
   the input to each electrode.

   In the near future, this will be done automatically using an implant's
   ``preprocess`` method.

Then the implant can be passed to the model's
:py:meth:`~pulse2percept.models.ScoreboardModel.predict_percept` method:

.. GENERATED FROM PYTHON SOURCE LINES 216-219

.. code-block:: Python


    percept_gray = model.predict_percept(implant)








.. GENERATED FROM PYTHON SOURCE LINES 220-230

.. note ::

    :py:class:`~pulse2percept.models.ScoreboardModel` has no temporal
    component, so it reports the instantaneous brightness of each frame of
    the pulse train. :py:meth:`~pulse2percept.percepts.Percept.plot` shows
    the brightest of them.

To see what difference our image preprocessing makes on the quality of the
resulting percept, we can re-run the model on ``logo_dilate`` and plot the
two percepts side-by-side:

.. GENERATED FROM PYTHON SOURCE LINES 230-238

.. code-block:: Python


    implant.stim = logo_dilate.trim().resize(implant.shape).encode()
    percept_dilate = model.predict_percept(implant)

    fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(10, 4))
    percept_gray.plot(ax=ax1)
    percept_dilate.plot(ax=ax2)




.. image-sg:: /examples/stimuli/images/sphx_glr_plot_image_stim_005.png
   :alt: plot image stim
   :srcset: /examples/stimuli/images/sphx_glr_plot_image_stim_005.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <Axes: xlabel='x (degrees of visual angle)', ylabel='y (degrees of visual angle)'>



.. GENERATED FROM PYTHON SOURCE LINES 239-250

Customizing the encoding
------------------------

The :py:meth:`~pulse2percept.stimuli.ImageStimulus.encode` method used above
converts an image into a series of pulse trains (i.e., into electrical
stimuli with a time component).

By default, it interprets the gray level of a pixel as the current amplitude
of a 20 Hz train of :py:class:`~pulse2percept.stimuli.BiphasicPulse`
(0.46 ms phase duration), lasting 500 ms overall. Gray levels in the range
[0, 1] are mapped onto currents in the range [0, 50] uA:

.. GENERATED FROM PYTHON SOURCE LINES 250-253

.. code-block:: Python


    implant.stim = logo_dilate.trim().resize(implant.shape).encode()








.. GENERATED FROM PYTHON SOURCE LINES 254-309

We can customize the range of amplitudes to be used by passing a keyword
argument; e.g. ``amp_range=(0, 20)`` to use currents in [0, 20] uA, and the
pulse rate with ``freq=50``.

We can also specify our own pulse shape to be repeated, by passing a keyword
argument such as ``pulse=BiphasicPulse(1, 0.2)``. Its amplitude is normalized
away, since that is what the encoding sets; only its shape is used.

``encode`` is a shorthand for
:py:class:`~pulse2percept.stimuli.AmplitudeEncoder`, which offers the full
set of options. In particular, passing it an ``implant`` samples the image at
the electrode locations *before* building the pulse trains, which for a video
is the difference between a stimulus of a few hundred kilobytes and one of a
few hundred megabytes:

.. code-block:: python

    encoder = p2p.stimuli.AmplitudeEncoder(implant, amp_range=(0, 50))
    implant.stim = encoder.encode(p2p.stimuli.BostonTrain())

The other way to encode a gray level is as a pulse *rate* at fixed amplitude,
which is what :py:class:`~pulse2percept.stimuli.FrequencyEncoder` does. It is
considerably more expensive to simulate, because electrodes pulsing at
different rates no longer pulse at the same times; ``clock`` (the period of
the stimulator's time base) is the lever that keeps that under control:

.. code-block:: python

    encoder = p2p.stimuli.FrequencyEncoder(implant, freq_range=(0, 300),
                                           amp=50, clock=1)
    implant.stim = encoder.encode(p2p.stimuli.BostonTrain())

A real stimulator usually cannot drive every electrode at once, because the
current it can source at any instant is limited. Give the implant a
:py:class:`~pulse2percept.implants.Raster` and the electrodes take turns
instead, a group at a time, all of them within one pulse period. Every group
still pulses at the full requested rate; the raster only decides *when*
within each period each one fires, so no two groups are ever active at the
same instant:

.. code-block:: python

    implant.max_current = 1000  # uA, summed over electrodes
    implant.raster = p2p.implants.SequentialRaster(6)  # one row at a time
    implant.stim = p2p.stimuli.AmplitudeEncoder(implant).encode(video)

Using the image as input to a spatiotemporal model
---------------------------------------------------

Now, if we passed the new stimulus to
:py:class:`~pulse2percept.models.ScoreboardModel`, it would simply apply the
model (in space) to every time point in the stimulus.
To get a proper temporal response, we need to extend the scoreboard model
with a proper temporal model, such as
:py:class:`~pulse2percept.models.Horsager2009Temporal`:

.. GENERATED FROM PYTHON SOURCE LINES 309-313

.. code-block:: Python


    model = p2p.models.Model(spatial=p2p.models.ScoreboardSpatial,
                             temporal=p2p.models.Horsager2009Temporal)








.. GENERATED FROM PYTHON SOURCE LINES 314-327

.. note::

   You can combine any spatial model (names ending in **Spatial**) with any
   temporal model (names ending in **Temporal**).

To make the model focus on the same visual field as above, we set ``xrange``,
``yrange``, and choose a proper ``step``.

The ``rho`` parameter of the scoreboard model controls how much blur we get
in the resulting percept. The value of this parameter should be set
empirically to match the quality of the vision reported behaviorally by each
implant user.
For the purpose of this tutorial, we will set it to 50um:

.. GENERATED FROM PYTHON SOURCE LINES 327-330

.. code-block:: Python


    model.build(xrange=(-7, 7), yrange=(-7, 7), step=0.1, rho=50)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    Model(beta=3.43, dt=0.005, eps=2.25, 
          grid_type='rectangular', min_current_spread=1e-08, 
          n_gray=None, n_jobs=14, n_threads=14, ndim=[2], 
          noise=None, reduce='last', rho=50, 
          spatial=ScoreboardSpatial, step=0.1, tau1=0.42, 
          tau2=45.25, tau3=26.25, 
          temporal=Horsager2009Temporal, thresh_percept=0, 
          verbose=True, vfmap=Watson2014Map(ndim=2), 
          xrange=(-7, 7), yrange=(-7, 7))



.. GENERATED FROM PYTHON SOURCE LINES 331-339

The predicted percept will now be a movie, where the spatial response (i.e.,
each frame of the movie) is primarily determined by the scoreboard model, but
the temporal evolution of these frames is determined by the Horsager model.

By default, the model will output a movie frame every 20 ms (corresponding to
a 50 Hz frame rate). The frame rate can be adjusted by passing a list of
time points to :py:meth:`~pulse2percept.Model.predict_percept` (e.g.,
``t_percept=np.arange(500)`` to get an output every millisecond):

.. GENERATED FROM PYTHON SOURCE LINES 339-342

.. code-block:: Python


    percept = model.predict_percept(implant)








.. GENERATED FROM PYTHON SOURCE LINES 343-346

The output of the model is a :py:class:`~pulse2percept.percepts.Percept`
object, which can be animated in IPython or Jupyter Notebook using the
:py:meth:`~pulse2percept.percepts.Percept.play` method:

.. GENERATED FROM PYTHON SOURCE LINES 346-349

.. code-block:: Python


    percept.play()






.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">

    <div class="p2p-anim" id="p2p-anim-7328f4a8ee174100a67d119860c97055">
      <div class="p2p-stage">
        <img class="p2p-bg" src="data:image/png;base64,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" alt="">
        <canvas class="p2p-canvas" width="800" height="500"></canvas>
      </div>
      <div class="p2p-controls">
        <button class="p2p-btn" data-p2p-go="first"
                title="First frame">&#9198;</button>
        <button class="p2p-btn" data-p2p-go="prev"
                title="Previous frame">&#9194;</button>
        <button class="p2p-btn p2p-toggle" title="Play/Pause">&#9654;</button>
        <button class="p2p-btn" data-p2p-go="next"
                title="Next frame">&#9193;</button>
        <button class="p2p-btn" data-p2p-go="last"
                title="Last frame">&#9197;</button>
        <input class="p2p-slider" type="range" min="0" max="0" value="0"
               step="1">
        <span class="p2p-count">1/1</span>
        <select class="p2p-mode" title="Loop mode">
          <option value="once">Once</option>
          <option value="loop">Loop</option>
          <option value="reflect">Reflect</option>
        </select>
      </div>
    </div>
    <style>
    #p2p-anim-7328f4a8ee174100a67d119860c97055 { display: inline-block; max-width: 100%; width: 800px;
            font-family: sans-serif; font-size: 13px; }
    #p2p-anim-7328f4a8ee174100a67d119860c97055 .p2p-stage { position: relative; line-height: 0; }
    #p2p-anim-7328f4a8ee174100a67d119860c97055 .p2p-bg { width: 100%; height: auto; display: block; }
    #p2p-anim-7328f4a8ee174100a67d119860c97055 .p2p-canvas { position: absolute; left: 0; top: 0;
                        width: 100%; height: 100%; }
    #p2p-anim-7328f4a8ee174100a67d119860c97055 .p2p-controls { display: flex; align-items: center; gap: 4px;
                          padding-top: 4px; }
    #p2p-anim-7328f4a8ee174100a67d119860c97055 .p2p-btn { cursor: pointer; border: 1px solid rgba(128,128,128,0.4);
                     border-radius: 3px; background: transparent; color: inherit;
                     padding: 1px 6px; font-size: 13px; line-height: 1.4; }
    #p2p-anim-7328f4a8ee174100a67d119860c97055 .p2p-btn:hover { background: rgba(128,128,128,0.2); }
    #p2p-anim-7328f4a8ee174100a67d119860c97055 .p2p-slider { flex: 1 1 auto; min-width: 40px; margin: 0 4px; }
    #p2p-anim-7328f4a8ee174100a67d119860c97055 .p2p-count { font-variant-numeric: tabular-nums; opacity: 0.7;
                       white-space: nowrap; }
    #p2p-anim-7328f4a8ee174100a67d119860c97055 .p2p-mode { background: transparent; color: inherit; font-size: 12px;
                      border-radius: 3px;
                      border: 1px solid rgba(128,128,128,0.4); }
    </style>
    <script>
    (function () {
      var cfg = {"n": 1, "ncols": 1, "fw": 141, "fh": 141, "sw": 141, "sh": 141, "rect": [211, 60, 386, 385], "smooth": true, "interval": 33.333333333333336, "mode": "loop", "title": {"rect": [0, 37, 800, 20], "x": 404, "y": 47, "align": "center", "font": "normal 16.7px \"DejaVu Sans\", Verdana, sans-serif", "color": "#000000"}, "labels": ["t = 500.00 ms"]};
      var root = document.getElementById("p2p-anim-7328f4a8ee174100a67d119860c97055");
      if (!root) { return; }
      var ctx = root.querySelector(".p2p-canvas").getContext("2d");
      var slider = root.querySelector(".p2p-slider");
      var counter = root.querySelector(".p2p-count");
      var mode = root.querySelector(".p2p-mode");
      var toggle = root.querySelector(".p2p-toggle");
      var frame = 0, dir = 1, timer = null, sheet = new Image();

      function draw() {
        if (!sheet.complete || !sheet.naturalWidth) { return; }
        var col = frame % cfg.ncols, row = (frame - col) / cfg.ncols;
        ctx.imageSmoothingEnabled = cfg.smooth;
        // Frames with an alpha channel are composited onto the static background,
        // so the previous frame has to go first or they stack up:
        ctx.clearRect(cfg.rect[0], cfg.rect[1], cfg.rect[2], cfg.rect[3]);
        ctx.drawImage(sheet, col * cfg.sw, row * cfg.sh, cfg.fw, cfg.fh,
                      cfg.rect[0], cfg.rect[1], cfg.rect[2], cfg.rect[3]);
        if (cfg.title) {
          ctx.clearRect(cfg.title.rect[0], cfg.title.rect[1],
                        cfg.title.rect[2], cfg.title.rect[3]);
          ctx.font = cfg.title.font;
          ctx.fillStyle = cfg.title.color;
          ctx.textAlign = cfg.title.align;
          ctx.textBaseline = "middle";
          ctx.fillText(cfg.labels[frame], cfg.title.x, cfg.title.y);
        }
      }

      function show(i) {
        frame = Math.max(0, Math.min(cfg.n - 1, i));
        slider.value = frame;
        counter.textContent = (frame + 1) + "/" + cfg.n;
        draw();
      }

      function pause() {
        if (timer !== null) { clearInterval(timer); timer = null; }
        toggle.innerHTML = "&#9654;";
      }

      function play() {
        if (timer !== null) { return; }
        if (mode.value === "once" && frame === cfg.n - 1) { show(0); }
        toggle.innerHTML = "&#10074;&#10074;";
        timer = setInterval(advance, Math.max(1, cfg.interval));
      }

      function advance() {
        var next = frame + dir;
        if (next > cfg.n - 1 || next < 0) {
          if (mode.value === "loop") {
            next = dir > 0 ? 0 : cfg.n - 1;
          } else if (mode.value === "reflect" && cfg.n > 1) {
            dir = -dir;
            next = frame + dir;
          } else {
            pause();
            return;
          }
        }
        show(next);
      }

      root.querySelectorAll("[data-p2p-go]").forEach(function (btn) {
        btn.addEventListener("click", function () {
          pause();
          dir = 1;
          var go = btn.dataset.p2pGo;
          show(go === "first" ? 0 : go === "last" ? cfg.n - 1 :
               go === "next" ? frame + 1 : frame - 1);
        });
      });
      toggle.addEventListener("click", function () {
        if (timer === null) { play(); } else { pause(); }
      });
      slider.addEventListener("input", function () {
        pause();
        dir = 1;
        show(parseInt(slider.value, 10));
      });
      mode.value = cfg.mode;
      sheet.onload = draw;
      sheet.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAI0AAACNCAMAAAC9gAmXAAADAFBMVEUAAAABAQECAgIDAwMEBAQFBQUGBgYHBwcICAgJCQkKCgoLCwsMDAwNDQ0ODg4PDw8QEBARERESEhITExMUFBQVFRUWFhYXFxcYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAgICAiIiIjIyMkJCQkJCQmJiYnJycoKCgoKCgqKiorKyssLCwsLCwuLi4vLy8wMDAwMDAyMjIzMzM0NDQ0NDQ2NjY3Nzc4ODg4ODg6Ojo7Ozs8PDw8PDw+Pj4/Pz9AQEBBQUFBQUFDQ0NERERFRUVGRkZHR0dISEhJSUlJSUlLS0tMTExNTU1OTk5PT09QUFBRUVFRUVFTU1NUVFRVVVVWVlZXV1dYWFhZWVlZWVlbW1tcXFxdXV1eXl5fX19gYGBhYWFhYWFjY2NkZGRlZWVmZmZnZ2doaGhpaWlpaWlra2tsbGxtbW1ubm5vb29wcHBxcXFxcXFzc3N0dHR1dXV2dnZ3d3d4eHh5eXl5eXl7e3t8fHx9fX1+fn5/f3+AgICBgYGCgoKDg4ODg4OFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+QkJCRkZGSkpKTk5OTk5OVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGioqKjo6Ojo6OlpaWmpqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7Ozs7O1tbW2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr6/v7/AwMDBwcHCwsLDw8PDw8PFxcXGxsbHx8fIyMjJycnKysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PT09PV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pj4+Pl5eXm5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v7+/w8PDx8fHy8vLz8/Pz8/P19fX29vb39/f4+Pj5+fn6+vr7+/v8/Pz9/f3+/v7///8OeeLkAAASMklEQVR4Xu1baYwc5Zn2V/dX9dV9dFffxxw9M5673eOesfE92INtGHtsPBh8BJvDHALjtUkwjjFgUIKDDAEnAQzBXNqNBSggEnYhQPYgUtBqBZtVDqFof2SlKNp/K620P3b1flXd09MzDdPjsffPPD9G01XVVU+97/u91/f2kiWLWMQiFrGIRSxiEYtYxByAGJbjhRrwPMcyqHr+CgIxnIBVw3Y9z3Ndx3Ec27YMTZH4K08o4GJFEplcS0s+l81m0ulUMh51rSvOBzGsIMlEt1w/kc6GTBKJmB9xbUMjCpYEnr1SfBALKjIty7JsO9CQZZmmoeuaShRZVhRFwSJ3ReSDWF4iuu04lqESGUuSJIn0jxiasijJCiGyJFx+PojhJUUzLNsyVFniOZZlGJZlOY7+F/zPixKWZRlLwmVWF2IFWTMt09AIFsFYAQxD2QQfgk+U0OVWF8NJim6BWAIqcAycjiBJIs/C54APw7K8IMmyLF0+aw6tN/AplYfQ9aWomoqFiqgCRiAfWb5s2qJaMqZzAb8jYploug7HORbATPHBMhY4pnLxAoLhREXVdRXXCh+B45GxhGVVNzQFwxITaXgAPqBCfFmMh4F1DQKouTdi6NuLPMfxEjFMU9c0TVUVLFT58CLQW2A6iOFhLemKyNUIhhNlhfoVhmE4iegGwLQgWgUCQRBAFpwOYgViup6j4xoyDIdVjeBgnTOsAMoyDMNyvIhnazhgAHTEhaWDWFF1YqmEpwpVi0QMj6sriQEREN0EWLbjeZ6tY55eG2hrAekgVtIj6bb2nEd4ek/q4gRZVWm4posHYqjjuq5jQ7wCX12VI1g6lhaKDmIlI97aM9CbdzCLliAEKZaIiU6tg2EgbhmOF4lEPM91LFMjikJ0y9LEcPGBzyR4SqyXAsRKZqpraOVIX1rnQSscODvdMA0igpZYQTa8WCLuRxzLNCCQQyyVNdNQAl1RRRuaHH66NDCikeq5anRDud2VQDSsFGQThgqLHRabGU1l0vGIbaggFRWWuCjKqqFVdMWImlM1pEsCI6ixrpUbN67oiMggecSKCiGEBCERJKV7yWw25bsmCAXLClEJFgVR1nRVDIUjaK5nq1LNgpwfEK84ueK60eF2F4wG6LE8HyYQsJYk1Y4mkgnfs01DUxXKB5yQICm6LgfPR5xie66hXGrMQhzW/bZlq4bbHYmtHAtiN6wsmnhZkP6BxRgGtZkwtxGxZlQ8AiPpjmOpoQ+aLxArEsvP9wx2RnCFzBQgC1RUFbJPjDGWiarpkBUDHywKEqlaDuJlwzI1WbykCAoeznTj+baENlPnQAYiA0RJAAeZu0q1JUNiLMmarlSEIxADksVL0RV1FKpu+3EHz3gpyEkxptkvVV0QI2UCyTIGlhImmhaKFEEUUTDNycLvNwsEqYuMZdV0dGHGTRhOlOoy8SDzAsXJYDtY1ozQey9hRIXIkMnPV1eQ6oH+BUk11PCmU0CcMMubgsBkBV5BIQq8hx4ucobHsNAEQZip8jkBNCEJHMcJiqbUs0GsIM4WCkM6WFZUIsuqZYYqRpyERZ7nhXnWfaAnmjZBfAwdxxQYflYylKYMq4xoqqJotiVXDAfYcNBEmI+uQE/U3VI29esbceJMNQWgy0cjqqYRYji2UlnjmJZfHD8v4VA9QZSkoUCa/j6gp0aLlcVmNGrTnFS3I07IhhGIpkCWOC86iJNkTB+IWEmpuI0KQDQNBI4EI9nWmnQMTdVMz3dJwIaVDEuHMMtw89BVoCe4EeIkUscGsXxj0ZDkwMpyR9xSiWpG4l6FjWxHHQV8E9u8cGBlSGEqyUqEhOs0xFeJRoyWtu0ZL+ccVSFGJB6psnETvibQqN+scBAL6yl8A0ZQ1NrsHI40Fo22dNfxR+4a64qoGKu2X5ENIznJpAUvRek0+PbsAF9VrVXAq09TFWLFUG5VVOO6GNvw4GtvPDY5GNOwiHWvYjdIMBJpjzofqqsmhBOYcPULIBy5xv0hTqotq2hECLqPiFULN53/9B+eO1hO6pIgKqZd8eIc8TM+ocuC4ZsSDnXjU88DOybilMdheKmSgFNA2g7dUIQYwVl277tf/ua1QyNpQ+J5STNJJYpjN53UKTXwD3MXTp1oaHpCaiyH4aVpZxnaTYK0gpPja058/B9/eP32kYyJeV4kWoUNEsxUxhbpTZoSDiPIU1ZDwYrKlKrqXg3aNUG1yXKikR977J/+/IdXbxnOOoooiMqUxXFqIheR6YdmhIM4TOTal6fCmbJjuFcNV8QE4QpCiOJ2bvver//y+wu3rGiNGgqkg9XvMbKfj6tc8D9fZ3mNgQSi1UVJxGGlajhQWU9jE/6PWFGL9U9+/5//8rsLt63uykQtXTeq2d8SJHn5lBFIGAxzZsY0KxisT6v+AzaqTINWkOHNyga8f2rZjc989qfPX7xt/UBHLhH1PKtiN0uQYGezTmA49O3mpipWNo36mM1iTZOhBQspijRNzFNsGMlMFXed+cUXnzx9YMPygZ5CPp3wtKpMOSOdiwTpDhjDzNx2VrCKNYMNI+rQoDahGQrlUi2b0PHRqjTevflbr777yonJteWh0mB3e9Y3q2Jm1UQuplTYzEhSGmA22SCe2BE/DmWca+qkERvVzQ3vPXXmxDc2DZeGyssHu/Jxp5IZL2HkaCau0huDbOqSlEZgJK1SJE6BlXTXjyeh4PasaoENqLEbUTGinaP7btm9aXigb7A0NNiVT3h65bFIcpKxKpu52g3ipwcCCvDHhmlHEumk7xrT4kR1TXGSojnZ0qbN65b3dy/t6evvKWQTvh3mohCqop5CP0AqV/+ERmAlRRbqtUpbZlhz44mYZ1WlT0+E/oYTiW66mf5Vq8sDvd1LOzs7C/lUIh5RQ0EiTjGNMG4K02PLV6EuTFUAi1vUvJgfsWs6btQXw8LnsGZ70URL//BwaXCgv7vQkssk4/GEHwQn+pZh2kY91twURd2YPFM4AGg2+DHfrdoCAGICw/JYj6Ry+dbO/qGhUqlUXJpPxf1oNJaMmRU/V/HAkDo2kf7RBH+mcKiFW34i4VfqkgB0e1MkTqrQ07O0u3egWFq+fLCQiti27fnJuFmxV8TRHLTp7I8VwxS9Hkg0/HQ2VcnoQkBKISp2umeoNNDT01dcPlLuy0cMVdXtaCJuVRcVy8PWyFdl1bMCTaXF04F4NZLOZ31tepQB6YhafGm5XOzrKw6vXj28NGkqGBOrng20LZsUTVgyzMaflcxYJu1XyusqwIq9juUryqXlK9dvGi0XIkTkBdmIJmJWxZUiVhDmVeBB2Tu7cDhsQA9vJlVG8rqu2rB+7brRsbF1xawpcSwn6dFk3K6ygZsKvCA23Rlg+Eo9VQeoiBWlLhsDsEqyPL57cvvWsdHVpUKU8AzDino0Fbdp9xK+ymPYD4YCPvzOXDGthpkOBNXrDM0j3u4ev/v+e2/evqHc2xY3RCidBM1PJ5wKm2qDa8abfC1gF2xWXVE+LMfVMUU4ufr2x86cuGVLuasSuRle8zPJKTai7jgGaXTXrwTEkpn6CFEpWabAkNYtx548c2zyqq50xAza6IjXYtm0W3FOLDYjEYvMNLk5AAykYdcQMfXCYdSO8aOnj9882puJmGFnGPFaPJ+pYWNFI9Y8O/zhumpAp15XrFbYcsd9BzcX81Gzkv8gXk+0Zt3KmmKx6TrVvZBmEbZwqp9rMcN0WK1tw417rh0uxG3oUtNjiDdS7fmg3oUXwJpZn3HPHXRjqVGwpQVmje2wan7Flq2re7MRvVr+IMHMdLRU2XASgVw/ONc8Kt226oFaBOucbsnTR6mZ4po1pY6kPWWmjGjnOlvdMDJAF6aB05gbYJk3WlgQiiWR7u7CB15L9QyVevJRfSr6M9hr6WpxgihCJX0pZML3aUiHF6GZzkN6w0lmor27qyU2VSOAe/bbu3IWVRxE7vn4vVoghnawZ79JMCcgY0kURInYsUwuHTVqyCBeS3Z0pg3oaFEyjZQ+Z4QN9dnpQEoJOxwK3ch0PdcitVci0c51FRKaQDc/6cZv9dw8AWnpbEEyAKLDCTD9A/1h2PGpuY5V/EJPu68KHL1qQeZNgomAhkKGulyA4SRRqB8e441s30BbVJVgXqlRDG4WDCfJRJYa0aG1RDBZUj1EgaRI1/BQIarT7byG2m4WdJtKaRgkGoElmaENq5bGLY0QUGJz324MSoc0KWrEW13rr9s4kPHMYDSleuZSQXfkm3w/BseHxndfV271HUNtFO7mB0oHxibmrC3EG61rdu3dNtIeowMn1RMLAQSTSVoT2mJwtHv9xPVjpZaocQmhsgHA76i6Go75fC0Qr6f7V42uL3cmzIUnQ72yrOognrnwYSQn31ss9rYn5pvsfQ1g/ofA/js41a/hgzjFy7YXWtOR2sC1sICxNs3QYSTzq2d2oVnrxlOJ6Gxl4IIh0BaMttEJqerx6YDYrhi261owdNPoqgUAPEgO5yGDMbrqqQAQJjhBUjRonzbnoOYDxPKY6Kahw4QCTf2CpjYFMIHRSJXORs5x+V0aIKkhMCoFlGRJ4On2Cx3lhbkODU5odMDs8nOh6oJxCc20HdvUYaQERp1FSBoUVadHp8+SXm4AH0xgkgymv6eg0ekyvQmXvTAIhgplmBrT9GAk04CxdBgwobPH1SuvDKjN8oKE6bwdjNapMNMSDNBWr7qSqBICwLDW/x8VCjqGzgtgxTQxviJkZjyjZrCNpulVNoH7Ca9aSNB5kKCJKUIzE8qi4BCU4JVJXjqyqmm6rqsKnT4SRWo8dXl76BzZ+cZzRjIjsVjEsSwnGvM9S1eJajhROARDuxYRYJdXUXUnnmttL3R2tKZ813Ej0Po3NVXTVFkIfu0QVncSVk29fudrjkCC27lidHT18oHevmJpWX93oa2to7e89uqr4VBPZ9YlooDNWKatb+XY+MTOXTu3rhsu9g8Uh4aW9S/tKHR0tqdsWRRoqSUqViQaibV0F6Jz3EGsA1LyGw+dOHnsjr07tmwcvXrT2Ng1W3fsu/uBUw8du3XnxpHenEdESUv0rLh64sDhB7798CMnjx7at3vXxHWbxzZtumbr+MSOrStabKKoOkzixAqDg73FdeObuq1gE7pJMFrP/qfe/tmbLz1xdM+Wq8cm9h468uDjz1x467133zh7ZKLc5utYEPXciomDh0889uSzzz3/gydPnzp5/J592zdv3nHgyMnTj95/w7K4CUPQnp/t37hr59ZtB+67dW0i2PZtEoyx7J6L//rvv//Vm0/cumXdxuvvfOj7r7z9waf/8psvPr346K5iypIFjleza/YfO/nwY98799IrF158/oXzzz50y7aNY5NHzr7+1k/O3b06Y1teLJktlLbc8e3j9xx++OzJ7a3yvNiYy+//2z//z3/98eNzd127fmz3fWdefe+Xv/78t19++fnPnthdTBqYZzk5MbLn6PFvfvOhJ1944+Kbb7/z09e+c8fEps17Hnzp/b//4OUja7OO42c7BlZtu+uJF59/6ukf//XTe7vIfAyHNcvf+vA///e///jhucO7rp24+f4zL73584/+8bMv/u2znz6xf2WrB2tKdHuvvfXOW2+77/Hzb77/0Scf/fyNM4dvmth58OT5dz5494d3rkw7brJrZMu+I9/98cWLf/PWhx+eP9ijzocNY5QOv/XbP/3uo5dP3/ONPftvv+/4o989+4OXL773/tvPP3Rw81CrizmW1zLDW7ePTxz49gvvfPzLX7zz2rOPHLn95gN33H/6qXNnH9g1ELOcdHH87kfOnvvRCy//5O9+9cmP9nQo89IU6dhx6vyFc6fu2js5uXv3DZPX79w5uffQ0ZMPH797386ta/sShGNY0cr1FovDYwdP/fDCS888evTQzfv379t70w033Lhn97XlrKUa8YGJv3r88QfvvfPI6edef/7YhuS8rBgJTueqa7aMjvR39wwOlQa6O1pbWgu9pRVXjRT7+vp7W2AYG4oDJxKJt5Y27pjcuXnN0MDAsvJIudjdUSi053xdEiQ9VRzbvnVNqb+0bnzX+Eg22BFvGohXDNuGHwQQ+GkQ/VUbVjQdUmJV18NGbPB7All3on4UXLCqm5apw1Qv7AvAfB82PN8zYeDOi7p6dYS7adAfZgXpdxAL6f8UdcE66CgFV1W+UzkPcZUeCkJqeHQRi1jEIhaxiEUsYhFXHP8HwdI9ABWKOlgAAAAASUVORK5CYII=";
      show(0);
    })();
    </script>

    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 350-351

You can also save the percept as a movie:

.. GENERATED FROM PYTHON SOURCE LINES 351-353

.. code-block:: Python


    percept.save('logo_percept.mp4')








.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 6.652 seconds)


.. _sphx_glr_download_examples_stimuli_plot_image_stim.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_image_stim.ipynb <plot_image_stim.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_image_stim.py <plot_image_stim.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: plot_image_stim.zip <plot_image_stim.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
