.. 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 ` to download the full example code or to run this example in your browser via Binder .. 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.050 seconds) .. _sphx_glr_download_auto_examples_filters_plot_butterworth.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/scikit-image/scikit-image/v0.23.2?filepath=notebooks/auto_examples/filters/plot_butterworth.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_butterworth.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_butterworth.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_