目录
- Noise Attack
- 1 高斯噪声(Gaussian Noise)
- 2 椒盐噪声(Salt and Pepper Noise)
- 3 泊松噪声(Poisson Noise)
- 4 斑点噪声(Speckle Noise)
- 5 完整代码
参考博客:Python 使用 opencv 对图像添加噪声(高斯/椒盐/泊松/斑点)
Noise Attack
1 高斯噪声(Gaussian Noise)
高斯噪声是通过在图片中引入服从高斯分布的随机噪声来实现的。通过调整高斯分布的标准差 s i g m a \mathsf{sigma} sigma,可以控制噪声的添加程度; s i g m a \mathsf{sigma} sigma 的值越大,图片受噪声影响越严重。
def add_gaussian_noise(image):
mean = 0 # 设置高斯分布的均值
sigma = 25 # 设置高斯分布的标准差
# 根据均值和标准差生成符合高斯分布的噪声
gauss = np.random.normal(mean, sigma, image.shape)
# 添加高斯噪声
noise_attacked_image = image + gauss
# 控制添加噪声后的像素值在[0,255]之间
noise_attacked_image = np.clip(noise_attacked_image, a_min=0, a_max=255)
noise_attacked_image = noise_attacked_image.astype(np.uint8)
return noise_attacked_image
实现效果
2 椒盐噪声(Salt and Pepper Noise)
椒盐噪声是通过在图片中引入黑白噪点来实现的,其中 椒 代表黑色噪点 ( 0 , 0 , 0 ) (0,0,0) (0,0,0),盐 代表白色噪点 ( 255 , 255 , 255 ) (255,255,255) (255,255,255)。通过调整 a m o u n t \mathsf{amount} amount 参数,可以控制噪声的比例; a m o u n t \mathsf{amount} amount 值越大,图像受噪声影响越严重。
def add_salt_and_pepper_noise(image):
amount = 0.04 # 设置添加的噪声占原始图像的比例
s_vs_p = 0.5 # 设置噪声中salt和pepper的比例
noise_attacked_image = np.copy(image)
# 设置添加的salt噪声的数量
num_salt = np.ceil(amount * s_vs_p * image.size)
# 设置添加噪声的坐标位置
coords = [np.random.randint(0, i-1, int(num_salt)) for i in image.shape]
# 添加salt噪声
noise_attacked_image[coords[0], coords[1], :] = [255, 255, 255]
# 设置添加的pepper噪声的数量
num_salt = np.ceil(amount * (1 - s_vs_p) * image.size)
# 设置添加噪声的坐标位置
coords = [np.random.randint(0, i - 1, int(num_salt)) for i in image.shape]
# 添加pepper噪声
noise_attacked_image[coords[0], coords[1], :] = [0, 0, 0]
return noise_attacked_image
实现效果
3 泊松噪声(Poisson Noise)
def add_poisson_noise(image):
# 计算图像像素的分布
vals = len(np.unique(image))
vals = 2 ** np.ceil(np.log2(vals))
# 添加泊松噪声
noise_attacked_image = np.random.poisson(image * vals) / float(vals)
noise_attacked_image = noise_attacked_image.astype(np.uint8)
return noise_attacked_image
由于我不知道原理,因此无法判断上述代码的正误。比如,以下博客的实现方式就与它不同:
- 如何给图片添加泊松(Poisson)噪声(附 Python 代码)
实现效果
前者噪声图像中心有非常明显的噪声点,但是后者噪声图像却没有,这噪声攻击是见人下碟啊😇
4 斑点噪声(Speckle Noise)
def add_speckle_noise(image):
# 生成一个服从高斯分布的噪声
gauss = np.random.randn(image.shape[0], image.shape[1], image.shape[2])
# 添加speckle噪声
noise_attacked_image = image + image * gauss
# 控制添加噪声后的像素值在[0,255]之间
noise_attacked_image = np.clip(noise_attacked_image, a_min=0, a_max=255)
noise_attacked_image = noise_attacked_image.astype(np.uint8)
return noise_attacked_image
实现效果
5 完整代码
import cv2
import numpy as np
import matplotlib.pyplot as plt
def add_gaussian_noise(image):
mean = 0 # 设置高斯分布的均值
sigma = 25 # 设置高斯分布的标准差
# 根据均值和标准差生成符合高斯分布的噪声
gauss = np.random.normal(mean, sigma, image.shape)
# 添加高斯噪声
noise_attacked_image = image + gauss
# 控制添加噪声后的像素值在[0,255]之间
noise_attacked_image = np.clip(noise_attacked_image, a_min=0, a_max=255)
noise_attacked_image = noise_attacked_image.astype(np.uint8)
return noise_attacked_image
def add_salt_and_pepper_noise(image):
amount = 0.04 # 设置添加的噪声占原始图像的比例
s_vs_p = 0.5 # 设置噪声中salt和pepper的比例
noise_attacked_image = np.copy(image)
# 设置添加的salt噪声的数量
num_salt = np.ceil(amount * s_vs_p * image.size)
# 设置添加噪声的坐标位置
coords = [np.random.randint(0, i-1, int(num_salt)) for i in image.shape]
# 添加salt噪声
noise_attacked_image[tuple(coords)] = 255
# 设置添加的pepper噪声的数量
num_salt = np.ceil(amount * (1 - s_vs_p) * image.size)
# 设置添加噪声的坐标位置
coords = [np.random.randint(0, i - 1, int(num_salt)) for i in image.shape]
# 添加pepper噪声
noise_attacked_image[tuple(coords)] = 0
return noise_attacked_image
def add_poisson_noise(image):
# 计算图像像素的分布
vals = len(np.unique(image))
vals = 2 ** np.ceil(np.log2(vals))
# 添加泊松噪声
noise_attacked_image = np.random.poisson(image * vals) / float(vals)
noise_attacked_image = noise_attacked_image.astype(np.uint8)
return noise_attacked_image
def add_speckle_noise(image):
# 生成一个服从高斯分布的噪声
gauss = np.random.randn(image.shape[0], image.shape[1], image.shape[2])
# 添加speckle噪声
noise_attacked_image = image + image * gauss
# 归一化图像的像素值
noise_attacked_image = np.clip(noise_attacked_image, a_min=0, a_max=255)
noise_attacked_image = noise_attacked_image.astype(np.uint8)
return noise_attacked_image
image = cv2.imread("logo.jpg")
image = image[:, :, [2, 1, 0]]
# noise_attacked_image = add_gaussian_noise(image)
noise_attacked_image = add_salt_and_pepper_noise(image)
# noise_attacked_image = add_poisson_noise(image)
# noise_attacked_image = add_speckle_noise(image)
# 画图
plt.subplot(1, 2, 1)
plt.title("image", fontsize=12, loc="center")
plt.axis('off')
plt.imshow(image, cmap='gray')
plt.subplot(1, 2, 2)
plt.title("noise_attacked_image", fontsize=12, loc="center")
plt.axis('off')
plt.imshow(noise_attacked_image, cmap='gray')
plt.savefig('test.jpg', dpi=400, bbox_inches='tight')
plt.show()