从opencv-python入门opencv--图像处理之图像滤波

时间:2024-11-18 15:56:54

从opencv-python入门opencv--图像处理之图像滤波

  • 一、文章介绍
  • 二、滤波器原理简述
  • 三、 cv.filter2D()
    • 1、参数说明
    • 2、公式
    • 3、代码
    • 4、效果
  • 四、 cv.blur()
    • 1、参数详解
    • 2、公式
    • 3、代码
  • 五、cv.boxFilter()
    • 1、参数
    • 2、公式
    • 3、代码
  • 六、 cv.GaussianBlur()和cv.bilateralFilter()
    • 1、cv.GaussianBlur()参数详解
    • 2、cv.bilateralFilter()参数详解
    • 3、双边滤波原理简述
    • 4、高斯滤波和双边滤波代码及效果对比
  • 七、cv.medianBlur()
    • 1、参数详解
    • 2、代码及效果

一、文章介绍

本文主要介绍经典的图像滤波器,包括均值滤波、中值滤波、高斯滤波和双边滤波。
涉及的opencv-python函数有cv.filter2D()、 cv.boxFilter()、cv.GaussianBlur()、cv.blur()和cv.bilateralFilter等。
opencv中各个滤波器效果如下:

二、滤波器原理简述

在百度百科中,图像滤波的定义如下:
图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。

跟一维滤波相同,图像也可以设计低通滤波器、高通滤波器进行边缘查找以及噪声消除等。使用的滤波参数为二维的卷积核。
图像处理中,常见的滤波器有均值滤波、中值滤波和高斯滤波等。
在图像中,低频的部分是连续的平滑结构,高频部分是边缘等突兀的细节。使用均值、中值、高斯滤波主要是为了去除噪声,噪声属于高频部分,因此,这些滤波器本质上属于低通滤波器。而如果我们想要得到图像的边缘,使用一些边缘梯度算子,如果sobel算子、拉普拉斯算子等,这些本质上属于高通滤波器。

卷积原理:
使用一个矩阵(假设为 3 ∗ 3 3*3 33),如下图所示,扫过一张 5 ∗ 5 5*5 55的图像, 3 ∗ 3 3*3 33的矩阵和扫过的图像 3 ∗ 3 3*3 33的区域每一个像素点对应相乘再相加,得到一个新的像素点的值,为了防止卷积后图像变小,卷积操作都会在边缘补0,比如3*3的卷积核,在图像周围补1个0像素,对于 k ∗ k k*k kk大小的卷积核,图像补零个数的公式为:
p = k − 1 2 p=\frac{k-1}{2} p=2k1
其中,p为四周补零的个数,k为卷积核的尺寸。
在这里插入图片描述

三、 cv.filter2D()

在这里插入图片描述

1、参数说明

(1)src
意义:输入图像,可以是单通道或多通道的图像。
类型:numpy.ndarray
(2)ddepth
意义:输出图像的深度(数据类型)。可以是以下值之一:
cv.CV_8U:无符号8位整型
cv.CV_16S:有符号16位整型
cv.CV_32F:32位浮点型
cv.CV_64F:64位浮点型
-1:与输入图像相同的深度
类型:整数
(3)kernel
意义:卷积核(滤波器),是一个二维数组,定义了如何对图像进行卷积操作。核的大小通常是奇数(如3x3、5x5等),并且可以是任意形状。
类型:numpy.ndarray
(4)anchor
意义:卷积核的锚点,指定卷积核的中心位置。默认值为 (-1, -1),表示卷积核的中心点是其几何中心。如果你想要改变锚点,可以设置为具体的坐标。
类型:元组或 None
(5)delta
意义:在卷积结果上添加的值。可以用于调整输出图像的亮度。例如,如果你想在每个像素值上加一个常数,可以通过这个参数实现。
类型:标量(数值)
(6)borderType
意义:边界类型,用于处理图像边界。当卷积核超出图像边界时,如何处理这些区域。常用的边界类型包括:
cv.BORDER_CONSTANT:用常数填充边界
cv.BORDER_REPLICATE:复制边界像素
cv.BORDER_REFLECT:反射边界像素
cv.BORDER_REFLECT_101:反射边界像素(不包括最外层)
cv.BORDER_WRAP:循环边界
cv.BORDER_DEFAULT:默认边界类型
类型:整数
(7)dst
意义:输出图像,经过卷积操作后生成的图像。输出图像的尺寸和深度根据输入图像和卷积核的大小以及指定的边界类型而定。
类型:numpy.ndarray

2、公式

d s t ( x , y ) = ∑ 0 < = x ′ < k e r n e l . c o l s ; 0 < = y ′ < k e r n e l . r o w s k e r n e l ( x ′ , y ′ ) ∗ s r c ( x + x ′ − a n c h o r . x , y + y ′ − a n c h o r . y ) dst(x,y)=\sum_{0<=x^{'}<kernel.cols;0<=y^{'}<kernel.rows}kernel(x^{'},y^{'})*src(x+x^{'}-anchor.x,y+y^{'}-anchor.y) dst(x,y)=0<=x<kernel.cols;0<=y<kernel.rowskernel(x,y)src(x+xanchor.x,y+yanchor.y)
其中, k e r n e l ( x ′ , y ′ ) kernel(x^{'},y^{'}) kernel(x,y)表示卷积核的系数, s r c src src表示原图像, a n c h o r anchor anchor表示锚点的坐标。

3、代码

设计如下滤波核:
1 9 [ 1 1 1 1 1 1 1 1 1 ] (3) \frac{1}{9} \left[ \begin{matrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{matrix} \right] \tag{3} 91 111111111 (3)
相当于 3 ∗ 3 3*3 33的均值滤波。
代码如下:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('data\squirrel_cls_noise.png')
kernel = np.ones((3,3),np.float32)
dst = cv.filter2D(img,-1,kernel)
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(dst),plt.title('Averaging')
plt.xticks([]), plt.yticks([])
plt.show()

4、效果

在这里插入图片描述

四、 cv.blur()

在这里插入图片描述

1、参数详解

(1)src
意义:输入图像,可以是单通道或多通道的图像。
类型:numpy.ndarray
(2)ksize
意义:模糊的内核大小,通常是一个元组 (宽度, 高度),表示模糊区域的大小。内核大小必须是正奇数(例如:(3, 3)、(5, 5) 等)。
类型:元组或整数
注意:如果传入一个整数 k,则会被解释为 (k, k),即宽度和高度相同。
(3)anchor
意义:内核的锚点,指定模糊内核的中心位置。默认值为 (-1, -1),表示内核的中心是其几何中心。如果你想要改变锚点,可以设置为具体的坐标。
类型:元组或 None
(4)borderType
意义:边界类型,用于处理图像边界。当模糊内核超出图像边界时,如何处理这些区域。常用的边界类型包括:
cv.BORDER_CONSTANT:用常数填充边界
cv.BORDER_REPLICATE:复制边界像素
cv.BORDER_REFLECT:反射边界像素
cv.BORDER_REFLECT_101:反射边界像素(不包括最外层)
cv.BORDER_WRAP:循环边界
cv.BORDER_DEFAULT:默认边界类型
类型:整数
(5)输出参数dst
意义:输出图像,经过模糊处理后的结果。
类型:numpy.ndarray

2、公式

k = 1 k s i z e . w i d t h ∗ k s i z e . h e i g h t [ 1 1 1 . . . 1 1 1 1 . . . 1 . . . . . . . . . . . . 1 1 1 1 . . . 1 ] (3) k=\frac{1}{ksize.width*ksize.height} \left[ \begin{matrix} 1 & 1 & 1 &...&1\\ 1 & 1 & 1 &...&1\\ ... & ... & ...&...&1\\ 1 & 1 & 1&...&1 \end{matrix} \right] \tag{3} k=ksize.widthksize.height1 11...111...111...1............1111 (3)

3、代码

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('data\squirrel_cls_noise.png')
blur = cv.blur(img,(3,3))
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()

五、cv.boxFilter()

在这里插入图片描述
cv.boxFilter()也是用于均值滤波的函数,相比于cv.blur(),其 可以处理不同的深度,并且可以选择是否归一化输出。

1、参数

(1)src: 输入图像,类型为 numpy.ndarray。
(2)ddepth: 输出图像的深度。可以是 cv.CV_8U、cv.CV_32F 等。如果设置为 -1,则输出图像的深度与输入图像相同。
(3)ksize: 模糊内核的大小,必须是正奇数,例如 (3, 3)、(5, 5) 等。
(4)anchor: 内核的锚点,默认值为 (-1, -1),表示内核的中心。
(5)normalize: 布尔值,指示是否对输出进行归一化。默认值为 True,表示对内核进行归一化处理。
(6)borderType: 边界处理方式,可以选择不同的边界类型,如 cv.BORDER_CONSTANT、cv.BORDER_REPLICATE 等。

2、公式

k = α [ 1 1 1 . . . 1 1 1 1 . . . 1 . . . . . . . . . . . . 1 1 1 1 . . . 1 ] k=\alpha \left[ \begin{matrix} 1 & 1 & 1 &...&1\\ 1 & 1 & 1 &...&1\\ ... & ... & ...&...&1\\ 1 & 1 & 1&...&1 \end{matrix} \right] k=