1.线性空域滤波器
(1)基于OpenCV对灰度图像进行平滑滤波
# 导入所需的库
import numpy as np
import cv2 as cv
from scipy import ndimage
from skimage import io, util, exposure, filters, morphology, color
import matplotlib.pyplot as plt
%matplotlib inline # 在Jupyter Notebook中显示Matplotlib图片
#--------------------------------------
# 读取灰度图像
img = cv.imread('./imagedata/eight.tif',cv.IMREAD_GRAYSCALE)
# 定义3个不同大小的平均滤波器
w3 = 3
kav3 = np.ones((w3, w3), np.float32) / (w3*w3)
w5 = 5
kav5 = np.ones((w5, w5), np.float32) / (w5*w5)
w7 = 7
kav7 = np.ones((w7, w7), np.float32) / (w7*w7)
# 使用OpenCV的filter2D函数进行平滑滤波操作,并分别采用了两种不同的边界填充方式:反射填充和常数填充。
img_smoothed31 = cv.filter2D(img, -1, kernel=kav3)
img_smoothed32 = cv.filter2D(img, -1, kernel=kav3 ,borderType=cv.BORDER_CONSTANT)
img_smoothed51 = cv.filter2D(img, -1, kernel=kav5)
img_smoothed52 = cv.filter2D(img, -1, kernel=kav5 ,borderType=cv.BORDER_CONSTANT)
img_smoothed71 = cv.filter2D(img, -1, kernel=kav7)
img_smoothed72 = cv.filter2D(img, -1, kernel=kav7 ,borderType=cv.BORDER_CONSTANT)
# 使用Matplotlib将原始图像和滤波后的图像展示在一个4×3的矩阵中。
plt.figure(figsize=(16,8))
plt.gray() # 将显示的图像设置为灰度模式
plt.subplot(4,3,2); plt.imshow(img,vmin=0,vmax=255)
plt.title('Original')
plt.axis('off') # 不显示坐标轴
plt.subplot(4,3,4); plt.imshow(img_smoothed51,vmin=0,vmax=255)
plt.title('smoothed5, border reflect')
plt.axis('off')
plt.subplot(4,3,6); plt.imshow(img_smoothed52,vmin=0,vmax=255)
plt.title('smoothed5,border padding 0')
plt.axis('off')
plt.subplot(4,3,7); plt.imshow(img_smoothed31,vmin=0,vmax=255)
plt.title('smoothed3,border padding 0')
plt.axis('off')
plt.subplot(4,3,9); plt.imshow(img_smoothed32,vmin=0,vmax=255)
plt.title('smoothed3,border padding 0')
plt.axis('off')
plt.subplot(4,3,10); plt.imshow(img_smoothed71,vmin=0,vmax=255)
plt.title('smoothed7,border padding 0')
plt.axis('off')
plt.subplot(4,3,12); plt.imshow(img_smoothed72,vmin=0,vmax=255)
plt.title('smoothed7,border padding 0')
plt.axis('off')
plt.show() # 显示图像
(2)基于OpenCV对彩色图像进行平滑滤波
# 导入所需的库
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 读取彩色图像
img = cv.imread('./imagedata/baboon.jpg', cv.IMREAD_COLOR)
h = 35
kav5 = np.ones((h, h), np.float32) / (h * h)
# 使用OpenCV的filter2D函数进行平滑滤波操作
img_smoothed = cv.filter2D(img, -1, kav5)
# 创建一个大小为12x6的图像窗口,并展示原始图像和平滑后的图像
plt.figure(figsize=(12, 6))
# 显示原始图像
plt.subplot(1, 2, 1)
plt.imshow(img, vmin=0, vmax=255)
plt.title('Original')
plt.axis('off')
# 显示平滑后的图像
plt.subplot(1, 2, 2)
plt.imshow(img_smoothed, vmin=0, vmax=255)
plt.title('smoothed35, border reflect')
plt.axis('off')
plt.show() # 显示图像
(3)基于SciPy对灰度图像进行平滑滤波
# 导入所需的库
import numpy as np
from scipy import ndimage
from skimage import io
import matplotlib.pyplot as plt
# 读取灰度图像
img = io.imread('./imagedata/camera.png')
# 定义一个5x5的平均滤波器
kav5 = np.ones((5, 5), np.float32) / 25
# 使用Scipy的convolve函数进行平滑滤波操作,并分别采用了两种不同的边界填充方式:反射填充和常数填充。
img_smoothed1 = ndimage.convolve(img, kav5)
img_smoothed2 = ndimage.convolve(img, kav5, mode='constant', cval=0)
# 创建一个大小为12x6的图像窗口,并展示原始图像和滤波后的图像
plt.figure(figsize=(12, 6))
# 显示原始图像
plt.subplot(1, 3, 1)
plt.imshow(img, vmin=0, vmax=255)
plt.title('Original')
plt.axis('off')
# 显示滤波后的图像(反射填充)
plt.subplot(1, 3, 2)
plt.imshow(img_smoothed1, vmin=0, vmax=255)
plt.title('Convolved Image')
plt.axis('off')
# 显示滤波后的图像(常数填充)
plt.subplot(1, 3, 3)
plt.imshow(img_smoothed2, vmin=0, vmax=255)
plt.title('Convolved with Constant Mode')
plt.axis('off')
plt.show() # 显示图像
(4)基于SciPy对彩色图像进行平滑滤波
# 导入所需的库
import numpy as np
from scipy import ndimage
from skimage import io
import matplotlib.pyplot as plt
# 读取彩色图像
img = io.imread('./imagedata/astronaut.png')
# 定义一个5x5的平均滤波器,中心位置为0,周围为均匀权重
kav5 = np.ones((5, 5), np.float32) / 25
a0 = np.zeros((5, 5), np.float32)
kav5c = np.dstack((a0, kav5, a0))
# 使用Scipy的convolve函数进行平滑滤波操作,采用常数填充方式
img_smoothed_c0 = ndimage.convolve(img, kav5c, mode='constant', cval=0)
# 使用Scipy的correlate函数进行相关运算
img_smoothed_r = ndimage.correlate(img, kav5c)
# 创建一个大小为12x6的图像窗口,并展示原始图像、常数填充后的滤波图像和相关运算后的图像
plt.figure(figsize=(12, 6))
# 显示原始图像
plt.subplot(1, 3, 1)
plt.imshow(img, vmin=0, vmax=255)
plt.title('Original')
plt.axis('off')
# 显示常数填充后的滤波图像
plt.subplot(1, 3, 2)
plt.imshow(img_smoothed_c0, vmin=0, vmax=255)
plt.title('Convolved Image')
plt.axis('off')
# 显示相关运算后的图像
plt.subplot(1, 3, 3)
plt.imshow(img_smoothed_r, vmin=0, vmax=255)
plt.title('Correlated Image')
plt.axis('off')
plt.show() # 显示图像
2.非线性空域滤波器
(1)最大值/最小值滤波
# 导入所需的库
import numpy as np
from skimage import io, util
from scipy import ndimage
import matplotlib.pyplot as plt
# 读取灰度图像
img = io.imread('./imagedata/eight.tif')
# 添加椒盐噪声
img_noise1 = util.random_noise(img, mode='pepper', amount=0.1)
img_noise1 = util.img_as_ubyte(img_noise1)
# 添加盐噪声
img_noise2 = util.random_noise(img, mode='salt', amount=0.1)
img_noise2 = util.img_as_ubyte(img_noise2)
# 对图像进行最大值滤波
img_result1 = ndimage.maximum_filter(img_noise1, size=3)
# 对图像进行最小值滤波
img_result2 = ndimage.minimum_filter(img_noise2, size=3)
# 创建一个大小为15x6的图像窗口,并展示原始图像、添加噪声后的图像、最大值滤波和最小值滤波后的图像
plt.figure(figsize=(15, 6))
# 显示原始图像
plt.subplot(1, 5, 1)
plt.imshow(img, vmin=0, vmax=255)
plt.title('Original')
plt.axis('off')
# 显示添加椒盐噪声的图像
plt.subplot(1, 5, 2)
plt.imshow(img_noise1, vmin=0, vmax=255)
plt.title('Pepper Noise')
plt.axis('off')
# 显示添加盐噪声的图像
plt.subplot(1, 5, 3)
plt.imshow(img_noise2, vmin=0, vmax=255)
plt.title('Salt Noise')
plt.axis('off')
# 显示最大值滤波后的图像
plt.subplot(1, 5, 4)
plt.imshow(img_result1, vmin=0, vmax=255)
plt.title('Maximum Filter')
plt.axis('off')
# 显示最小值滤波后的图像
plt.subplot(1, 5, 5)
plt.imshow(img_result2, vmin=0, vmax=255)
plt.title('Minimum Filter')
plt.axis('off')
plt.show() # 显示图像
(2)中值滤波
# 导入所需的库
import cv2 as cv
from skimage import util
import matplotlib.pyplot as plt
# 读取灰度图像
img = cv.imread('./imagedata/eight.tif', 0)
# 添加椒盐噪声
img_noise = util.random_noise(img, mode='s&p', amount=0.2)
img_noise = util.img_as_ubyte(img_noise)
# 对图像进行中值滤波,设置卷积核大小为3x3和5x5
img_result1 = cv.medianBlur(img_noise, ksize=3)
img_result2 = cv.medianBlur(img_noise, ksize=5)
# 创建一个大小为12x6的图像窗口,并展示原始图像、添加椒盐噪声后的图像、3x3和5x5中值滤波后的图像
plt.figure(figsize=(12, 6)) # 调整图像显示大小
# 显示原始图像
plt.subplot(1, 4, 1)
plt.imshow(img, cmap='gray', vmin=0, vmax=255)
plt.title('Original')
plt.axis('off')
# 显示添加椒盐噪声后的图像
plt.subplot(1, 4, 2)
plt.imshow(img_noise, cmap='gray', vmin=0, vmax=255)
plt.title('Salt & Pepper Noise')
plt.axis('off')
# 显示3x3中值滤波后的图像
plt.subplot(1, 4, 3)
plt.imshow(img_result1, cmap='gray', vmin=0, vmax=255)
plt.title('Median Filter (3x3)')
plt.axis('off')
# 显示5x5中值滤波后的图像
plt.subplot(1, 4, 4)
plt.imshow(img_result2, cmap='gray', vmin=0, vmax=255)
plt.title('Median Filter (5x5)')
plt.axis('off')
plt.show() # 显示图像
(3)自适应中值滤波
import numpy as np
import cv2
from skimage import util
import matplotlib.pyplot as plt
def adpmedfilt2(image, msize=7):
# 获取图像的行数和列数
rows, cols = image.shape
# 复制输入图像以保存滤波结果
filtered_image = np.copy(image)
for i in range(rows):
for j in range(cols):
kernel_size = 3
while kernel_size <= msize:
k_start = max(0, i - kernel_size // 2)
k_end = min(rows, i + kernel_size // 2 + 1)
l_start = max(0, j - kernel_size // 2)
l_end = min(cols, j + kernel_size // 2 + 1)
kernel = image[k_start:k_end, l_start:l_end]
median = np.median(kernel)
min_val = np.min(kernel)
max_val = np.max(kernel)
if min_val < median < max_val:
if min_val < image[i, j] < max_val:
break
else:
filtered_image[i, j] = median
break
else:
kernel_size += 2
return filtered_image
# 读取原始图像并添加椒盐噪声
img = cv.imread('./imagedata/cameraman.tif', 0)
img_noise = util.random_noise(img, mode='s&p', amount=0.2)
img_noise = util.img_as_ubyte(img_noise)
# 使用3x3和7x7尺寸的中值滤波器对噪声图像进行处理
img_result1 = cv.medianBlur(img_noise, ksize=3)
img_result2 = cv.medianBlur(img_noise, ksize=7)
# 使用自适应中值滤波器对噪声图像进行处理
img_result3 = adpmedfilt2(img_noise, msize=7)
# 创建一个大小为15x6的图像窗口,展示不同处理步骤后的图像
plt.figure(figsize=(15, 6))
# 显示原始图像
plt.subplot(1, 5, 1)
plt.imshow(img, cmap='gray', vmin=0, vmax=255)
plt.title('Original')
plt.axis('off')
# 显示添加椒盐噪声后的图像
plt.subplot(1, 5, 2)
plt.imshow(img_noise, cmap='gray', vmin=0, vmax=255)
plt.title('Salt & Pepper Noise')
plt.axis('off')
# 显示3x3中值滤波后的图像
plt.subplot(1, 5, 3)
plt.imshow(img_result1, cmap='gray', vmin=0, vmax=255)
plt.title('Median Filter (3x3)')
plt.axis('off')
# 显示7x7中值滤波后的图像
plt.subplot(1, 5, 4)
plt.imshow(img_result2, cmap='gray', vmin=0, vmax=255)
plt.title('Median Filter (7x7)')
plt.axis('off')
# 显示自适应中值滤波后的图像
plt.subplot(1, 5, 5)
plt.imshow(img_result3, cmap='gray', vmin=0, vmax=255)
plt.title('Adaptive Median Filter')
plt.axis('off')
plt.show()
(4)图像平滑
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from skimage import util
# 读取原始图像
img = cv.imread('./imagedata/cameraman.tif', 0)
if img is not None:
# 添加高斯噪声并转换为8位无符号整数
img_noise = util.random_noise(img, mode='gaussian', var=0.01)
img_noise = util.img_as_ubyte(img_noise)
# 应用不同的滤波技术
img_result1 = cv.bilateralFilter(img_noise, d=9, sigmaColor=50, sigmaSpace=100)
img_result2 = cv.blur(img_noise, ksize=(3,3))
img_result3 = cv.blur(img_noise, ksize=(15,15))
img_result4 = cv.GaussianBlur(img_noise, (3,3), sigmaX=0, sigmaY=0)
img_result5 = cv.GaussianBlur(img_noise, (15,15), sigmaX=0, sigmaY=0)
# 显示图像和标题
plt.figure(figsize=(10, 15)) # 调整图像显示大小
plt.subplot(4, 2, 1)
plt.imshow(img, cmap='gray', vmin=0, vmax=255)
plt.title('Original')
plt.axis('off')
plt.subplot(4, 2, 2)
plt.imshow(img_noise, cmap='gray', vmin=0, vmax=255)
plt.title('Gaussian Noise')
plt.axis('off')
plt.subplot(4, 2, 3)
plt.imshow(img_result1, cmap='gray', vmin=0, vmax=255)
plt.title('Bilateral Filter')
plt.axis('off')
plt.subplot(4, 2, 4)
plt.imshow(img_result2, cmap='gray', vmin=0, vmax=255)
plt.title('Blur (3x3)')
plt.axis('off')
plt.subplot(4, 2, 5)
plt.imshow(img_result3, cmap='gray', vmin=0, vmax=255)
plt.title('Blur (15x15)')
plt.axis('off')
plt.subplot(4, 2, 6)
plt.imshow(img_result4, cmap='gray', vmin=0, vmax=255)
plt.title('Gaussian Blur (3x3)')
plt.axis('off')
plt.subplot(4, 2, 7)
plt.imshow(img_result5, cmap='gray', vmin=0, vmax=255)
plt.title('Gaussian Blur (15x15)')
plt.axis('off')
plt.show()
(5)图像锐化
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 定义拉普拉斯算子
klap4 = np.array([[0, -1, 0],
[-1, 4, -1],
[0, -1, 0]])
klap8 = np.array([[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]])
# 对图像进行高斯平滑
img_smooth = cv2.GaussianBlur(img, ksize=(5, 5), sigmaX=0, sigmaY=0)
# 使用filter2D函数对图像进行卷积操作
img_klap4 = cv2.filter2D(img_smooth, -1, kernel=klap4)
img_klap8 = cv2.filter2D(img_smooth, -1, kernel=klap8)
# 对图像进行锐化处理
alpha = 1.5
img_sharpen4 = cv2.addWeighted(img, 1, img_klap4, -1 * alpha, 0, dtype=cv2.CV_8U)
img_sharpen8 = cv2.addWeighted(img, 1, img_klap8, -1 * alpha, 0, dtype=cv2.CV_8U)
# 创建一个大小为12x6的图像窗口,展示原始图像、平滑后的图像、两种拉普拉斯算子处理后的图像
plt.figure(figsize=(12, 6))
# 显示原始图像
plt.subplot(3, 2, 1)
plt.imshow(img, vmin=0, vmax=255, cmap='gray')
plt.title('Original')
plt.axis('off')
# 显示平滑后的图像
plt.subplot(3, 2, 2)
plt.imshow(img_smooth, vmin=0, vmax=255, cmap='gray')
plt.title('Smoothed')
plt.axis('off')
# 显示拉普拉斯算子处理后的图像(4邻域)
plt.subplot(3, 2, 3)
plt.imshow(img_klap4, vmin=0, vmax=255, cmap='gray')
plt.title('Laplacian 4')
plt.axis('off')
# 显示锐化后的图像(4邻域)
plt.subplot(3, 2, 4)
plt.imshow(img_sharpen4, vmin=0, vmax=255, cmap='gray')
plt.title('Sharpened 4')
plt.axis('off')
# 显示拉普拉斯算子处理后的图像(8邻域)
plt.subplot(3, 2, 5)
plt.imshow(img_klap8, vmin=0, vmax=255, cmap='gray')
plt.title('Laplacian 8')
plt.axis('off')
# 显示锐化后的图像(8邻域)
plt.subplot(3, 2, 6)
plt.imshow(img_sharpen8, vmin=0, vmax=255, cmap='gray')
plt.title('Sharpened 8')
plt.axis('off')
plt.show()
(6)对图像的感兴趣区域进行平滑模糊
from skimage import io, morphology, filters
import matplotlib.pyplot as plt
# 读取原始图像和掩模图像
img = io.imread('./imagedata/lena_gray.bmp')
img_mask = io.imread('./imagedata/lena_mask.png')
img_result = img.copy()
# 定义形态学操作的结构元素
selem = morphology.square(25)
# 使用均值滤波器计算感兴趣区域内的均值
img_roi = filters.rank.mean(img, footprint=selem, mask=img_mask)
# 将感兴趣区域内的均值作为修复后的像素值
img_result[img_mask > 0] = img_roi[img_mask > 0]
# 创建一个大小为12x8的图像窗口,展示原始图像、掩模图像和处理后的图像
plt.figure(figsize=(12, 8))
# 显示原始图像
plt.subplot(1, 3, 1)
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.axis('off')
# 显示掩模图像
plt.subplot(1, 3, 2)
plt.imshow(img_mask, cmap='gray')
plt.title('Mask Image')
plt.axis('off')
# 显示处理后的图像
plt.subplot(1, 3, 3)
plt.imshow(img_result, cmap='gray')
plt.title('Processed Image')
plt.axis('off')
plt.show()