
- SciPy - Home
- SciPy - Introduction
- SciPy - Environment Setup
- SciPy - Basic Functionality
- SciPy - Relationship with NumPy
- SciPy Clusters
- SciPy - Clusters
- SciPy - Hierarchical Clustering
- SciPy - K-means Clustering
- SciPy - Distance Metrics
- SciPy Constants
- SciPy - Constants
- SciPy - Mathematical Constants
- SciPy - Physical Constants
- SciPy - Unit Conversion
- SciPy - Astronomical Constants
- SciPy - Fourier Transforms
- SciPy - FFTpack
- SciPy - Discrete Fourier Transform (DFT)
- SciPy - Fast Fourier Transform (FFT)
- SciPy Integration Equations
- SciPy - Integrate Module
- SciPy - Single Integration
- SciPy - Double Integration
- SciPy - Triple Integration
- SciPy - Multiple Integration
- SciPy Differential Equations
- SciPy - Differential Equations
- SciPy - Integration of Stochastic Differential Equations
- SciPy - Integration of Ordinary Differential Equations
- SciPy - Discontinuous Functions
- SciPy - Oscillatory Functions
- SciPy - Partial Differential Equations
- SciPy Interpolation
- SciPy - Interpolate
- SciPy - Linear 1-D Interpolation
- SciPy - Polynomial 1-D Interpolation
- SciPy - Spline 1-D Interpolation
- SciPy - Grid Data Multi-Dimensional Interpolation
- SciPy - RBF Multi-Dimensional Interpolation
- SciPy - Polynomial & Spline Interpolation
- SciPy Curve Fitting
- SciPy - Curve Fitting
- SciPy - Linear Curve Fitting
- SciPy - Non-Linear Curve Fitting
- SciPy - Input & Output
- SciPy - Input & Output
- SciPy - Reading & Writing Files
- SciPy - Working with Different File Formats
- SciPy - Efficient Data Storage with HDF5
- SciPy - Data Serialization
- SciPy Linear Algebra
- SciPy - Linalg
- SciPy - Matrix Creation & Basic Operations
- SciPy - Matrix LU Decomposition
- SciPy - Matrix QU Decomposition
- SciPy - Singular Value Decomposition
- SciPy - Cholesky Decomposition
- SciPy - Solving Linear Systems
- SciPy - Eigenvalues & Eigenvectors
- SciPy Image Processing
- SciPy - Ndimage
- SciPy - Reading & Writing Images
- SciPy - Image Transformation
- SciPy - Filtering & Edge Detection
- SciPy - Top Hat Filters
- SciPy - Morphological Filters
- SciPy - Low Pass Filters
- SciPy - High Pass Filters
- SciPy - Bilateral Filter
- SciPy - Median Filter
- SciPy - Non - Linear Filters in Image Processing
- SciPy - High Boost Filter
- SciPy - Laplacian Filter
- SciPy - Morphological Operations
- SciPy - Image Segmentation
- SciPy - Thresholding in Image Segmentation
- SciPy - Region-Based Segmentation
- SciPy - Connected Component Labeling
- SciPy Optimize
- SciPy - Optimize
- SciPy - Special Matrices & Functions
- SciPy - Unconstrained Optimization
- SciPy - Constrained Optimization
- SciPy - Matrix Norms
- SciPy - Sparse Matrix
- SciPy - Frobenius Norm
- SciPy - Spectral Norm
- SciPy Condition Numbers
- SciPy - Condition Numbers
- SciPy - Linear Least Squares
- SciPy - Non-Linear Least Squares
- SciPy - Finding Roots of Scalar Functions
- SciPy - Finding Roots of Multivariate Functions
- SciPy - Signal Processing
- SciPy - Signal Filtering & Smoothing
- SciPy - Short-Time Fourier Transform
- SciPy - Wavelet Transform
- SciPy - Continuous Wavelet Transform
- SciPy - Discrete Wavelet Transform
- SciPy - Wavelet Packet Transform
- SciPy - Multi-Resolution Analysis
- SciPy - Stationary Wavelet Transform
- SciPy - Statistical Functions
- SciPy - Stats
- SciPy - Descriptive Statistics
- SciPy - Continuous Probability Distributions
- SciPy - Discrete Probability Distributions
- SciPy - Statistical Tests & Inference
- SciPy - Generating Random Samples
- SciPy - Kaplan-Meier Estimator Survival Analysis
- SciPy - Cox Proportional Hazards Model Survival Analysis
- SciPy Spatial Data
- SciPy - Spatial
- SciPy - Special Functions
- SciPy - Special Package
- SciPy Advanced Topics
- SciPy - CSGraph
- SciPy - ODR
- SciPy Useful Resources
- SciPy - Reference
- SciPy - Quick Guide
- SciPy - Cheatsheet
- SciPy - Useful Resources
- SciPy - Discussion
SciPy - Bilateral Filter
A Bilateral Filter is a nonlinear, edge-preserving and noise-reducing smoothing filter. It smooths images while preserving edges by weighting pixel values with a spatial Gaussian filter and an intensity Gaussian filter.
SciPy does not have a built-in bilateral filter but it can be implemented using the scipy.ndimage module or other libraries like OpenCV.
Key Features of Bilateral Filter
Following are the key features of the Bilateral Filter which is used in SciPy Image Processing −
- Edge Preservation: The Bilateral filter is designed to preserve edges while reducing noise. It smooths regions that are spatially close and have similar intensity values while keeping sharp edges intact. This makes it especially useful for tasks where edge information is critical such as in image denoising and pre-processing for segmentation.
- Non-Linear Filtering: Unlike linear filters such as Gaussian filters, the bilateral filter is non-linear because it combines both the spatial distance and intensity difference between neighboring pixels to compute a weighted average. This non-linearity helps to preserve the edges of objects in the image.
- Dual Gaussian Filters: The bilateral filter uses two Gaussian functions namely, Spatial Gaussian which determines the spatial distance i.e., the Euclidean distance between pixels to decide how much influence neighboring pixels have and Intensity Guassian which considers the intensity i.e., color or grayscale difference between neighboring pixels to determine how much influence a pixel will have based on its similarity to the center pixel.
- Edge-Aware Smoothing: This filter performs smoothing by adjusting the weight of each pixel based not only on its spatial distance but also its intensity difference from the target pixel. This makes it ideal for applications where we want to reduce noise while preserving the edges as the filter will not smooth across edges with high intensity differences.
- Parameter Sensitivity: There are two methods namely, sigma spatial(_spatial) which is used to how much spatial distance influences the filter. Larger values means that pixels farther from the center pixel will have a higher weight and sigma Intensity(_Intensity) which controls how much the intensity difference influences the filter. Larger values reduce the edge-preserving effect and increase smoothing even across intensity differences.
- Local Adaptive Filtering: The Bilateral filter adapts to the local features of the image. It adjusts the amount of filtering applied based on both the pixels spatial location and its intensity similarity to neighboring pixels. This leads to a more context-sensitive result compared to traditional linear filters.
- Computational Complexity: The Bilateral filter is computationally expensive because it requires the calculation of pixel similarity for each pixel in a neighborhood by making it slower than linear filters. The complexity increases with the size of the filter kernel and the image.
- Noise Reduction: Bilateral filters are especially effective at reducing various types of noise such as Gaussian noise or salt-and-pepper noise without blurring the edges of objects in the image.
Advantages of Bilateral Filter
Here are the advantages of the Scipy Bilateral Filter used in Image processing −
- Edge Preservation: The traditional filters that smooth across edges where the bilateral filter keeps edges sharp.
- Noise Removal: This filter is effective in removing various types of noise especially in high-resolution images.
- Local Adaptability: The filter adapts to local image features by considering both spatial proximity and intensity similarity.
Disadvantages of Bilateral Filter
Bilateral Filter have the advantages as well as the disadvantages which can be defined as follows −
- Computationally Intensive: In the Bilateral Filter the need of computing the intensity and spatial weights for each pixel makes the bilateral filter slower than other traditional smoothing filters, especially for large images.
- Parameter Tuning: In this filter the parameter tuning for choosing appropriate values for the spatial and intensity sigma values can be tricky and requires experimentation for different images.
Implementing a Bilateral Filter in SciPy
Implementing a bilateral filter in SciPy requires combining spatial and intensity domain Gaussian weighting to smooth images while preserving edges.
SciPy itself does not have a direct bilateral filter implementation but we can create one using its utilities such as scipy.ndimage.gaussian_filter() and NumPy for computations.
Syntax
Following is the syntax of the scipy.ndimage.gaussian_filter() function which can be used to apply the Bilateral filter in scipy −
scipy.ndimage.gaussian_filter( input, sigma, order=0, output=None, mode='reflect', cval=0.0, truncate=4.0 )
Here are the parameters of the function scipy.ndimage.gaussian_filter() −
- input: The input array such as an image as a NumPy array.
- sigma: Standard deviation for the Gaussian kernel. It can be a single number or a sequence for each axis.
- order: This is the derivative order where 0 for a regular Gaussian blur and higher values compute derivatives.
- output(optional): This is the output array to store the result.
- mode: This parameter determines how the array borders are handled and the modes are such as reflect, constant, nearest, mirror and wrap.
- cval: This is the constant value to fill edges if mode='constant'.
- truncate: This parameter is used to truncate the filter at this many standard deviations.
Example
Following is the example of implementing the Bilateral filter using the scipy.ndimage.guassian_filter() function of scipy −
import numpy as np from scipy.ndimage import gaussian_filter from skimage import data import matplotlib.pyplot as plt # load an image image = data.camera() sigma_s = 5 sigma_r = 20 def bilateral_filter(image, sigma_s, sigma_r): # Ensure the image is a floating-point array image = image.astype(np.float64) # Create a grid of spatial coordinates radius = int(3 * sigma_s) # Typically, 3*sigma_s is used as the filter radius y, x = np.mgrid[-radius:radius+1, -radius:radius+1] # Spatial Gaussian weights spatial_gaussian = np.exp(-(x**2 + y**2) / (2 * sigma_s**2)) # Initialize the output image output = np.zeros_like(image) normalizer = np.zeros_like(image) # Iterate over each pixel for i in range(radius, image.shape[0] - radius): for j in range(radius, image.shape[1] - radius): # Extract the local patch patch = image[i-radius:i+radius+1, j-radius:j+radius+1] # Compute the intensity Gaussian weights intensity_gaussian = np.exp(-((patch - image[i, j])**2) / (2 * sigma_r**2)) # Combine the spatial and intensity weights weights = spatial_gaussian * intensity_gaussian # Normalize weights weights /= weights.sum() # Compute the filtered pixel value output[i, j] = np.sum(patch * weights) normalizer[i, j] = weights.sum() return output bilateral_image = bilateral_filter(image, sigma_s, sigma_r) # Display original and Filtered images plt.figure(figsize=(12, 6)) plt.subplot(1, 2, 1) plt.title("Original Image") plt.imshow(image, cmap="gray") plt.subplot(1, 2, 2) plt.title("Bilateral Filter (sigma_s=2)") plt.imshow(bilateral_image) plt.show()
Here is the output of the Bilateral filter with the help of scipy.ndimage.guassian_filter() function −

Implementing Bilateral Filter using OpenCV
OpenCV provides a highly optimized implementation of bilateral filtering through the cv2.bilateralFilter() function. This function is much faster than a custom implementation and is well-suited for real-time applications.
Here is the example of implementing the Bilateral Filtering through the cv2.bilateralFilter() function in OpenCV −
import cv2 import matplotlib.pyplot as plt # Load a color image image = cv2.imread("\images\images.jpeg") # Check if the image was loaded correctly if image is None: print("Error: Unable to load image. Check the file path.") else: # Convert from BGR to RGB (OpenCV loads images in BGR by default) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # Apply bilateral filter filtered_image = cv2.bilateralFilter(image, d=15, sigmaColor=80, sigmaSpace=80) # Display the original and filtered images plt.figure(figsize=(12, 6)) plt.subplot(1, 2, 1) plt.title("Original Image") plt.imshow(image) plt.axis('off') plt.subplot(1, 2, 2) plt.title("Bilateral Filtered Image") plt.imshow(filtered_image) plt.axis('off') plt.show()
Following is the output of the Bilateral Function through OpenCV −
