【OpenCV实现平滑图像处理】

文章目录

概要

在图像处理中,低通滤波器是一种常用的技术,用于平滑、模糊或降低图像的噪音。这种滤波器通过去除图像中高频部分(即变化较快的部分)来实现这些效果。通过应用2D卷积操作,低通滤波器将每个像素的值与其周围像素的值进行加权平均,从而实现图像的平滑处理。

在实际应用中,我们可以定制不同类型的低通滤波器,例如平均滤波器、高斯滤波器等,根据需求选择合适的滤波器。平均滤波器将像素的值替换为其周围像素值的平均值,从而消除图像中的高频噪音。而高斯滤波器则使用高斯函数生成一个权重矩阵,将像素值进行加权平均,使得距离中心像素越远的像素权重越小,实现更加自然的平滑效果。

定制的低通滤波器可以根据图像特性进行调整,例如在面对强烈噪音时增加滤波器的大小,或者根据图像中对象的大小调整滤波器的标准差。这种灵活性使得低通滤波器在图像处理中具有广泛的应用,例如在计算机视觉中的目标检测、图像识别、医学图像处理等领域。

2D 卷积(图像过滤)

使用各种低通滤波平滑图像

将定制的过滤器应用在图像上(2D卷积)

OpenCV提供了一个非常有用的函数,即cv.filter2D,该函数允许我们将一个图像和一个自定义的核(也称为滤波器)进行卷积操作。举个例子,如果我们想在一幅图像上尝试平均滤波,我们可以使用一个简单的平均核,该核中的所有元素值相等,代表了平均操作。通过使用cv.filter2D函数,我们可以将这个平均核应用到图像上,从而实现平均滤波的效果。

这种滤波技术不仅可以用于去除图像中的噪声,还可以在图像处理任务中发挥关键作用,比如在边缘检测、图像增强和特征提取等领域。

一个 5 X 5 的平均滤波核如下所示:

保持这个核在像素上面,将被这个核覆盖的25个像素点的值求平均值,然后将这个平均值替换掉最中间那个像素点的值。然后将这个操作应用在图像的所有像素点上。

bash 复制代码
# 导入必要的库
import numpy as np  # 用于数值计算
import cv2 as cv     # OpenCV库,用于图像处理
import matplotlib.pyplot as plt  # 用于绘图和可视化

# 读取图像文件 'img.png'
img = cv.imread('img.png')

# 定义一个 5x5 的平均滤波核
kernel = np.ones((5, 5), np.float32) / 25

# 使用 cv2.filter2D 函数将图像与平均滤波核进行卷积
dst = cv.filter2D(img, -1, kernel)

# 绘制原始图像、平均滤波后的图像并显示
plt.subplot(121)  # 创建第一个子图
plt.imshow(img)    # 显示原始图像
plt.title('Original')  # 设置子图标题为 'Original'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.subplot(122)  # 创建第二个子图
plt.imshow(dst)    # 显示平均滤波后的图像
plt.title('Averaging')  # 设置子图标题为 'Averaging'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.show()  # 显示绘制好的图像

模糊图像(平滑图像)

图像处理中,模糊(或称平滑)图像是一种常见的操作,可以通过低通滤波器与图像进行卷积来实现。这个技术非常有效地去除图像中的噪声,因为它能够消除高频内容,比如噪声和边缘。然而,需要注意的是,模糊操作也会稍微模糊图像的边缘,尽管有一些特殊的模糊技术可以保持边缘的清晰度。

  1. 平均
    这是通过将图像与归一化框滤波器进行卷积完成的。它简单的将核下面的像素值求平均并覆盖中间的像素值。这个可以使用函数cv.blur() 或者 cv.boxFilter() 来实现。我们应该指定内核的高度和宽度。一个 3 X 3 的归一化框滤波器如下所示:

    Note: 如果你不想使用归一化框滤波器,那可以使用 cv.boxFilter。将 normalize=False 传入函数。
bash 复制代码
# 导入必要的库
import cv2 as cv  # OpenCV库,用于图像处理
import numpy as np  # 用于数值计算
from matplotlib import pyplot as plt  # 用于绘图和可视化

# 读取图像文件 'img.png'
img = cv.imread('img.png')

# 使用平均模糊(平滑)技术对图像进行处理,卷积核大小为 (5, 5)
blur = cv.blur(img, (5, 5))

# 绘制原始图像和模糊处理后的图像并显示
plt.subplot(121)  # 创建第一个子图
plt.imshow(img)    # 显示原始图像
plt.title('Original')  # 设置子图标题为 'Original'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.subplot(122)  # 创建第二个子图
plt.imshow(blur)   # 显示平均模糊后的图像
plt.title('Blurred')  # 设置子图标题为 'Blurred'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.show()  # 显示绘制好的图像

2.高斯滤波(Gaussian Blur)

在高斯滤波中,我们使用高斯核替代了盒(框)滤波器。这种滤波方法已经被集成在OpenCV的cv.GaussianBlur()函数中。在使用高斯滤波时,我们需要确定核的高度和宽度,这两个数值需要是正数且奇数。此外,我们还需要指定X和Y方向上的标准差(sigma X和sigma Y)。如果只确定了sigma X,那么sigma Y的值会被设置为与sigma X相同。如果两者都为0,那么它们的值会根据核的大小自动计算。

高斯滤波在去除图像中的高斯噪声方面非常有效。高斯核的权重分布使得中心像素周围的像素对平均值的贡献更大,这样可以更好地保留图像的细节。

bash 复制代码
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 读取图像文件 'img.png'
img = cv.imread('img.png')

# 使用高斯滤波(核大小为 5x5,标准差为 0,表示自动计算)
blur = cv.GaussianBlur(img, (5, 5), 0)

# 绘制原始图像和高斯滤波处理后的图像并显示
plt.subplot(121)  # 创建第一个子图
plt.imshow(img)    # 显示原始图像
plt.title('Original')  # 设置子图标题为 'Original'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.subplot(122)  # 创建第二个子图
plt.imshow(blur)   # 显示高斯滤波后的图像
plt.title('Blurred')  # 设置子图标题为 'Blurred'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.show()  # 显示绘制好的图像

中值模糊

中值模糊是一种特殊的滤波技术,它的原理是在核的覆盖区域内找到像素值的中间值,并将中间值赋给核中心的像素点。与其他滤波方法不同,中值滤波不是使用计算得到的新值替代中心像素,而是直接采用该区域内的中间值。

在OpenCV中,中值滤波可以通过cv.medianBlur()函数实现。与其他滤波方法类似,中值滤波的核的大小也应该是正数和奇数。这种滤波技术在处理图像中的椒盐噪声(图像中随机出现的亮或暗像素点)非常有效。因为它通过选择中间值,可以避免受到噪声的干扰。

bash 复制代码
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 读取图像文件 'img.png'
img = cv.imread('img.png')

# 使用中值模糊(核大小为 5x5)
blur = cv.medianBlur(img, 5)

# 绘制原始图像和中值模糊处理后的图像并显示
plt.subplot(121)  # 创建第一个子图
plt.imshow(img)    # 显示原始图像
plt.title('Original')  # 设置子图标题为 'Original'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.subplot(122)  # 创建第二个子图
plt.imshow(blur)   # 显示中值模糊后的图像
plt.title('Blurred')  # 设置子图标题为 'Blurred'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.show()  # 显示绘制好的图像

双边过滤

双边过滤在需要处理噪声但又需要保持图像边缘清晰的场景中非常有效。它的操作由cv.bilateralFilter()函数完成。相较于其他滤波器,这个操作相对较慢。我们已经了解到,高斯滤波器通过获取像素周围的邻域并计算其高斯加权平均值来进行操作。高斯滤波仅仅是一个空间函数,即在滤波时只考虑相邻像素的值。它不会检查像素值是否接近,也不会检查一个像素是否是边缘像素。因此,它可能会模糊掉一些我们希望保留的边缘细节。

双边滤波在空间上同样使用高斯滤波器,但还引入了一个像素强度差异的高斯滤波器。空间上的高斯函数确保只有附近的像素被用来进行模糊处理,而像素差异高斯函数确保只有与中心像素具有相似强度的像素被模糊处理。因此,它可以保持图像边缘的清晰度,因为边缘处的像素会有较大的强度变化,不容易被平滑掉。这种特性使得双边滤波在同时保持图像细节和去除噪声的需求下表现出色。

bash 复制代码
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 读取图像文件 'img.png'
img = cv.imread('img.png')

# 使用双边过滤(参数:d表示领域直径,sigmaColor表示颜色空间标准差,sigmaSpace表示坐标空间标准差)
blur = cv.bilateralFilter(img, d=9, sigmaColor=75, sigmaSpace=75)

# 绘制原始图像和双边过滤处理后的图像并显示
plt.subplot(121)  # 创建第一个子图
plt.imshow(img)    # 显示原始图像
plt.title('Original')  # 设置子图标题为 'Original'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.subplot(122)  # 创建第二个子图
plt.imshow(blur)   # 显示双边过滤后的图像
plt.title('Bilateral Filtered')  # 设置子图标题为 'Bilateral Filtered'
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

plt.show()  # 显示绘制好的图像

小结

总之,低通滤波器通过2D卷积操作,能够有效平滑图像、去除噪音、提高图像质量,为各种图像处理任务提供了重要支持。通过定制不同类型的滤波器,我们能够根据具体需求进行图像处理,获得更清晰、更有信息量的图像结果。

相关推荐
荒古前17 分钟前
龟兔赛跑 PTA
c语言·算法
Colinnian21 分钟前
Codeforces Round 994 (Div. 2)-D题
算法·动态规划
岑梓铭21 分钟前
(CentOs系统虚拟机)Standalone模式下安装部署“基于Python编写”的Spark框架
linux·python·spark·centos
边缘计算社区25 分钟前
首个!艾灵参编的工业边缘计算国家标准正式发布
大数据·人工智能·边缘计算
用户00993831430127 分钟前
代码随想录算法训练营第十三天 | 二叉树part01
数据结构·算法
shinelord明30 分钟前
【再谈设计模式】享元模式~对象共享的优化妙手
开发语言·数据结构·算法·设计模式·软件工程
游客52035 分钟前
opencv中的各种滤波器简介
图像处理·人工智能·python·opencv·计算机视觉
一位小说男主36 分钟前
编码器与解码器:从‘乱码’到‘通话’
人工智能·深度学习
დ旧言~37 分钟前
专题八:背包问题
算法·leetcode·动态规划·推荐算法