.. 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>`_