penCV轻松入门_面向python(第七章 图像平滑处理)

图像平滑处理

图像的平滑处理: 尽量保留图像原有信息的情况下,过滤掉图像内部的噪声;图像平滑处理会对图像中与周围像素点的像素值差异较大 的像素点进行处理,将其值调整为周围 像素点像素值的近似值

均值滤波

均值滤波 是指用当前像素点周围 N ⋅ N N·N N⋅N个像素值的均值 来代替当前像素值。使用该方法遍历处理图像内的每一个像素点,即可完成整幅图像的均值滤波。

针对边缘像素点 ,可以只取图像内存在的周围邻域点的像素值均值。

除此以外,还可以扩展当前图像的周围像素点。完成图像边缘扩展后,可以在新增的行列内填充不同的像素值。在此基础上,再针对 9×7的原始图像计算其 5×5 邻域内像素点的像素值均值。

根据上述运算,针对每一个像素点,都是与一个内部值均为 1/25 的 5×5 矩阵相乘,得到均值滤波的计算结果

矩阵一般化:

右侧的矩阵被称为卷积核,一般形式为:

  • M 和 N 分别对应高度和宽度

函数语法

均值滤波的函数是 cv2.blur(),其语法格式为:
dst = cv2.blur( src, ksize, anchor, borderType )

  • dst 是返回值,表示进行均值滤波后得到的处理结果。
  • src 是需要处理的图像,即原始图像。它可以有任意数量的通道,并能对各个通道独立处理。图像深度应该是 CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F 中的一种。
  • ksize 是滤波核的大小。滤波核大小是指在均值处理过程中,其邻域图像的高度和宽度, N ∗ M N*M N∗M的邻域。
  • anchor 是锚点,其默认值是(-1, -1),表示当前计算均值的点位于核的中心点位置。该值使用默认值即可,在特殊情况下可以指定不同的点作为锚点。
  • borderType 是边界样式,该值决定了以何种方式处理边界。

通常情况下,使用均值滤波函数时,对于锚点 anchor 和边界样式 borderType,直接采用其默认值即可。

读取一幅噪声图像,使用函数 cv2.blur()对图像进行均值滤波处理,得到去噪图像,并显示原始图像和去噪图像。

python 复制代码
import cv2  
img = cv2.imread("lena.jpg")  
rst = cv2.blur(img,(5,5))  
cv2.imshow("original",img)  
cv2.imshow("result",rst)  
cv2.waitKey()  
cv2.destroyAllWindows()

针对噪声图像,使用不同大小的卷积核对其进行均值滤波,并显示均值滤波的情况。

python 复制代码
import cv2  
img = cv2.imread("lena.jpg")  
rst1 = cv2.blur(img,(5,5))  
rst2 = cv2.blur(img,(30,30))  
cv2.imshow("original",img)  
cv2.imshow("result5",rst1)  
cv2.imshow("result30",rst2)  
cv2.waitKey()  
cv2.destroyAllWindows()

方框滤波

在方框滤波中,可以自由选择是否对均值滤波的结果进行归一化 ,即可以自由选择滤波结果是邻域像素值之和的平均值 ,还是邻域像素值之和

现方框滤波的函数是 cv2.boxFilter(),其语法格式为:
dst = cv2.boxFilter( src, ddepth, ksize, anchor, normalize, borderType )

  • dst 是返回值,表示进行方框滤波后得到的处理结果。
  • src 是需要处理的图像,即原始图像。它能够有任意数量的通道,并能对各个通道独立处理。图像深度应该是 CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F 中的一种。
  • ddepth 是处理结果图像的图像深度,一般使用-1 表示与原始图像使用相同的图像深度。
  • ksize 是滤波核的大小。
  • anchor 是锚点,其默认值是(-1, -1),表示当前计算均值的点位于核的中心点位置。该值使用默认值即可,在特殊情况下可以指定不同的点作为锚点。
  • normalize 表示在滤波时是否进行归一化(这里指将计算结果规范化为当前像素值范围内的值)处理,该参数是一个逻辑值,可能为真(值为 1)或假(值为 0)。
    • 当参数 normalize=1 时,表示要进行 归一化处理,要用邻域像素值的和除以面积
    • 当参数 normalize=0 时,表示不需要 进行归一化处理,直接使用邻域像素值的和
      当 normalize=0 时,因为不进行归一化处理,因此滤波得到的值很可能超过 当前像素值范围的最大值,从而被截断为最大值。这样,就会得到一幅纯白色的图像。
  • borderType 是边界样式,该值决定了以何种方式处理边界。
    通常情况下,在使用方框滤波函数时,对于参数 anchor、normalize 和 borderType,直接采用其默认值即可。

针对噪声图像,对其进行方框滤波,显示滤波结果。

python 复制代码
import cv2  
img = cv2.imread("lena.jpg")  
rst = cv2.boxFilter(img,-1,(5,5))  
cv2.imshow("original",img)  
cv2.imshow("result",rst)  
cv2.waitKey()  
cv2.destroyAllWindows()

针对噪声图像,在方框滤波函数 cv2.boxFilter()内将参数 normalize 的值设置为 0,显示滤波处理结果。

python 复制代码
import cv2  
img = cv2.imread("lena.jpg")  
rst = cv2.boxFilter(img,-1,(5,5) , normalize=0)  
cv2.imshow("original",img)  
cv2.imshow("result",rst)  
cv2.waitKey()  
cv2.destroyAllWindows()

高斯滤波

在进行均值滤波和方框滤波时,其邻域内每个像素的权重是相等 的。在高斯滤波中,会将中心点的权重值加大,远离中心点的权重值减小,在此基础上计算邻域内各个像素值不同权重的和。

在高斯滤波中,核的宽度和高度可以不相同,但是它们都必须是奇数

高斯滤波的函数是 cv2.GaussianBlur(),该函数的语法格式是:
dst = cv2.GaussianBlur( src, ksize, sigmaX, sigmaY, borderType )

  • dst 是返回值,表示进行高斯滤波后得到的处理结果。
  • src 是需要处理的图像,即原始图像。它能够有任意数量的通道,并能对各个通道独立处理。图像深度应该是 CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F 中的一种。
  • ksize 是滤波核的大小。滤波核大小是指在滤波处理过程中其邻域图像的高度和宽度。需要注意,滤波核的值必须是奇数
  • sigmaX 是卷积核在水平方向上(X 轴方向)的标准差,其控制的是权重比例
  • sigmaY 是卷积核在垂直方向上(Y 轴方向)的标准差。如果将该值设置为 0,则只采用sigmaX 的值;如果 sigmaX 和 sigmaY 都是 0,则通过 ksize.width 和 ksize.height 计算得到。
    其中:
    • s i g m a X = 0.3 × [ ( k s i z e . w i d t h − 1 ) × 0.5 − 1 ] + 0.8 sigmaX = 0.3×[(ksize.width-1)×0.5-1] + 0.8 sigmaX=0.3×[(ksize.width−1)×0.5−1]+0.8
    • s i g m a Y = 0.3 × [ ( k s i z e . h e i g h t − 1 ) × 0.5 − 1 ] + 0.8 sigmaY = 0.3×[(ksize.height-1)×0.5-1] + 0.8 sigmaY=0.3×[(ksize.height−1)×0.5−1]+0.8
  • borderType 是边界样式,该值决定了以何种方式处理边界。
    在该函数中,sigmaY 和 borderType 是可选参数。sigmaX 是必选参数,但是可以将该参数设置为 0,让函数自己去计算 sigmaX 的具体值。

对噪声图像进行高斯滤波,显示滤波的结果。

python 复制代码
import cv2  
img  = cv2.imread("D:\openCV\lena.jpg")  
rst = cv2.GaussianBlur(img,(5,5),0,0)  
cv2.imshow("original",img)  
cv2.imshow("result",rst)  
cv2.waitKey()  
cv2.destroyAllWindows()

中值滤波

用邻域内所有像素值的中间值 来替代当前像素点的像素值。

中值滤波会取当前像素点及其周围临近像素点(一共有奇数 个像素点)的像素值,将这些像素值排序 ,然后将位于中间位置的像素值作为当前像素点的像素值。

中值滤波的函数是 cv2.medianBlur(),其语法格式如下:
dst = cv2.medianBlur( src, ksize)

式中:

  • dst 是返回值,表示进行中值滤波后得到的处理结果。
  • src 是需要处理的图像,即源图像。它能够有任意数量的通道,并能对各个通道独立处理。图像深度应该是 CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F 中的一种。
  • ksize 是滤波核的大小。滤波核大小是指在滤波处理过程中其邻域图像的高度和宽度。需要注意,核大小必须是比 1 大的奇数,比如 3、5、7 等。

用函数 cv2.medianBlur()实现中值滤波

python 复制代码
import cv2  
img = cv2.imread("lena.jpg")  
rst = cv2.medianBlur(img,3)  
cv2.imshow("original",img)  
cv2.imshow("result",rst)  
cv2.waitKey()  
cv2.destroyAllWindows()

双边滤波

前述滤波方式基本都只考虑了空间的权重信息,这种情况计算起来比较方便,但是在边缘信息的处理上存在较大的问题。

在均值滤波、方框滤波、高斯滤波中,都会计算边缘上各个像素点的加权平均值,从而模糊边缘信息;处理过程单纯地考虑空间信息,造成了边界模糊和部分信息的丢失。

双边滤波在计算某一个像素点的新值时,不仅考虑距离信息(距离越远,权重越小),还考虑色彩信息(色彩差别越大,权重越小)。双边滤波综合考虑距离和色彩的权重 结果,既能够有效地去除噪声,又能够较好地保护边缘信息;当处在边缘时,与当前点色彩相近的像素点(颜色距离很近)会被给予较大的权重值;而与当前色彩差别较大的像素点(颜色距离很远)会被给予较小的权重值(极端情况下权重可能为 0,直接忽略该点),这样就保护了边缘信息。

双边滤波的函数是 cv2.bilateralFilter(),该函数的语法是:
dst = cv2.bilateralFilter( src, d, sigmaColor, sigmaSpace, borderType )

  • dst 是返回值,表示进行双边滤波后得到的处理结果。
  • src 是需要处理的图像,即原始图像。它能够有任意数量的通道,并能对各个通道独立处理。图像深度应该是 CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F 中的一种。
  • d 是在滤波时选取的空间距离参数,这里表示以当前像素点为中心点的直径。如果该值为非正数,则会自动从参数 sigmaSpace 计算得到。如果滤波空间较大(d>5),则速度较慢。因此,在实时应用中,推荐 d=5。对于较大噪声的离线滤波,可以选择 d=9。
  • sigmaColor 是滤波处理时选取的颜色差值范围,该值决定了周围哪些像素点能够参与到滤波中来。与当前像素点的像素值差值小于 sigmaColor 的像素点,能够参与到当前的滤波中。该值越大,就说明周围有越多的像素点可以参与到运算中。该值为 0 时,滤波失去意义;该值为 255 时,指定直径内的所有点都能够参与运算。
  • sigmaSpace 是坐标空间中的 sigma 值。它的值越大,说明有越多的点能够参与到滤波计算中来。当 d>0 时,无论 sigmaSpace 的值如何,d 都指定邻域大小;否则,d 与 sigmaSpace的值成比例。
  • borderType 是边界样式,该值决定了以何种方式处理边界。一般情况下,不需要考虑该值,直接采用默认值即可。

针对噪声图像,分别对其进行高斯滤波和双边滤波,比较不同滤波方式对边缘的处理结果是否相同。

python 复制代码
import cv2  
img = cv2.imread("billTest.jpg")  
rst_Gauss = cv2.GaussianBlur(img,(55,55),0,0)  
rst_bilateral = cv2.bilateralFilter(img,55,100,100)  
cv2.imshow("original",img)  
cv2.imshow("Gaussian",rst_Gauss)  
cv2.imshow("bilateral",rst_bilateral)  
cv2.waitKey()  
cv2.destroyAllWindows()

2D卷积

在 OpenCV 中,允许用户自定义卷积核实现卷积操作,使用自定义卷积核实现卷积操作的函数是 cv2.filter2D(),其语法格式为:
dst = cv2.filter2D( src, ddepth, kernel, anchor, delta, borderType )

式中:

  • dst 是返回值,表示进行方框滤波后得到的处理结果。
  • src 是需要处理的图像,即原始图像。它能够有任意数量的通道,并能对各个通道独立处理。图像深度应该是 CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F 中的一种。
  • ddepth 是处理结果图像的图像深度,一般使用-1 表示与原始图像使用相同的图像深度。
  • kernel 是卷积核 ,是一个单通道的数组。如果想在处理彩色图像时,让每个通道使用不同的核,则必须将彩色图像分解后使用不同的核完成操作。
  • anchor 是锚点,其默认值是(-1, -1),表示当前计算均值的点位于核的中心点位置。该值使用默认值即可,在特殊情况下可以指定不同的点作为锚点。
  • delta 是修正值,它是可选项。如果该值存在,会在基础滤波的结果上加上该值作为最终的滤波处理结果。
  • borderType 是边界样式,该值决定了以何种情况处理边界,通常使用默认值即可。
    在通常情况下,使用滤波函数 cv2.filter2D()时,对于参数锚点 anchor、修正值 delta、边界样式 borderType,直接采用其默认值即可。

自定义一个卷积核,通过函数 cv2.filter2D()应用该卷积核对图像进行滤波操作,并显示滤波结果。

python 复制代码
import cv2  
import numpy as np  
img = cv2.imread("lena.jpg")  
kernel =np.ones((9,9),np.float32)/81  
rst = cv2.filter2D(img,-1,kernel)  
cv2.imshow("original",img)  
cv2.imshow("Gaussian",rst)  
cv2.waitKey()  
cv2.destroyAllWindows()
相关推荐
骥龙3 小时前
1.1、开篇:AI如何重塑网络安全攻防格局?
人工智能·安全·web安全
微学AI3 小时前
国产数据库替代MongoDB的技术实践过程:金仓多模数据库在电子证照系统中的深度应用
数据库·人工智能·1024程序员节
gddkxc3 小时前
AI驱动的客户管理:悟空AI CRM的核心功能与优势
人工智能
狂奔solar4 小时前
Apple 开源FastVLM:AI看图说话更快更准
人工智能
星空的资源小屋4 小时前
Antares SQL,一款跨平台开源 SQL 客户端
数据库·人工智能·pdf·开源·电脑·excel·1024程序员节
集和诚JHCTECH4 小时前
赋能边缘智能:BRAV-7722搭载全新Edge BMC模块,开启远程运维新纪元!
人工智能·嵌入式硬件
WLJT1231231235 小时前
生活电器:重构家居体验的产业变革与发展探索
大数据·人工智能·科技·生活
~~李木子~~5 小时前
聚类算法实战:从 KMeans 到 DBSCAN
人工智能·机器学习·支持向量机