二维卷积(图像滤波)
与一维信号一样, 图像也可以用各种低通滤波器 (LPF), 高通滤波器(HPF) 等进行滤波. LPF 有助于去除噪声, 模糊图像等. HPF 过滤器有助于在图像中找到边缘. OpenCV 提供了一个函数 cv.filter2D()来将内核与图像进行卷积. 例如, 我们将尝试对图像进行平均滤波. 一个 5x5 平均滤波内核如下:
操作如下: 将该内核保持在一个像素之上, 将该内核之下的所有 25 个像素相加, 取其平均值, 然后用新的平均值替换中心像素. 继续对图像中的所有像素继续此操作.
函数
dst=cv.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
参数:
src | 输入图像 |
dst | 与 src 相同大小、相同通道数的输出图像。 |
ddepth | 目标图像的所需深度。-1 使用原图像深度。 see combinations |
kernel | 卷积核, 一个单通道浮点矩阵; 如果想对不同通道使用不同卷积核, 使用分割将图像分割成单独的彩色平面,并单独处理它们。 |
anchor | 内核的锚点,表示内核中经过过滤的点的相对位置; 锚点应该位于内核中; 默认值 (-1,-1) 代表锚点即内核中心。 |
delta | 在储存目标图像前可选的添加到像素的值,默认值为 0 |
borderType | 边界类型, see BorderTypes |
举例:
- import numpy as np
- import cv2 as cv
- from matplotlib import pyplot as plt
- img = cv.imread('2.jpg')
- # 卷积核, 一个单通道浮点矩阵
- kernel = np.ones((5, 5), np.float32)/25
- 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()
图像模糊(图像平滑)
图像模糊是通过将图像与低通滤波核进行卷积来实现的. 它对消除噪音很有用. 它实际上删除了图像中的高频内容(如: 噪声, 边缘). 所以在这个操作中, 边缘有点模糊. OpenCV 主要提供四种类型的模糊技术.
平均模糊
由归一化卷积框来实现. 他只是用卷积框覆盖区域所有像素的平均值来代替中心元素, 可以由函数 cv.blur 或 cv.boxFilter()完成. 我们需要设定卷积框的 宽和高. 下面是一个 归一化卷积框, 又称平均滤波器核:
例如, 一个 3*3 的卷积框是:
如果你不想使用归一化卷积框, 你应该使用 cv2.boxFilter(), 这时要传入参数 normalize=False.
函数:
dst=cv.blur(src, ksize[, dst[, anchor[, borderType]]])
参数:
src | 输入图像,它可以拥有任意数量的通道,都是独立处理的。但深度应该是 CV_8U, CV_16U, CV_16S, CV_32F or CV_64F. |
dst | 输出图像,与 src 由同样的大小和类型 |
ksize | 平均卷积核的尺寸,元组(x,y) 即代表 x*y 的矩阵 |
anchor | 锚点,核的基准点; 默认值点 (- 1,1) 表示锚位于内核中心。 |
borderType | 边界类型, see BorderTypes |
调用 blur(src, dst, ksize, anchor, borderType)函数相当于调用 boxFilter(src, dst, src.type(), anchor, true, borderType).
高斯模糊
在这种情况下, 用高斯核函数代替了盒形滤波器. 这是通过函数 cv.GaussianBlur()完成的. 我们应该指定内核的宽度和高度, 它们应该是正的奇数. 我们还应该分别指定 X 和 Y 方向的标准差, sigmaX 和 sigmaY. 如果只指定 sigmaX, 则 sigmaY 与 sigmaX 相同. 如果两者都是零, 那么函数会根据核函数的大小自己计算. 高斯滤波可以有效的从 图像中去除高斯噪音.
函数:
dst=cv.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]])使用高斯滤波器模糊图像
参数:
src | 输入图像; 图像可以有任意数量的通道,这些通道是独立处理的,但是深度应该是 CV_8U、CV_16U、CV_16S、CV_32F 或 CV_64F。 |
dst | 与 src 有相同大小和类型的输出图像 |
ksize | 高斯卷积核尺寸,元祖(x,y). ksize.width 和 ksize.height 可以是不同的 但必须是正的奇数. 或者, 它们可以为 0 然后由计算得到. |
sigmaX | 高斯核在 x 方向的标准差 |
sigmaY | 高斯核在 y 方向的标准差(sigmaY=0 时,其值自动由 sigmaX 确定(sigmaY=sigmaX);sigmaY=sigmaX=0 时,它们的值将由 ksize.width 和 ksize.height 自动确定) |
borderType | 像素边界类型, see BorderTypes |
中值模糊
就是用与卷积框对应像素的中值来替代中心像素的值. 这个滤波器经常用来去除椒盐噪声. 前面的滤波器都是用计算得到的一个新值来取代中 心像素的值, 而中值滤波是用中心像素周围 (也可以使他本身) 的值来取代他. kernel size 的大小也应该是一个正奇数.
函数:
dst=cv.medianBlur(src, ksize[, dst])使用中值滤波器模糊图像.
该函数使用 ksize*ksize 孔径的中值滤波器平滑图像. 多通道图像的每个通道都是独立处理的. 支持就地操作. 中值过滤器在内部使用 border_replication 来处理边界像素, 请参见 BorderTypes
参数:
src | 输入 1-,3-,4 - 通道的图像; 当 ksize 是 3 或 5 时, 图像的深度应该时 CV_8U, CV_16U, or CV_32F, 如果孔径更大, 它只可能是 CV_8U. |
dst | 与 src 大小和类型相同的输出图像 |
ksize | 孔径大小,必须是奇数且大于 1, for example: 3, 5, 7 ... |
双边滤波
cv.bilateralFilter 在保持边缘清晰的同时, 对噪声去除非常有效. 但与其他过滤器相比, 该操作速度较慢. 们已经知道高斯滤波器是求 中心点邻近区域像素的高斯加权平均值. 这种高斯滤波器只考虑像素之间的空间关系, 而不会考虑像素值之间的关系(像素的相似度, 所以这种方法不会考 虑一个像素是否位于边界. 因此边界也会别模糊掉, 而这并不是我们想要的.
双边滤波在同时使用空间高斯权重和灰度值相似性高斯权重. 空间高斯函数确保只有邻近区域的像素对中心点有影响, 灰度值相似性高斯函数确保只有 与中心像素灰度值相近的才会被用来做模糊运算. 所以这种方法会确保边界不 会被模糊掉, 因为边界处的灰度值变化比较大.
函数:
dst=cv.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])
参数:
src | 8-bit or floating-point, 1-channel or 3-channel image. |
dst | 与原图像具有相同大小和类型的输出图像 |
d | 用于滤波的每个像素邻域的直径. 如果这个值是负数,则根据 sigmaSpace 自动计算 |
sigmaColor | 色空间过滤器的 sigma 值. 值越大 & nbsp; 表明该像素邻域内 (see sigmaSpace) 更多的颜色被混合到一起,产生较大的半相等颜色区域 |
sigmaSpace | 坐标空间中滤波器的 sigma 值,参数值越大,表示距离越远的像素只要颜色足够接近就会相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当 d>0 时,d 指定了邻域大小且与 sigmaSpace 无关,否则 d 正比于 sigmaSpace. |
borderType | 边界类型, see BorderTypes |
综合案例
- import cv2
- import numpy as np
- from matplotlib import pyplot as plt
- img = cv2.imread('4.jpg') # 注意图片尺寸必须是卷积核的整倍, 否则出错
- # 2D 卷积滤波
- kernel = np.ones((3, 3), np.float32)/9 # 创建一个 9*9 的平均滤波器核
- dst = cv2.filter2D(img, -1, kernel)
- # 平均模糊
- blur = cv2.blur(img, (5, 5))
- # 高斯滤波
- gauss = cv2.GaussianBlur(img, (5, 5), 0)
- # 中值滤波
- median = cv2.medianBlur(img, 5)
- # 双边滤波
- bila = cv2.bilateralFilter(img, 10, 200, 200)
- plt.subplot(231), plt.imshow(img), plt.title('Original')
- plt.subplot(232), plt.imshow(dst), plt.title('Filter2D')
- plt.subplot(233), plt.imshow(blur), plt.title('Averaging')
- plt.subplot(234), plt.imshow(gauss), plt.title('GuassianBlur')
- plt.subplot(235), plt.imshow(median), plt.title('MedianBlur')
- plt.subplot(236), plt.imshow(bila), plt.title('BilateralFilter')
- plt.show()
opencv-python - 学习笔记十一(图像平滑与滤波)
来源: http://www.bubuko.com/infodetail-3137738.html