【OpenCV图像处理6】滤波器(上)

简介: 【OpenCV图像处理6】滤波器(上)

六、滤波器

1、卷积

1.1 什么是图像卷积

图像卷积就是卷积核在图像上按行滑动遍历像素时不断的相乘求和的过程。

1.2 步长

步长就是卷积核在图像上移动的步幅。

上面的例子中卷积核每次移动一个像素步长的结果,如果将这个步长修改为2,结果会如何?

为了充分扫描图像,步长一般设为1。

1.3 padding

从上面例子中我们发现,卷积之后图像的长宽会变小,如果要保持图像大小不变,我们需要在图像周围填充0,padding指的就是填充0的圈数。

我们可以通过公式计算出需要填充0的圈数:

  • 输入体积大小:H1 * W1 * D1
  • 四个超参数:
  • Filter数量K
  • Filter大小F
  • 步长S
  • 零填充大小P
  • 输出体积大小:H2 * W2 * D2
  • H2 = (H1 - F + 2P) / S + 1
  • W2 = (W1 - F + 2P) / S +1
  • D2 = K

如果要保持卷积之后图像大小不变,可以得出等式:(N + 2P - F + 1) = N 从而可以推导出 P = F − 1 2 P = \frac {F-1} {2}P=2F1

1.4 卷积核的大小

图像卷积中,卷积核一般为奇数,比如 3 * 3,5 * 5,7 * 7,为什么一般是奇数呢?出于以下两个方面的考虑:

1、根据上面padding的计算公式,如果要保持图像大小不变,采用偶数卷积核的话,比如 4 * 4,将会出现填充1.5圈零的情况。

2、奇数维度的滤波器有中心,便于指出滤波器的位置,即OpenCV卷积中的锚点。

1.5 卷积案例

filter2D()用法:

cv2.filter2D(src, ddepth, kernel, dst, anchor, delta, borderType)

参数说明:

  • ddepth:卷积之后图像的位深,即卷积之后图像的数据类型,一般设为-1,表示和原图像类型一致。
  • kernel:卷积核大小,用元组或者ndarray表示,要求数据类型必须是float型。
  • anchor:锚点,即卷积核的中心点,是可选参数,默认是(-1, -1)。
  • delta:可选参数,表示卷积之后额外加的一个值,相当于线性方程中的偏差,默认是0。
  • borderType:边界类型,一般不设置。

代码实现(锐化)

import cv2
import numpy as np
img = cv2.imread('../resource/r_cat.jpg')
# 相当于原始图像中的每个点都被平均了一下,所以图像变模糊了
# kernel = np.ones((5, 5), np.float32) / 25
# 突出轮廓
# kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
# 浮雕效果
# kernel = np.array([[-2, 1, 0], [-1, 1, 1], [0, 1, 2]])
# 锐化
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
dst = cv2.filter2D(img, -1, kernel)
cv2.imshow('img', np.hstack((img, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

2、方盒滤波和均值滤波

2.1 方盒滤波

boxFilter()用法:

cv2.boxFilter(src, ddepth, ksize, dst, anchor, normalize, borderType)

参数说明:

  • ddepth:卷积之后图像的位深,即卷积之后图像的数据类型,一般设为-1,表示和原图像类型一致。
  • Ksize:方盒滤波卷积核大小

方盒滤波的卷积核形式如下:

  • 当 normalize = True 时,a = 1 / (W * H) 滤波器的宽高
  • 当 normalize = False 时,a = 1
  • 一般情况下都使用 normalize = True,这是 方盒滤波 等价于 均值滤波

代码实现:

import cv2
import numpy as np
img = cv2.imread('../resource/r_cat.jpg')
# 不用手动创建卷积核,只需要告诉方盒滤波,卷积核的大小是多少
dst = cv2.boxFilter(img, -1, (5, 5), normalize=True)
cv2.imshow('img', np.hstack((img, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

2.2 均值滤波

blur()用法:

cv2.blur(src, ksize, dst, anchorborderType)

参数说明:

  • anchorborderType:用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT

代码实现:

import cv2
import numpy as np
img = cv2.imread('../resource/r_cat.jpg')
dst = cv2.blur(img, (5, 5))
cv2.imshow('img', np.hstack((img, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

3、高斯滤波

要理解高斯滤波首先要知道什么是高斯函数:

高斯函数是符合高斯分布(也叫正态分布)数据的概率密度函数。

高斯函数的特点是以x轴某一点(这一点称为均值)为对称轴,越靠近中心数据发生的概率越高,最终形成一个两边平缓,中间陡峭的钟型(也被称为帽子)图形。

高斯函数的一般形式为:

高斯滤波就是使用符合高斯分布的卷积核对图像进行卷积操作,所以高斯滤波的重点是如何计算符合高斯分布的卷积核,即高斯模板

假定中心点的坐标是(0, 0),那么取距离它最近的8个点坐标,为了计算,需要设 定σ \sigmaσ 的值。假定 σ \sigmaσ = 1.5,则模糊半径为1的高斯模板如下:

我们可以观察到越靠近中心,数值越大,越边缘的数值越小,符合高斯分布的特点。

通过高斯函数计算出来的是概率分布函数,所以我们还要确保这九个点加起来为1,这九个点的权重总和等于0.4787147,因此,上面九个值还要分别除以0.4787147,得到最终的高斯模板。

注:有些整数高斯模板是在归一化后的高斯模板的基础上每个数除以左上角的值,然后取整。

有了卷积核,计算高斯滤波就简单了。假设现在有9个像素点,灰度值(0 ~ 255)的高斯滤波计算如下:

将这9个值加起来,就是中心点的高斯滤波的值。对所有点重复这个过程,就得到了高斯模糊后的图像。

GaussianBlur()用法:

cv2.GaussianBlur(src, ksize, sigmaX, dst, sigmaY, borderType)

参数说明:

  • ksize:高斯核的大小
  • sigmaX:X轴的标准差
  • sigmaY:Y轴的标准差,默认为0,这时 sigmaY = sigmaX
  • 如果没有指定sigma值,则会分别从ksize的宽度和高度中计算sigma
  • 选择不同的sigma值会得到不同的平滑效果,sigma越大,平滑效果越明显。

代码实现一: 模糊

import cv2
import numpy as np
img = cv2.imread('../resource/r_cat.jpg')
# dst = cv2.GaussianBlur(img, (9, 9), sigmaX=100)
# 如果不指定sigmaX,会使用ksize计算sigma
dst = cv2.GaussianBlur(img, (9, 9), sigmaX=0)
cv2.imshow('img', np.hstack((img, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

代码实现二: 去噪

import cv2
import numpy as np
img = cv2.imread('../resource/cv.webp')
dst = cv2.GaussianBlur(img, (5, 5), sigmaX=1)
cv2.imshow('img', np.hstack((img, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

4、中值滤波

中值滤波原理非常简单,假设有一个数组[1 5 5 6 7 8 9],取1其中的中间值(即中位数)作为卷积后的结果值即可。

中值滤波对胡椒噪音(也叫椒盐噪音)效果明显。

medianBlur()用法:

cv2.medianBlur(src, ksize, dst)

参数说明:

  • ksize:就是一个数字

代码实现:

import cv2
import numpy as np
img = cv2.imread('../resource/cv_noise.webp')
dst = cv2.medianBlur(img, 5)
cv2.imshow('img', np.hstack((img, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

目录
相关文章
|
28天前
|
算法 计算机视觉
基于qt的opencv实时图像处理框架FastCvLearn实战
本文介绍了一个基于Qt的OpenCV实时图像处理框架FastCvLearn,通过手撕代码的方式详细讲解了如何实现实时人脸马赛克等功能,并提供了结果展示和基础知识回顾。
基于qt的opencv实时图像处理框架FastCvLearn实战
|
19天前
|
机器学习/深度学习 算法 计算机视觉
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
44 2
WK
|
2月前
|
计算机视觉 Python
如何使用OpenCV进行基本图像处理
使用OpenCV进行基本图像处理包括安装OpenCV,读取与显示图像,转换图像颜色空间(如从BGR到RGB),调整图像大小,裁剪特定区域,旋转图像,以及应用图像滤镜如高斯模糊等效果。这些基础操作是进行更复杂图像处理任务的前提。OpenCV还支持特征检测、图像分割及对象识别等高级功能。
WK
39 4
|
5月前
|
人工智能 计算机视觉 Python
【OpenCV】计算机视觉图像处理基础知识(上)
【OpenCV】计算机视觉图像处理基础知识(上)
|
5月前
|
算法 计算机视觉
【OpenCV】计算机视觉图像处理基础知识(下)
【OpenCV】计算机视觉图像处理基础知识(下)
|
5月前
|
机器学习/深度学习 算法 Linux
使用OpenCV在Python中进行图像处理
使用OpenCV在Python中进行图像处理
|
5月前
|
算法 安全 机器人
最新版opencv4.9安装介绍,基本图像处理详解
最新版opencv4.9安装介绍,基本图像处理详解
269 0
|
5月前
|
机器学习/深度学习 API vr&ar
Qt, OpenCV与OpenGL协同作战:图像处理与三维图形界面的完美结合
Qt, OpenCV与OpenGL协同作战:图像处理与三维图形界面的完美结合
858 4
|
5月前
|
机器学习/深度学习 存储 算法
OpenCV与NumPy:图像处理中的黄金组合
【4月更文挑战第17天】OpenCV和NumPy是Python图像处理的两大利器,互补协作形成黄金组合。OpenCV专注计算机视觉,提供丰富算法,而NumPy擅长数值计算和数组操作。两者无缝对接,共同实现高效、灵活的图像处理任务。通过灰度化、二值化、边缘检测等案例,展示了它们的协同作用。未来,这一组合将在计算机视觉和机器学习领域发挥更大作用,解锁更多图像处理潜力。
|
5月前
|
编解码 算法 自动驾驶
探索OpenCV:图像处理的利器
探索OpenCV:图像处理的利器
56 0