0%

OpenCV(七)-滤波器

一、图像滤波

滤波的作用:
一副图像==通过滤波器==得到==另一幅图像==
其中滤波器又称为==卷积核==,滤波的过程称为==卷积==

image-20241107155955301

image-20241107160007913

二、卷积相关概念

2.1、卷积核的大小

卷积核一般为==奇数==,如3x3,5x5,7x7等
一方面是增加==padding==的原因
另一方面是保证==锚点==在中间,防止位置发生偏移

在深度学习中,卷积核越大,看到的信息(==感受野==)越多,提取的==特征越好==,同时计算量也就越大

2.2、锚点

image-20241107160751205

2.3、边界扩充

当卷积核大于1且不进行边界扩充,输出尺寸将相应缩小

当卷积核以标准方式进行边界扩充,则输出数据的空间大小与输入相等

image-20241107160906228

image-20241107160916733

2.4、步长

image-20241107160945609

步长为2

三、实战图像卷积

image-20241107161122621

1
2
3
4
5
6
7
8
9
10
(function)
def filter2D(
src: MatLike,
ddepth: int, # 位深
kernel: MatLike, # 卷积核
dst: MatLike | None = ...,
anchor: Point = ..., # 锚点
delta: float = ...,
borderType: int = ...
) -> MatLike: ...

image-20241107162224860

1
2
3
4
5
6
7
8
9
10
11
12
import cv2
import numpy as np

img = cv2.imread('dog.jpeg')

kernal = np.ones((5,5), np.float32) / 25

dst = cv2.filter2D(img, -1, kernal)

cv2.imshow('dst', dst)
cv2.imshow('img', img)
cv2.waitKey(0)

可以看出滤波之后,线条变模糊了,眼睛变暗了

image-20241107162500753

四、方盒滤波与均值滤波

image-20241107162849123

image-20241107162945808

image-20241107162952541

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(function)
def boxFilter(
src: MatLike,
ddepth: int,
ksize: Size,
dst: MatLike | None = ...,
anchor: Point = ...,
normalize: bool = ...,
borderType: int = ...
) -> MatLike: ...

(function) def blur(
src: MatLike,
ksize: Size,
dst: MatLike | None = ...,
anchor: Point = ...,
borderType: int = ...
) -> MatLike
1
2
3
4
5
6
7
8
9
10
11
12
import cv2
import numpy as np

img = cv2.imread('dog.jpeg')

dst = cv2.blur(img, (5,5))

cv2.imshow('dst', dst)
cv2.imshow('img', img)
cv2.waitKey(0)

# 效果图和上一节一样,均值滤波

五、高斯滤波

image-20241107163554151

image-20241107163625762

image-20241107163638106

中间比重高,四边权重低

1
2
3
4
5
6
7
8
9
10
def GaussianBlur(
src: MatLike,
ksize: Size,
sigmaX: float, # 越大越模糊
dst: MatLike | None = ...,
sigmaY: float = ...,
borderType: int = ...
) -> MatLike: ...

# 高斯滤波解决的是噪点
1
2
3
4
5
6
7
8
9
10
import cv2
import numpy as np

img = cv2.imread('./gaussian.png')

dst = cv2.GaussianBlur(img, (5,5), sigmaX=1)

cv2.imshow('dst', dst)
cv2.imshow('img', img)
cv2.waitKey(0)

可以看出右侧的噪点少了很多,但是边缘也变模糊了

image-20241107164528763

六、中值滤波

image-20241107164709281

优点:对==胡椒噪音==效果明显

1
2
3
4
5
def medianBlur(
src: MatLike,
ksize: int,
dst: MatLike | None = ...
) -> MatLike: ...
1
2
3
4
5
6
7
8
9
10
import cv2
import numpy as np

img = cv2.imread('./papper.png')

dst = cv2.medianBlur(img, 5)

cv2.imshow('dst', dst)
cv2.imshow('img', img)
cv2.waitKey(0)

image-20241107165121046

七、双边滤波

image-20241107165219906

image-20241107165227513

image-20241107165309701

1
2
3
4
5
6
7
8
9
(function)
def bilateralFilter(
src: MatLike,
d: int, # 直径,大小
sigmaColor: float,
sigmaSpace: float,
dst: MatLike | None = ...,
borderType: int = ...
) -> MatLike: ...
1
2
3
4
5
6
7
8
9
10
import cv2
import numpy as np

img = cv2.imread('./lena.png')

dst = cv2.bilateralFilter(img, 7, 20, 50)

cv2.imshow('dst', dst)
cv2.imshow('img', img)
cv2.waitKey(0)

可以看出,帽子这些颜色比较深,看作了边缘,保留的很好,
但是脸这里进行了优化

image-20241107165725441

八、高通滤波

8.1、Sobel(索贝尔)算子

image-20241107170107968

1
2
3
4
5
6
7
8
9
10
11
12
13
(function) def Sobel(
src: MatLike,
ddepth: int, # 输出图像的深度(通常为 CV_8U 或 CV_64F)
dx: int, # x 方向的阶数(指定对图像在 x 方向的微分次数)
dy: int, # y 方向的阶数(指定对图像在 y 方向的微分次数)
dst: MatLike | None = ...,
ksize: int = ..., # Sobel 核的大小,必须是 1, 3, 5, 7 等奇数
scale: float = ...,
delta: float = ...,
borderType: int = ...
) -> MatLike

# 主要是用于边缘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import cv2
import numpy as np

img = cv2.imread('./chess.png')

# 索贝尔算子y方向边缘
d1 = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=5)
# 索贝尔算子x方向边缘
d2 = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=5)

dst = cv2.add(d1, d2)

cv2.imshow('img', img)
cv2.imshow('d1', d1)
cv2.imshow('d2', d2)
cv2.imshow('dst', dst)
cv2.waitKey(0)

image-20241107172706614

8.2、Scharr(沙尔)算子

image-20241107172817277

image-20241107172858112

image-20241107172925261

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import cv2
import numpy as np

img = cv2.imread('./chess.png')

# 沙尔算子y方向边缘
d1 = cv2.Scharr(img, cv2.CV_64F, 1, 0)
# 沙尔算子x方向边缘
d2 = cv2.Scharr(img, cv2.CV_64F, 0, 1)

dst = cv2.add(d1, d2)

cv2.imshow('img', img)
cv2.imshow('d1', d1)
cv2.imshow('d2', d2)
cv2.imshow('dst', dst)
cv2.waitKey(0)

# 沙尔比较少用,在比较细小的边缘,索贝尔不行,它可以

image-20241107173136905

8.3、Laplacian(拉普拉斯)算子

image-20241107173307166

image-20241107173319212

1
2
3
4
5
6
7
8
9
10
11
import cv2
import numpy as np

img = cv2.imread('./chess.png')

# 拉普拉斯
ldst = cv2.Laplacian(img, cv2.CV_64F, ksize=5)

cv2.imshow('img', img)
cv2.imshow('ldst', ldst)
cv2.waitKey(0)

image-20241107173555100

九、边缘检测Canny

image-20241108090807306

image-20241108090830529

1
2
3
4
5
6
7
8
(function) def Canny(
image: MatLike,
threshold1: float,
threshold2: float,
edges: MatLike | None = ...,
apertureSize: int = ...,
L2gradient: bool = ...
) -> MatLike
1
2
3
4
5
6
7
8
9
10
import cv2
import numpy as np

img = cv2.imread('./lena.png')

dst = cv2.Canny(img, 100, 200)

cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.waitKey(0)

image-20241108093520473

-------------本文结束感谢您的阅读-------------