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

.. only:: html

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

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

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

.. _sphx_glr_auto_examples_filters_plot_butterworth.py:


===================
Butterworth Filters
===================

The Butterworth filter is implemented in the frequency domain and is designed
to have no passband or stopband ripple. It can be used in either a lowpass or
highpass variant. The ``cutoff_frequency_ratio`` parameter is used to set the
cutoff frequency as a fraction of the sampling frequency. Given that the
Nyquist frequency is half the sampling frequency, this means that this
parameter should be a positive floating point value < 0.5. The ``order`` of the
filter can be adjusted to control the transition width, with higher values
leading to a sharper transition between the passband and stopband.

.. GENERATED FROM PYTHON SOURCE LINES 18-22

Butterworth filtering example
=============================
Here we define a `get_filtered` helper function to repeat lowpass and
highpass filtering at a specified series of cutoff frequencies.

.. GENERATED FROM PYTHON SOURCE LINES 22-119

.. code-block:: Python


    import matplotlib.pyplot as plt

    from skimage import data, filters

    image = data.camera()

    # cutoff frequencies as a fraction of the maximum frequency
    cutoffs = [0.02, 0.08, 0.16]


    def get_filtered(image, cutoffs, squared_butterworth=True, order=3.0, npad=0):
        """Lowpass and highpass butterworth filtering at all specified cutoffs.

        Parameters
        ----------
        image : ndarray
            The image to be filtered.
        cutoffs : sequence of int
            Both lowpass and highpass filtering will be performed for each cutoff
            frequency in `cutoffs`.
        squared_butterworth : bool, optional
            Whether the traditional Butterworth filter or its square is used.
        order : float, optional
            The order of the Butterworth filter

        Returns
        -------
        lowpass_filtered : list of ndarray
            List of images lowpass filtered at the frequencies in `cutoffs`.
        highpass_filtered : list of ndarray
            List of images highpass filtered at the frequencies in `cutoffs`.
        """

        lowpass_filtered = []
        highpass_filtered = []
        for cutoff in cutoffs:
            lowpass_filtered.append(
                filters.butterworth(
                    image,
                    cutoff_frequency_ratio=cutoff,
                    order=order,
                    high_pass=False,
                    squared_butterworth=squared_butterworth,
                    npad=npad,
                )
            )
            highpass_filtered.append(
                filters.butterworth(
                    image,
                    cutoff_frequency_ratio=cutoff,
                    order=order,
                    high_pass=True,
                    squared_butterworth=squared_butterworth,
                    npad=npad,
                )
            )
        return lowpass_filtered, highpass_filtered


    def plot_filtered(lowpass_filtered, highpass_filtered, cutoffs):
        """Generate plots for paired lists of lowpass and highpass images."""
        fig, axes = plt.subplots(2, 1 + len(cutoffs), figsize=(12, 8))
        fontdict = dict(fontsize=14, fontweight='bold')

        axes[0, 0].imshow(image, cmap='gray')
        axes[0, 0].set_title('original', fontdict=fontdict)
        axes[1, 0].set_axis_off()

        for i, c in enumerate(cutoffs):
            axes[0, i + 1].imshow(lowpass_filtered[i], cmap='gray')
            axes[0, i + 1].set_title(f'lowpass, c={c}', fontdict=fontdict)
            axes[1, i + 1].imshow(highpass_filtered[i], cmap='gray')
            axes[1, i + 1].set_title(f'highpass, c={c}', fontdict=fontdict)

        for ax in axes.ravel():
            ax.set_xticks([])
            ax.set_yticks([])
        plt.tight_layout()
        return fig, axes


    # Perform filtering with the (squared) Butterworth filter at a range of
    # cutoffs.
    lowpasses, highpasses = get_filtered(image, cutoffs, squared_butterworth=True)

    fig, axes = plot_filtered(lowpasses, highpasses, cutoffs)
    titledict = dict(fontsize=18, fontweight='bold')
    fig.text(
        0.5,
        0.95,
        '(squared) Butterworth filtering (order=3.0, npad=0)',
        fontdict=titledict,
        horizontalalignment='center',
    )





.. image-sg:: /auto_examples/filters/images/sphx_glr_plot_butterworth_001.png
   :alt: original, lowpass, c=0.02, lowpass, c=0.08, lowpass, c=0.16, highpass, c=0.02, highpass, c=0.08, highpass, c=0.16
   :srcset: /auto_examples/filters/images/sphx_glr_plot_butterworth_001.png
   :class: sphx-glr-single-img


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

 .. code-block:: none


    Text(0.5, 0.95, '(squared) Butterworth filtering (order=3.0, npad=0)')



.. GENERATED FROM PYTHON SOURCE LINES 120-132

Avoiding boundary artifacts
===========================

It can be seen in the images above that there are artifacts near the edge of
the images (particularly for the smaller cutoff values). This is due to the
periodic nature of the DFT and can be reduced by applying some amount of
padding to the edges prior to filtering so that there are not sharp eges in
the periodic extension of the image. This can be done via the ``npad``
argument to ``butterworth``.

Note that with padding, the undesired shading at the image edges is
substantially reduced.

.. GENERATED FROM PYTHON SOURCE LINES 132-146

.. code-block:: Python



    lowpasses, highpasses = get_filtered(image, cutoffs, squared_butterworth=True, npad=32)

    fig, axes = plot_filtered(lowpasses, highpasses, cutoffs)
    fig.text(
        0.5,
        0.95,
        '(squared) Butterworth filtering (order=3.0, npad=32)',
        fontdict=titledict,
        horizontalalignment='center',
    )





.. image-sg:: /auto_examples/filters/images/sphx_glr_plot_butterworth_002.png
   :alt: original, lowpass, c=0.02, lowpass, c=0.08, lowpass, c=0.16, highpass, c=0.02, highpass, c=0.08, highpass, c=0.16
   :srcset: /auto_examples/filters/images/sphx_glr_plot_butterworth_002.png
   :class: sphx-glr-single-img


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

 .. code-block:: none


    Text(0.5, 0.95, '(squared) Butterworth filtering (order=3.0, npad=32)')



.. GENERATED FROM PYTHON SOURCE LINES 147-157

True Butterworth filter
=======================

To use the traditional signal processing definition of the Butterworth filter,
set ``squared_butterworth=False``. This variant has an amplitude profile in
the frequency domain that is the square root of the default case. This causes
the transition from the passband to the stopband to be more gradual at any
given `order`. This can be seen in the following images which appear a bit
sharper in the lowpass case than their squared Butterworth counterparts
above.

.. GENERATED FROM PYTHON SOURCE LINES 157-170

.. code-block:: Python


    lowpasses, highpasses = get_filtered(image, cutoffs, squared_butterworth=False, npad=32)

    fig, axes = plot_filtered(lowpasses, highpasses, cutoffs)
    fig.text(
        0.5,
        0.95,
        'Butterworth filtering (order=3.0, npad=32)',
        fontdict=titledict,
        horizontalalignment='center',
    )

    plt.show()



.. image-sg:: /auto_examples/filters/images/sphx_glr_plot_butterworth_003.png
   :alt: original, lowpass, c=0.02, lowpass, c=0.08, lowpass, c=0.16, highpass, c=0.02, highpass, c=0.08, highpass, c=0.16
   :srcset: /auto_examples/filters/images/sphx_glr_plot_butterworth_003.png
   :class: sphx-glr-single-img






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

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


.. _sphx_glr_download_auto_examples_filters_plot_butterworth.py:

.. only:: html

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

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

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

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

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

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

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


.. only:: html

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

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