一、图像滤波
滤波的作用:
一副图像==通过滤波器==得到==另一幅图像==
其中滤波器又称为==卷积核==,滤波的过程称为==卷积==
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107155955301.png)
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107160007913.png)
二、卷积相关概念
2.1、卷积核的大小
卷积核一般为==奇数==,如3x3,5x5,7x7等
一方面是增加==padding==的原因
另一方面是保证==锚点==在中间,防止位置发生偏移
在深度学习中,卷积核越大,看到的信息(==感受野==)越多,提取的==特征越好==,同时计算量也就越大
2.2、锚点
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107160751205.png)
2.3、边界扩充
当卷积核大于1且不进行边界扩充,输出尺寸将相应缩小
当卷积核以标准方式进行边界扩充,则输出数据的空间大小与输入相等
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107160906228.png)
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107160916733.png)
2.4、步长
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107160945609.png)
步长为2
三、实战图像卷积
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107161122621.png)
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: ...
|
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107162224860.png)
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)
|
可以看出滤波之后,线条变模糊了,眼睛变暗了
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107162500753.png)
四、方盒滤波与均值滤波
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107162849123.png)
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107162945808.png)
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107162952541.png)
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)
|
五、高斯滤波
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107163554151.png)
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107163625762.png)
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107163638106.png)
中间比重高,四边权重低
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)
|
可以看出右侧的噪点少了很多,但是边缘也变模糊了
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107164528763.png)
六、中值滤波
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107164709281.png)
优点:对==胡椒噪音==效果明显
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)
|
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107165121046.png)
七、双边滤波
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107165219906.png)
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107165227513.png)
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107165309701.png)
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)
|
可以看出,帽子这些颜色比较深,看作了边缘,保留的很好,
但是脸这里进行了优化
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107165725441.png)
八、高通滤波
8.1、Sobel(索贝尔)算子
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107170107968.png)
1 2 3 4 5 6 7 8 9 10 11 12 13
| (function) def Sobel( src: MatLike, ddepth: int, dx: int, dy: int, dst: MatLike | None = ..., ksize: int = ..., 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')
d1 = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=5)
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)
|
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107172706614.png)
8.2、Scharr(沙尔)算子
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107172817277.png)
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107172858112.png)
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107172925261.png)
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')
d1 = cv2.Scharr(img, cv2.CV_64F, 1, 0)
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)
|
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107173136905.png)
8.3、Laplacian(拉普拉斯)算子
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107173307166.png)
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107173319212.png)
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)
|
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241107173555100.png)
九、边缘检测Canny
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241108090807306.png)
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241108090830529.png)
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)
|
-%E6%BB%A4%E6%B3%A2%E5%99%A8/image-20241108093520473.png)