.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "intro/scipy/auto_examples/solutions/plot_image_blur.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

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

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

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

.. _sphx_glr_intro_scipy_auto_examples_solutions_plot_image_blur.py:


=======================================================
Simple image blur by convolution with a Gaussian kernel
=======================================================

Blur an an image (:download:`../../../../data/elephant.png`) using a
Gaussian kernel.

Convolution is easy to perform with FFT: convolving two signals boils
down to multiplying their FFTs (and performing an inverse FFT).

.. GENERATED FROM PYTHON SOURCE LINES 13-18

.. code-block:: Python


    import numpy as np
    import scipy as sp
    import matplotlib.pyplot as plt








.. GENERATED FROM PYTHON SOURCE LINES 19-21

The original image
####################################################################

.. GENERATED FROM PYTHON SOURCE LINES 21-27

.. code-block:: Python


    # read image
    img = plt.imread("../../../../data/elephant.png")
    plt.figure()
    plt.imshow(img)




.. image-sg:: /intro/scipy/auto_examples/solutions/images/sphx_glr_plot_image_blur_001.png
   :alt: plot image blur
   :srcset: /intro/scipy/auto_examples/solutions/images/sphx_glr_plot_image_blur_001.png
   :class: sphx-glr-single-img


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

 .. code-block:: none


    <matplotlib.image.AxesImage object at 0x7f63435bc0e0>



.. GENERATED FROM PYTHON SOURCE LINES 28-30

Prepare an Gaussian convolution kernel
####################################################################

.. GENERATED FROM PYTHON SOURCE LINES 30-39

.. code-block:: Python


    # First a 1-D  Gaussian
    t = np.linspace(-10, 10, 30)
    bump = np.exp(-0.1 * t**2)
    bump /= np.trapezoid(bump)  # normalize the integral to 1

    # make a 2-D kernel out of it
    kernel = bump[:, np.newaxis] * bump[np.newaxis, :]








.. GENERATED FROM PYTHON SOURCE LINES 40-42

Implement convolution via FFT
####################################################################

.. GENERATED FROM PYTHON SOURCE LINES 42-60

.. code-block:: Python


    # Padded fourier transform, with the same shape as the image
    # We use :func:`scipy.fft.fft2` to have a 2D FFT
    kernel_ft = sp.fft.fft2(kernel, s=img.shape[:2], axes=(0, 1))

    # convolve
    img_ft = sp.fft.fft2(img, axes=(0, 1))
    # the 'newaxis' is to match to color direction
    img2_ft = kernel_ft[:, :, np.newaxis] * img_ft
    img2 = sp.fft.ifft2(img2_ft, axes=(0, 1)).real

    # clip values to range
    img2 = np.clip(img2, 0, 1)

    # plot output
    plt.figure()
    plt.imshow(img2)




.. image-sg:: /intro/scipy/auto_examples/solutions/images/sphx_glr_plot_image_blur_002.png
   :alt: plot image blur
   :srcset: /intro/scipy/auto_examples/solutions/images/sphx_glr_plot_image_blur_002.png
   :class: sphx-glr-single-img


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

 .. code-block:: none


    <matplotlib.image.AxesImage object at 0x7f634205d880>



.. GENERATED FROM PYTHON SOURCE LINES 61-67

Further exercise (only if you are familiar with this stuff):

A "wrapped border" appears in the upper left and top edges of the
image. This is because the padding is not done correctly, and does
not take the kernel size into account (so the convolution "flows out
of bounds of the image").  Try to remove this artifact.

.. GENERATED FROM PYTHON SOURCE LINES 70-76

A function to do it: :func:`scipy.signal.fftconvolve`
####################################################################

 The above exercise was only for didactic reasons: there exists a
 function in scipy that will do this for us, and probably do a better
 job: :func:`scipy.signal.fftconvolve`

.. GENERATED FROM PYTHON SOURCE LINES 76-83

.. code-block:: Python


    # mode='same' is there to enforce the same output shape as input arrays
    # (ie avoid border effects)
    img3 = sp.signal.fftconvolve(img, kernel[:, :, np.newaxis], mode="same")
    plt.figure()
    plt.imshow(img3)




.. image-sg:: /intro/scipy/auto_examples/solutions/images/sphx_glr_plot_image_blur_003.png
   :alt: plot image blur
   :srcset: /intro/scipy/auto_examples/solutions/images/sphx_glr_plot_image_blur_003.png
   :class: sphx-glr-single-img


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

 .. code-block:: none


    <matplotlib.image.AxesImage object at 0x7f63421a84a0>



.. GENERATED FROM PYTHON SOURCE LINES 84-87

Note that we still have a decay to zero at the border of the image.
Using :func:`scipy.ndimage.gaussian_filter` would get rid of this
artifact

.. GENERATED FROM PYTHON SOURCE LINES 87-90

.. code-block:: Python



    plt.show()








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

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


.. _sphx_glr_download_intro_scipy_auto_examples_solutions_plot_image_blur.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_blur.ipynb <plot_image_blur.ipynb>`

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

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

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

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


.. only:: html

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

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