python opencv入门 图像平滑(12)

来源:互联网 发布:b站发展史知乎 编辑:程序博客网 时间:2024/05/22 23:20

内容来自OpenCV-Python Tutorials 自己翻译整理

目标
使用不同的低通滤波对图像进行模糊化
使用自定义滤波对图像进行过滤(二维卷积)

2D卷积(图像过滤)
图像可以进行低通滤波和高通滤波,低通滤波可以使图像去除噪声,高通滤波可以找到图像的边缘。
opencv提供cv2.filter2D函数用来对图像进行卷积操作。
例如,对下面5*5的图像进行均值滤波的核
这里写图片描述

将核放在图像的每个像素上面,计算5*5的和,然后求平均数,将平均数代替该像素值。

import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread('3.jpg')kernel = np.ones((5,5),np.float32)/25dst = cv2.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中有四种方法进行平滑

均值
使用卷积框中的像素平均值代替该像素。可以使用cv2.blur和cv2.boxFilter函数完成。需要设定卷积框的宽度和高度。
3*3卷积框如下

这里写图片描述

如果不想使用归一化卷积框,那么使用函数cv2.boxFilter函数,参数传入normalize=False

import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread('3.jpg')blur = cv2.blur(img,(5,5))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()

高斯模糊
把卷积的核换成高斯核,也就是方框不变,矩阵中的值符合高斯分布,方框中心值最大,其余值与随着距离中心越远,值越小。类似于一个凸起。原来的求平均数方法变成加权平均数。函数使用 cv2.GaussianBlur,需要制定奇数的宽度和高度,以及沿着x和y方向的标准差。如果仅制定了x方向的标准差,y方向会取相同值。如果标准差都是0,函数会根据核函数大小自行计算。
可以使用cv2.getGaussianKernel函数自己构建高斯核。

blur = cv2.GaussianBlur(img,(5,5),0)

中值滤波
用卷积框对应像素的中值代替中心像素值。该方法可以去除椒盐噪声。卷积核大小应该是奇数

import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread('8.jpg')median = cv2.medianBlur(img,5)plt.subplot(121),plt.imshow(img),plt.title('Original')plt.xticks([]), plt.yticks([])plt.subplot(122),plt.imshow(median),plt.title('Blurred')plt.xticks([]), plt.yticks([])plt.show()

这里写图片描述

双边滤波
双边滤波可以保证图像边界清晰的情况下去除噪音,但是速度较慢。高斯滤波只考虑像素之间的空间关系,不考虑像素之间的值关系,所以会模糊掉边界。双边滤波同时使用空间高斯权重和灰度值相似的高斯权重值。空间高斯数只确保邻近区域像素对中心的影响,灰度相似高斯函数确保只有与中心像素灰度值接近才会用来实现模糊运算。所以该方便不会模糊边界,因为边界灰度值变换较大。

import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread('3.jpg')blur = cv2.bilateralFilter(img,9,75,75)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()

结果略

原创粉丝点击