Article directory
overview
Spatial filters are one of the basic tools in digital image processing. It modifies the value of that pixel by applying a specific filter template to each pixel position in the image, performing a weighted operation based on the values of neighboring pixels around that position. This weighting operation can highlight or blur specific features of the image, enabling a variety of image processing tasks.
In noise reduction tasks, spatial filters can average local pixel values, reducing noise in the image and making the image look clearer. In edge detection, filters can emphasize edges in an image, making them more noticeable and easier to analyze later. In image smoothing tasks, spatial filters can smooth the transition areas in the image to make the image look more continuous and natural.
By flexibly applying spatial filters in different image processing scenarios, image quality can be effectively improved to meet various visual needs. The design and selection of these filters is an important topic in the field of image processing, which can help people better understand and analyze image information.
Import library
In order to perform image processing, we usually need to import some necessary libraries
import numpy as np
import matplotlib.pyplot as plt
from fractions import Fraction
from skimage.io import imread, imshow
from scipy.signal import convolve2d
from skimage.color import rgb2gray, gray2rgb
Spatial filter template
The spatial filter template is the core tool for modifying pixel values. In the following code, we define five common spatial filter templates, namely Horizontal Sobel Filter, Vertical Sobel Filter, Edge Detection, Sharpen and Box Blur.
def get_filters():
# 定义滤波器模板
kernel_hsf = np.array([[1, 2, 1],
[0, 0, 0],
[-1, -2, -1]])
kernel_vsf = np.array([[1, 0, -1],
[2, 0, -2],
[1, 0, -1]])
kernel_edge = np.array([[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]])
kernel_sharpen = np.array([[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]])
kernel_bblur = (1 / 9.0) * np.array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
kernels = {
'Box Blur': kernel_bblur,
'Sharpen': kernel_sharpen,
'Horizontal Sobel Filter': kernel_hsf,
'Vertical Sobel Filter': kernel_vsf,
'Edge Detection': kernel_edge,
}
return kernels
Display of results
With the filter templates defined above, we can apply them to real images to obtain different visual effects.
willdisplay_filters('dorm_lobby.png') 换成自己的图片即可
def display_filters(image_path):
# 读取图像
image = imread(image_path)[:,:,:3]
kernels = get_filters()
# 创建包含子图的图像窗口
fig, ax = plt.subplots(2, 3, figsize=(20, 15))
ax[0, 0].imshow(rgb2gray(image[:,:,:3]), cmap='gray')
ax[0, 0].set_title('Original Image', fontsize=20)
ax[0, 0].set_xticks([])
ax[0, 0].set_yticks([])
for i, (name, kernel) in enumerate(kernels.items(), 1):
row = i // 3
col = i % 3
ax[row, col].imshow(kernel, cmap='gray')
ax[row, col].set_title(name, fontsize=30)
for (j, k), val in np.ndenumerate(kernel):
if val < 1:
ax[row, col].text(k, j,
str(Fraction(val).limit_denominator()),
ha='center', va='center',
color='red', fontsize=30)
else:
ax[row, col].text(k, j, str(val),
ha='center', va='center',
color='red', fontsize=30)
plt.tight_layout()
plt.show()
# 展示滤波器效果
display_filters('dorm_lobby.png')
Result:
In the above code, through the function get_filters(), we define five common spatial filter templates, namely Horizontal Sobel Filter, Vertical Sobel Filter, Edge Detection , Sharpen and Box Blur. We can then apply these filters to real images.
import numpy as np
import matplotlib.pyplot as plt
from fractions import Fraction
from skimage.io import imread, imshow
# For Spatial Filters
from scipy.signal import convolve2d
from skimage.color import rgb2gray, gray2rgb
def get_filters():
# Define Filters
# Horizontal Sobel Filter
kernel_hsf = np.array([[1, 2, 1],
[0, 0, 0],
[-1, -2, -1]])
# Vertical Sobel Filter
kernel_vsf = np.array([[1, 0, -1],
[2, 0, -2],
[1, 0, -1]])
# Edge Detection
kernel_edge = np.array([[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]])
# Sharpen
kernel_sharpen = np.array([[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]])
# Box Blur
kernel_bblur = (1 / 9.0) * np.array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
# Define the kernels
kernels = {
'Box Blur': kernel_bblur,
'Sharpen': kernel_sharpen,
'Horizontal Sobel Filter': kernel_hsf,
'Vertical Sobel Filter': kernel_vsf,
'Edge Detection': kernel_edge,
}
return kernels
def display_filters(image_path):
# Read the image
image = imread(image_path)[:, :, :3]
kernels = get_filters()
# Create a figure with subplots for each kernel
fig, ax = plt.subplots(2, 3, figsize=(20, 15))
ax[0, 0].imshow(rgb2gray(image[:, :, :3]), cmap='gray')
ax[0, 0].set_title('Original Image', fontsize=20)
ax[0, 0].set_xticks([])
ax[0, 0].set_yticks([])
# Loop over the keys and values in the kernels dictionary
for i, (name, kernel) in enumerate(kernels.items(), 1):
# Determine the subplot index
row = i // 3
col = i % 3
# Plot the kernel on the appropriate subplot
ax[row, col].imshow(kernel, cmap='gray')
ax[row, col].set_title(name, fontsize=30)
# Loop over the cells in the kernel
for (j, k), val in np.ndenumerate(kernel):
if val < 1:
ax[row, col].text(k, j,
str(Fraction(val).limit_denominator()),
ha='center', va='center',
color='red', fontsize=30)
else:
ax[row, col].text(k, j, str(val),
ha='center', va='center',
color='red', fontsize=30)
# Show the plot
plt.tight_layout()
plt.show()
def apply_selected_kernels(image_path, selected_kernels, plot_cols=3):
# Define the kernels
kernels = get_filters()
# Check if the selected kernels are defined, if not raise an exception
for k in selected_kernels:
if k not in kernels:
raise ValueError(f"Kernel '{k}' not defined.")
# Read the image
image = imread(image_path)[:, :, :3]
# Apply selected kernels to each color channel of the image
conv_rgb_images = {
}
for kernel_name in selected_kernels:
kernel = kernels[kernel_name]
transformed_channels = []
for i in range(3):
conv_image = convolve2d(image[:, :, i], kernel, 'valid')
transformed_channels.append(abs(conv_image))
conv_rgb_image = np.dstack(transformed_channels)
conv_rgb_image = np.clip(conv_rgb_image, 0, 255).astype(np.uint8)
conv_rgb_images[kernel_name] = conv_rgb_image
# Display the original and convolved images
fig, axs = plt.subplots(len(selected_kernels) + 1, plot_cols, figsize=(15, 10))
axs[0, 0].imshow(image)
axs[0, 0].set_title('Original Image')
axs[0, 0].axis('off')
for i, kernel_name in enumerate(selected_kernels, 1):
axs[i, 0].imshow(conv_rgb_images[kernel_name])
axs[i, 0].set_title(kernel_name)
axs[i, 0].axis('off')
# Hide remaining empty subplots, if any
for i in range(len(selected_kernels) + 1, len(axs.flat)):
axs.flatten()[i].axis('off')
plt.tight_layout()
plt.show()
# 调用display_filters()函数来获取滤波器矩阵
# display_filters('dorm_lobby.png')
# 调用apply_selected_kernels()函数,传入图像路径和希望应用的滤波器名称列表
apply_selected_kernels('dorm_lobby.png',
['Edge Detection',
'Horizontal Sobel Filter',
'Vertical Sobel Filter'])
Result:
Of course, we can check the corresponding effects of other templates through the following code:
# Visualize Edge Detection, Sharpen, and Box Blur
apply_selected_kernels('dog.png',
['Edge Detection',
'Sharpen',
'Box Blur'],
plot_cols=2)
Analysis and Summary
In image processing, spatial filters play a very powerful role. Different filter templates can be used to implement various image processing tasks, such as edge detection, image sharpening and blurring, etc. By deeply understanding the characteristics and application scenarios of each filter, we can better use them, unleash our creativity, and explore the infinite possibilities of image processing. Through the introduction of this article, I hope readers will have a clearer understanding of spatial filters and be able to flexibly use this knowledge in practical applications to create more eye-catching image effects.