opencv-python学习(3)--加噪与空间滤波

摘要

opencv的python图像处理学习笔记

1.图像噪声

图像噪声是指存在于图像数据中的不必要的或多余的干扰信息。有些噪声严重影响了图片的质量,因此在图片预处理的过程中需要先将图片的噪声去除。

噪声通常是随机过程,需要具备一定的概率论相关知识才能更好的理解。

常见的噪声有如下几种:椒盐/高斯/泊松/散斑,下面给出使用python对图片加噪的方法。部分代码参考csdn文章 python使用opencv对图像添加(高斯/椒盐/泊松/斑点)噪声

1.1 椒盐噪声

这个名字起的色香味俱全,椒盐噪声实际上指的是两种颜色的噪声,黑点为椒,白点为盐。在图片上的分布通常是随机的,就像是撒了胡椒和盐在图片上,由此得名。

产生的原因通常是脉冲干扰或者传感器内部错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 加椒盐噪声
def add_pepper_and_salt(self):
# 获取数量和椒盐比
amount = float(self.config.get("Noisy","noise_ratio"))
p_vs_s = float(self.config.get("Noisy","pepper_vs_salt"))
noisy_img = np.copy(self.image)
num_pepper = np.ceil(amount * noisy_img.size * p_vs_s)
num_salt = np.ceil(amount * noisy_img.size * (1. - p_vs_s))
#设置添加pepper噪声
coords = [np.random.randint(0, i - 1, int(num_pepper)) for i in self.image.shape]
noisy_img[tuple(coords)] = 0
#设置添加salt噪声
coords = [np.random.randint(0, i - 1, int(num_salt)) for i in self.image.shape]
noisy_img[tuple(coords)] = 255
# 展示
win_name = "pepper&salt"
UIFunctions.wait_key(self,noisy_img,win_name)

1.2 高斯噪声

高斯噪声是一种非常常见的噪声,很多噪声都是服从正态分布的,他们被统一称为高斯噪声。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 加高斯噪声
def add_gauss_noisy(self):
img = self.image
#获取均值和标准差
mean = float(self.config.get("Noisy","guass_mean"))
sigma = float(self.config.get("Noisy","guass_sigma"))
#生成高斯分布的噪声
gauss = np.random.normal(mean,sigma,img.shape)
#给图片添加高斯噪声
noisy_img = img + gauss
#设置图片添加高斯噪声之后的像素值的范围
noisy_img = np.uint8(np.clip(noisy_img,a_min=0,a_max=255))
# 展示
win_name = "gauss_noisy"
UIFunctions.wait_key(self,noisy_img,win_name)

1.3 泊松噪声

泊松噪声又称散粒噪声,适合于描述单位时间内随机事件发生的次数的概率分布。

1
2
3
4
5
6
7
8
9
10
11
# 加泊松噪声
def add_poisson_noisy(self):
img = self.image
lam = float(self.config.get("Noisy","poisson_lambda"))
# 生成泊松分布的噪声
poisson = np.random.poisson(lam=lam,size=img.shape).astype(dtype='uint8')
noisy_img = img + poisson
noisy_img = np.uint8(np.clip(noisy_img,a_min=0,a_max=255))
# 展示
win_name = "poisson_noisy"
UIFunctions.wait_key(self,noisy_img,win_name)

1.4 散斑噪声

散斑的英文是Speckle,产生的原因通常是干涉。

1
2
3
4
5
6
7
8
9
10
11
# 加散斑噪声
def add_speckle_noisy(self):
img = self.image
speckle = np.random.randn(*img.shape)
#给图片添加speckle噪声
noisy_img = img + img * speckle
#归一化图像的像素值
noisy_img = np.uint8(np.clip(noisy_img,a_min=0,a_max=255))
# 展示
win_name = "speckle_noisy"
UIFunctions.wait_key(self,noisy_img,win_name)

2.平滑空间滤波器

2.1 原理

滤波一词源于频域,指筛选掉一部分频率的波。但因为空域和频域是可以通过傅里叶变换相互转换的,所以在空间中对图像进行一些操作在频域上看起来就是滤波(如平滑操作对应于频域的低通滤波)。而且二者各有优劣,所以在空域上对图片进行处理统一称为空间滤波。

平滑滤波器的主要原理是针对每一个像素点对一个核内的数据进行对应处理实现平滑效果。有点类似与卷积但不完全是。

2.2 均值滤波

对核取平均值

1
cv2.GaussianBlur(img,size)

img 原图像

size 核大小,通常为奇数,如(3,3)

2.3 高斯滤波

对核高斯加权

1
2
cv2.GaussianBlur(src,ksize,sigmaX,sigmaY)
cv2.GaussianBlur(img,(5,5),0,0)

sigmaX,sigmaY分别表示X,Y方向的标准偏差。 如果两者都为零,则根据内核大小计算它们。

2.4 中值滤波

取核内的中位数

1
2
cv2.medianBlur(img, k)
cv2.medianBlur(img,3)

k 为方框的尺寸

3.锐化空间滤波器

3.1 原理

通过找到灰度变换明显的区域,强化该范围像素。

这里涉及到寻找一个跳变(边缘)的过程,所以可以采用求导的方法。一阶导或者二阶导(拉普拉斯算子)

因为是寻找边缘,所以还可以用来进行腐蚀,膨胀,边缘检测等操作。

3.2 sobel

索贝尔算子方法简单、处理速度快,被广泛应用于边缘提取。

1
img = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=5)

其中第二个参数是数据类型,第3、4个参数是dx,dy 表示水平方向/竖直方向,要求两者只能有一个为1,另一个为0,第5个值表示核的大小

3.3 scharr

当索贝尔算子的第五个参数为-1时,就变成了夏尔算子,scharr是sobel的一个增强,如下图

scharr 和 sobel
1
img = cv2.Scharr(img, cv2.CV_64F, 0, 1)

3.4 laplace

拉普拉斯算子

1
img = cv2.Laplacian(self.image, cv2.CV_64F)

3.5 canny

Canny算法年代久远,但可以说它是边缘检测的一种标准算法,而且仍在广泛使用。

Canny边缘检测算法可以分为以下5个步骤: 1. 高斯滤波来平滑图像去除噪声 2. 找寻图像的强度梯度 3. 应用非最大抑制(non-maximum suppression)技术来消除边误检 4. 应用双阈值的方法来决定可能的(潜在的)边界 5. 利用滞后技术来跟踪边界

1
img = cv2.Canny(img, lowThreshold, highThreshold)

参考资料

[1] https://blog.csdn.net/weixin_40922285/article/details/102801633

[2] https://baike.baidu.com/item/canny%E7%AE%97%E6%B3%95/8439208