时域与频域
视频处理归根到底还是得对图像进行处理,常见的图像处理可以大致分为时域上处理和频域上处理,为此,我们先了解一下什么是时域,什么是频域
时域是真实世界,是唯一真实存在的域,自变量是时间,即横轴是时间,纵轴是信号的变化,其动态信号x(t)是描述信号在不同时刻取值的函数;
频域最重要的性质就是它不是真实的,仅仅是一个数学构造,自变量是频率,即横轴是频率,纵轴是该频率信号的幅度,也就是通常说的频谱图。
更多关于时域与频域的请阅读以下文章
-什么是时域和频域
-信号时域频域及转换
相关图像噪声可以点击这里
均值滤波
均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标像素为中心的周围8个像素,构成一个滤波模板,即去掉目标像素本身),再用模板中的全体像素的平均值来代替原来像素值
通俗的所就是用选定区域的平均值来代替该点的像素值,比如选定的区域是(3,3)的,不考虑边界,第一个区域就是(1+2+1+1+2+2+5+7+6)/9=3,所以该点的值为3。边界值不变(如果考虑边界要进行补零操作),显然这有点类似卷积,给定一个33(当然也可以是其他大小的区域,一般都是33)的卷积核如下
这就可以实现均值滤波了,当然,可以更换卷积核来实现加权平均的效果,根据上面的原理可以自己编写均值滤波的函数,网上已有很多博客实现了,这里就不在多说了,以下功能的实现基于opencv自带的去燥模块(blur函数)。
C++: void blur(InputArray src,OutputArray,dst,Size ksize,Point anchor=Point(-1,-1),int borderType=BORDER_DEFAULT)
相关介绍点击这里
注意:
这里的像素值都是整数,所以在平均之后若有小数,按四舍五入处理
程序实现
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from skimage import util
import cv2
import chardet
# 打开图片
img = Image.open("C:\\Users\\ranmaohua\\Desktop\\solaka.jpg")
img0 = np.array(img) # 相应的数据类型处理,便于后续处理
# 给图片加噪声
noise_sp_img = util.random_noise(img0, mode="s&p") # 椒盐噪声
noise_gs_img = util.random_noise(img0, mode="gaussian") # 高斯噪声
noise_poisson_img = util.random_noise(img0, mode="poisson") # 泊松噪声
# 滤波处理
img1 = cv2.blur(noise_sp_img.astype(np.float32), (3, 3)) # 均值滤波
img2 = cv2.blur(noise_gs_img.astype(np.float32), (3, 3)) # 均值滤波
img3 = cv2.blur(noise_poisson_img.astype(np.float32), (3, 3)) # 均值滤波
# 图片可视化
plt.figure()
plt.subplot(1, 3, 1)
plt.imshow(noise_sp_img)
plt.title("salt and pepper noise ")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.subplot(1, 3, 2)
plt.imshow(img1)
plt.title("After filtering")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.subplot(1, 3, 3)
plt.imshow(img0)
plt.title("Original image")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.figure()
plt.subplot(1, 3, 1)
plt.imshow(noise_gs_img)
plt.title("gaussian noise ")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.subplot(1, 3, 2)
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.imshow(img2)
plt.title("After filtering")
plt.subplot(1, 3, 3)
plt.imshow(img0)
plt.title("Original image")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.figure()
plt.subplot(1, 3, 1)
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.imshow(noise_poisson_img)
plt.title("poisson noise ")
plt.subplot(1, 3, 2)
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.imshow(img3)
plt.title("After filtering")
plt.subplot(1, 3, 3)
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.imshow(img0)
plt.title("Original image")
plt.show()
效果
针对椒盐噪声
细节
针对高斯噪声
细节图
针对泊松噪声
细节图
分析:均值滤波对三种噪声的效果不是特别理想,看起来仅仅是对图像进行了模糊化处理,这也是均值滤波的一个缺陷。
中值滤波
中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值.
中值滤波法对消除椒盐噪声非常有效,在光学测量条纹图象的相位分析处理方法中有特殊作用,但在条纹中心分析方法中作用不大.
中值滤波在图像处理中,常用于保护边缘信息,是经典的平滑噪声的方法。
原理就是将上述的平均值,换成所选区域中的中值
同样所有值均为整数,出现小数按四舍五入处理。
程序实现
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from skimage import util
import cv2
import chardet
# 打开图片
img = Image.open("C:\\Users\\ranmaohua\\Desktop\\solaka.jpg")
img0 = np.array(img) # 相应的数据类型处理,便于后续处理
# 给图片加噪声
noise_sp_img = util.random_noise(img0, mode="s&p") # 椒盐噪声
noise_gs_img = util.random_noise(img0, mode="gaussian") # 高斯噪声
noise_poisson_img = util.random_noise(img0, mode="poisson") # 泊松噪声
# 滤波处理
# 均值滤波
# img1 = cv2.blur(noise_sp_img.astype(np.float32), (3, 3))
# img2 = cv2.blur(noise_gs_img.astype(np.float32), (3, 3))
# img3 = cv2.blur(noise_poisson_img.astype(np.float32), (3, 3))
# 中值滤波
img1 = cv2.medianBlur(noise_sp_img.astype(np.float32), 3)
img2 = cv2.medianBlur(noise_gs_img.astype(np.float32), 3)
img3 = cv2.medianBlur(noise_poisson_img.astype(np.float32), 3)
# img3 = cv2.medianBlur(noise_poisson_img.astype(np.float32), 3)
# 图片可视化
plt.figure()
plt.subplot(1, 3, 1)
plt.imshow(noise_sp_img)
plt.title("salt and pepper noise ")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.subplot(1, 3, 2)
plt.imshow(img1)
plt.title("After filtering")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.subplot(1, 3, 3)
plt.imshow(img0)
plt.title("Original image")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.figure()
plt.subplot(1, 3, 1)
plt.imshow(noise_gs_img)
plt.title("gaussian noise ")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.subplot(1, 3, 2)
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.imshow(img2)
plt.title("After filtering")
plt.subplot(1, 3, 3)
plt.imshow(img0)
plt.title("Original image")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.figure()
plt.subplot(1, 3, 1)
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.imshow(noise_poisson_img)
plt.title("poisson noise ")
plt.subplot(1, 3, 2)
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.imshow(img3)
plt.title("After filtering")
plt.subplot(1, 3, 3)
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.imshow(img0)
plt.title("Original image")
plt.show()
效果
针对椒盐噪声
细节图
针对高斯噪声
细节图
针对泊松噪声
细节图
分析
从结果来看,中值滤波对椒盐噪声(脉冲噪声)的滤波效果出奇的好,但是对其余两种噪声的滤波效果并不是特别理想。
高斯滤波
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。 [1] 通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。
感兴趣的可以阅读下面几篇文献
简单易懂的高斯滤波
高斯滤波详解
原理
理论上,高斯分布在所有定义域上都有非负值,这就需要一个无限大的卷积核。实际上,仅需要取均值周围3倍标准差内的值,以外部份直接去掉即可(就是我们通常说的3σ原则)
高斯核(也就是高斯模板)的值=像素点坐标对应的二维高斯分布函数的值
我们可以看到,以一维高斯分布函数为例,当x很小或者很大时,对应的函数值为趋于0,在卷积的过程中并不起作用,所以一般省略。另外从高斯分布来看,σ越小,曲线越高瘦,也就是说当σ很小时,高斯核的半径越小,也就是模糊半径越小。
高斯模板的确定
首先我们看看一维高斯分布和二维高斯分布
图像处理主要是采用二维高斯分布,锚点处为原点,水平向右为x轴正向,竖直向下为y轴正向,需要给定模糊半径
我们就得到了模糊半径为1的高斯模板,因为高斯模板的特性(模板内所有值的和为1),为此我们需要对右边的矩阵进行归一化处理,即将每个值除以九个值的和,得到的矩阵就是我们所需要的高斯模板(实际上就是一个卷积核)
注意:由于四舍五入的原因,模板内的值可以略微比1大或者略微比1小。
滤波
高斯滤波实际上就是用高斯模板对图像进行卷积,具体过程与一般的卷积类似。
效果
椒盐噪声
细节
高斯噪声
细节
泊松噪声
细节
分析
高斯滤波对高斯噪声的滤除效果还不错,但是细看的话还是有点差距,可能是高斯核(高斯模板)和σ取的值不太合适。
程序
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from skimage import util
import cv2
import chardet
# 打开图片
img = Image.open("C:\\Users\\ranmaohua\\Desktop\\solaka.jpg")
img0 = np.array(img) # 相应的数据类型处理,便于后续处理
# 给图片加噪声
noise_sp_img = util.random_noise(img0, mode="s&p") # 椒盐噪声
noise_gs_img = util.random_noise(img0, mode="gaussian") # 高斯噪声
noise_poisson_img = util.random_noise(img0, mode="poisson") # 泊松噪声
# 滤波处理
# 均值滤波
# img1 = cv2.blur(noise_sp_img.astype(np.float32), (3, 3))
# img2 = cv2.blur(noise_gs_img.astype(np.float32), (3, 3))
# img3 = cv2.blur(noise_poisson_img.astype(np.float32), (3, 3))
# # 中值滤波
# img1 = cv2.medianBlur(noise_sp_img.astype(np.float32), 3)
# img2 = cv2.medianBlur(noise_gs_img.astype(np.float32), 3)
# img3 = cv2.medianBlur(noise_poisson_img.astype(np.float32), 3)
# 高斯滤波
img1 = cv2.GaussianBlur(noise_sp_img.astype(np.float32), (5, 5), 1)
img2 = cv2.GaussianBlur(noise_gs_img.astype(np.float32), (5, 5), 3)
img3 = cv2.GaussianBlur(noise_poisson_img.astype(np.float32), (5, 5), 1)
# 图片可视化
plt.figure()
plt.subplot(1, 3, 1)
plt.imshow(noise_sp_img)
plt.title("salt and pepper noise ")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.subplot(1, 3, 2)
plt.imshow(img1)
plt.title("After filtering")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.subplot(1, 3, 3)
plt.imshow(img0)
plt.title("Original image")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.figure()
plt.subplot(1, 3, 1)
plt.imshow(noise_gs_img)
plt.title("gaussian noise ")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.subplot(1, 3, 2)
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.imshow(img2)
plt.title("After filtering")
plt.subplot(1, 3, 3)
plt.imshow(img0)
plt.title("Original image")
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.figure()
plt.subplot(1, 3, 1)
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.imshow(noise_poisson_img)
plt.title("poisson noise ")
plt.subplot(1, 3, 2)
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.imshow(img3)
plt.title("After filtering")
plt.subplot(1, 3, 3)
plt.xticks([]) # 去掉x轴
plt.yticks([]) # 去掉y轴
plt.axis('off') # 去掉坐标轴
plt.imshow(img0)
plt.title("Original image")
plt.show()