任务描述
本关任务:按照要求添加椒盐噪声。
相关知识
本关将介绍数字图像处理中的噪声模型。
图像的噪声
数字图像中的噪声,指在图像的获取和传输过程中,被干扰之后不符合原来的图像内容的像素点。
被认定为噪声的像素点,它的像素值往往和周围的点的像素值极不协调,比如比周围所有的像素点的值都要大很多或者小很多。我们需要用一些数学模型去描述图像中的噪声,常见的有高斯噪声、椒盐噪声等。
所谓模型,指的就是噪声点在原来的图像上是怎么分布的,以及噪声点的像素值的规律。
高斯噪声
高斯噪声几乎是最有名的数字图像噪声了,高斯噪声又叫正态噪声,它的数学公式如下:
p(z)=2πσ1e−(z−zˉ)2/2σ2
p(z)
表示像素点z
上叠加的噪声的值,sigma
(希腊字母这里我们统一使用英文表示)表示图像上所有噪声值的均值。这个公式的意思其实就是所有的噪声点的噪声值符合正态分布:即噪声值都集中在噪声值的均值的两侧的一个范围内,如下图所示:
用python
表示高斯噪声
程序
在opencv
中,我们可以模拟往图像上添加高斯噪声,程序如下所示:
# 使用opencv读取图片
image = cv2.imread("longmao.jpg")
# 将图片的像素值归一化,存入矩阵中
image = np.array(image/255, dtype=float)
# 生成正态分布的噪声,其中0表示均值,0.1表示方差
noise = np.random.normal(0, 0.1, image.shape)
# 将噪声叠加到图片上
out = image + noise
# 将图像的归一化像素值控制在0和1之间,防止噪声越界
out = np.clip(out, 0.0, 1.0)
# 将图像的像素值恢复到0到255之间
out = np.uint8(out*255)
# 展示图片
cv2.imshow("after gauss", out)
# 等待按键的按下
cv2.waitKey()
在上面的程序中,我们先将图片的像素点归一化,则像素值在0
到1
之间,然后生成高斯噪声:均值是0
,方差是0.1
,则这个噪声的特点是:噪声值集中在0
附近,而且以0
为对称轴对称,有正也有负,将噪声叠加到图片上,此时图片的像素值可能大于0
或者小于1
,所以需要使用clip
函数将像素值裁剪到0
和1
之间。
运行结果
看下运行结果,第一个是原图,第二个是高斯噪声污染的图像:
椒盐噪声
椒盐噪声指的是像图片中添加像素值为0
(黑色,胡椒的颜色)的噪声或者像素值为255
的噪声(白色,食盐的颜色),它的数学公式如下:
用python
表示椒盐噪声
程序
在opencv
中,我们可以模拟往图像上添加椒盐噪声,示例如下所示:
# 使用opencv读取图片
image = cv2.imread("longmao.jpg")
# 待输出的图片
output = np.zeros(image.shape,np.uint8)
# 椒盐噪声的阈值
prob = 0.2
thres = 1 - prob
# 遍历图像,获取叠加噪声后的图像
for i in range(image.shape[0]):
for j in range(image.shape[1]):
rdn = random.random()
if rdn < prob:
# 添加胡椒噪声
output[i][j] = 0
elif rdn > thres:
# 添加食盐噪声
output[i][j] = 255
else:
# 不添加噪声
output[i][j] = image[i][j]
# 展示图片
cv2.imshow("after gauss", output)
# 等待按键的按下
cv2.waitKey()
我们每遍历到一个像素点,就用随机函数获取一个随机值,如果这个值满足某个条件,则向当前点像素点添加胡椒噪声或者食盐噪声。
运行结果
看下运行结果,第一个是原图,第二个是椒盐噪声污染的图像:
编程要求
根据提示,在右侧编辑器Begin
和End
之间补充代码,往灰度图片img
上添加椒盐噪声,要求在像素值小于100
的点上添加食盐噪声,在像素值大于200
的点上添加胡椒噪声,其他值的像素点不需要添加噪声,结果图片保存到output
。
测试说明
平台会测试添加噪声后的打印结果。
输出结果:
18725817
开始你的任务吧,祝你成功!
# 导入numpy包
import numpy as np
# 导入opencv包
import cv2
# 使用opencv读取图片
image = cv2.imread("/data/workspace/myshixun/step10_zaosheng1/原图/edu.png", cv2.IMREAD_GRAYSCALE)
# 待输出的图片
output = np.zeros(image.shape, np.uint8)
######### Begin ##########
# 遍历图像,获取叠加噪声后的图像
for i in range(image.shape[0]):
for j in range(image.shape[1]):
if image[i][j] < 100:
# 在像素值小于100的点上添加食盐噪声
output[i][j] = 255
elif image[i][j] > 200:
# 在像素值大于200的点上添加胡椒噪声
output[i][j] = 0
else:
# 其他值的像素点不需要添加噪声
output[i][j] = image[i][j]
######### End ##########
cv2.imwrite("/data/workspace/myshixun/step10_zaosheng1/学员文件/output.jpg", output)
print(np.sum(output))