最近在做图像处理工作,需要向原图像添加高斯噪声,来模拟现实生活中的实际噪声。发现MATLAB和Python中都有相应的API可以用,但是实际使用中会有些“坑”需要注意。特此记录下来,与各位分享。
Matlab上有官方给出的API
J = imnoise(I,’gaussian’,M,V) adds Gaussian white noise of mean m and variance v to the image I. The default is zero mean noise with 0.01 variance.
I:原图 M:均值 V:方差
这里要注意的是,imnoise()函数,会将原始图片像素的取值范围转换到[0,1]范围内,然后才开始添加高斯噪声,最后还会将图像转换为[0,255]。所以如果你一开始输入的图片取值范围是[0,255],那么就需要将均值和方差必须也要归一化到[0,1]范围内。具体的MATLAB 实现如下,对应的PSNR为24.94
image_o=imread('C:\Users\ASUS\Desktop\JSRT_test\JPCLN147.jpg');
image_o=rgb2gray(image_o); %转为灰度图
x1=imnoise(image_o,'gaussian',0,(15/255)^2);%添加标准差为15的高斯噪声
imwrite(x1,'C:\Users\ASUS\Desktop\gaussian_15.jpg');%保存图像至桌面
psnr(image_o,x1) %PSNR=24.9461
我们一般可以使用,skimage.util.random_noise
(image, mode=’gaussian’, seed=None, clip=True, **kwargs)
image:输入图片,要求是array类型
mode:有很多种模式可选 这里是添加高斯噪声
seed:是随机种子,如果给定具体的数字,就可以产生伪随机,给定None就是真的随机参数
clip:对图像添加高斯噪声后,图像原始的像素值可能会小于0,也有可能大于255,clip设置为True将会将这些值统一设置为0或者255;clip设置成False,就会有可能出现一些超过区间的点
mean:均值,默认为0
var:噪声的方差,注意设置
与MATLAB一样,该函数也是需要将图片的取值范围转化成[0,1],所以设置方差的时候要注意参数的设置;不同的是,最终返回的数据的取值范围还是[0,1],不会变成[0,255],所以,你要是想保存加噪后的图片,或者要和原图进行PSNR的计算,就需要将图片的范围重新调至[0,255]
具体的Python的实现代码如下
import cv2
import numpy as np
import skimage
def psnr (img_1,img_2):
mse=((np.asarray(img_1) - np.asarray(img_2).astype(np.float)) ** 2).mean()
psnr=10* np.log10((255**2)/mse)
return psnr
img1=cv2.imread("C:/Users/ASUS/Desktop/JSRT_test/JPCLN147.jpg",0)
img_noise=skimage.util.random_noise(img1, mode='gaussian', seed=None, var=(15/255.0)**2) #add gaussian noise
img_noise=img_noise*255 #limit the value in the range (0,255)
Psnr=psnr(img1,img_noise)
print("PSNR:",Psnr)