数字图像处理3——基于空域滤波的图像增强

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()

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值