平滑处理也成模糊处理,是一种简单且使用频率很高的图像处理方法。平滑处理的用处有很多,最常见的是用来减少图像上的噪点或者市镇。在涉及到降低图像分辨率时,平滑处理是非常好用的方法。
滤波可分为低通滤波和高通滤波:以高斯滤波为例,高斯滤波是指用高斯函数作为滤波函数的滤波操作,至于是不是模糊,要看是高斯低通还是高斯高通,低通就是模糊,高通就是锐化
就是图像中像素灰度值变化快的就是高频部分,变化慢的就是低频部分,按我的理解高频注重细节,低频不要细节使图像模糊
线性滤波:方框滤波,均值滤波和高斯滤波
非线性滤波:中值滤波和双边滤波
线性滤波器:线性滤波器经常用于提出输入信号中不想要的频率或者从许多频率中选择一个想要的频率,常用线性滤波器:
生成有噪音的图片
# -*- coding:utf-8 -*-
import cv2
import numpy as np
# 读取图片
img = cv2.imread("timg.jpg", cv2.IMREAD_UNCHANGED)
# 加噪声
for i in range(50000):
x = np.random.randint(0, img.shape[0])
y = np.random.randint(0, img.shape[1])
img[x, y, :] = 255
cv2.imshow("noise", img)
cv2.imwrite("noise_image.jpg",img)
# 等待显示
key = cv2.waitKey(0)
if key == 27:
cv2.destroyAllWindows()
原图片:
效果图:![在这里插入图片描述](https://img-blog.csdnimg.cn/20190904090622527.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDY4ODcy,size_16,color_FFFFFF,t_70
方框滤波(box Filter)被封装在一个名为boxblur的函数中,即boxblur函数的作用是使用方框滤波器(box filter)来模糊一张图片,从src输入,从dst输出。
方框滤波所用的核
其中
result = cv2.boxFilter(原始图像, 目标图像深度, 核大小, normalize属性)
# -*- coding:utf-8 -*-
import cv2
import numpy as np
# 读取图片
img = cv2.imread("noise_image.jpg", cv2.IMREAD_UNCHANGED)
# 加噪声
img = cv2.boxFilter(img, -1, (5,5), normalize=1)
# 等待显示
cv2.imshow("boxfilter", img)
cv2.imwrite("boxfilter.jpg", img)
key = cv2.waitKey(0)
if key == 27:
cv2.destroyAllWindows()
代码中使用5*5的核,normalize=1表示进行归一化处理,此时与均值滤波相同
方框滤波效果图:
均值滤波是指任意一点的像素值,都是周围NM个像素值的均值。例如下图中,红色点的像素值为蓝色背景区域像素值之和除25。
其中红色区域的像素值均值滤波处理过程为: ((197+25+106+156+159)+ (149+40+107+5+71)+ (163+198+226+223+156)+ (222+37+68+193+157)+ (42+72+250+41+75)) / 25
其中55的矩阵称为核,针对原始图像内的像素点,采用核进行处理,得到结果图像。
将 1 / 25 1/25 1/25提取出来
result = cv2.blur(原始图像,核大小)
# -*- coding:utf-8 -*-
import cv2
import numpy as np
# 读取图片
img = cv2.imread("noise_image.jpg", cv2.IMREAD_UNCHANGED)
# 加噪声
img = cv2.blur(img,(5, 5))
# 等待显示
cv2.imshow("boxfilter", img)
cv2.imwrite("boxfilter.jpg", img)
key = cv2.waitKey(0)
if key == 27:
cv2.destroyAllWindows()
效果图和方框滤波一样,不粘贴了,卷积核越大,则生成的图像越模糊
高斯滤波分为两个步骤,首先建立高斯模板,然后利用高斯模板进行卷积。
高斯模板制作:
假定中心点的坐标是(0,0),那么取距离它最近的8个点坐标,为了计算,需要设定σ的值。假定σ=1.5,则模糊半径为1的高斯模板就算如下
这个时候我们我们还要确保这九个点加起来为1(这个是高斯模板的特性),这9个点的权重总和等于0.4787147,因此上面9个值还要分别除以0.4787147,得到最终的高斯模板。
高斯滤波计算:
有了高斯模板,那么高斯滤波的计算便顺风顺水了。
举个栗子:
假设现有9个像素点,灰度值(0-255)的高斯滤波计算如下:
为了克服简单局部平均法的弊端(图像模糊),目前已提出许多保持边缘、细节的局部平滑算法。它们的出发点都集中在如何选择邻域的大小、形状和方向、参数加平均及邻域各店的权重系数等。
图像高斯平滑也是邻域平均的思想对图像进行平滑的一种方法,在图像高斯平滑中,对图像进行平均时,不同位置的像素被赋予了不同的权重。高斯平滑与简单平滑不同,它在对邻域内像素进行平均时,给予不同位置的像素不同的权值,下图的所示的 3 * 3 和 5 * 5 领域的高斯模板。
高斯滤波让临近的像素具有更高的重要度,对周围像素计算加权平均值,较近的像素具有较大的权重值。如下图所示,中心位置权重最高为0.4。
Python中OpenCV主要调用GaussianBlur函数,如下:
dst = cv2.GaussianBlur(src, ksize, sigmaX)
其中,src表示原始图像,ksize表示核大小,sigmaX表示X方向方差。注意,核大小(N, N)必须是奇数,X方向方差主要控制权重。
# -*- coding:utf-8 -*-
import cv2
import numpy as np
# 读取图片
img = cv2.imread("noise_image.jpg", cv2.IMREAD_UNCHANGED)
# 加噪声
img = cv2.GaussianBlur(img, (3,3), 0)
# 等待显示
cv2.imshow("gauss", img)
cv2.imwrite("gauss.jpg", img)
key = cv2.waitKey(0)
if key == 27:
cv2.destroyAllWindows()
效果图:
在使用邻域平均法去噪的同时也使得边界变得模糊。而中值滤波是非线性的图像处理方法,在去噪的同时可以兼顾到边界信息的保留。选一个含有奇数点的窗口W,将这个窗口在图像上扫描,把窗口中所含的像素点按灰度级的升或降序排列,取位于中间的灰度值来代替该点的灰度值。 例如选择滤波的窗口如下图,是一个一维的窗口,待处理像素的灰度取这个模板中灰度的中值,滤波过程如下:
如下图所示,将临近像素按照大小排列,取排序像素中位于中间位置的值作为中值滤波的像素值。
OpenCV主要调用medianBlur()函数实现中值滤波。图像平滑里中值滤波的效果最好。
dst = cv2.medianBlur(src, ksize)
其中,src表示源文件,ksize表示核大小。核必须是大于1的奇数,如3、5、7等。
# -*- coding:utf-8 -*-
import cv2
import numpy as np
# 读取图片
img = cv2.imread("noise_image.jpg", cv2.IMREAD_UNCHANGED)
# 加噪声
img = cv2.medianBlur(img, 3)
# 等待显示
cv2.imshow("mediablur", img)
cv2.imwrite("mediablur.jpg", img)
key = cv2.waitKey(0)
if key == 27:
cv2.destroyAllWindows()
双边滤波很有名,使用广泛,简单的说就是一种同时考虑了像素空间差异与强度差异的滤波器,因此具有保持图像边缘的特性。(按我的理解就是保证轮廓存在)原理不是很懂,直接看代码和效果图
# -*- coding:utf-8 -*-
import cv2
import numpy as np
# 读取图片
img = cv2.imread("noise_image.jpg", cv2.IMREAD_UNCHANGED)
# 加噪声
img = cv2.bilateralFilter(src=img, d=0, sigmaColor=100, sigmaSpace=15)
# 等待显示
cv2.imshow("bilateralblur", img)
cv2.imwrite("bilateralblur.jpg", img)
key = cv2.waitKey(0)
if key == 27:
cv2.destroyAllWindows()
自带美颜效果