我想创建盐和胡椒噪声函数(PIL 和 Numpy)



我想创建盐和胡椒噪声函数。 输入是noise_density的,即输出图像中作为噪声的像素量,它应该返回的值是噪声图像数据源

def salt_pepper(noise_density):

noisesource = ColumnDataSource(data={'image': [noiseImage]})
return noisesource

此函数返回一个 [density]x[density] 像素的图像,使用 numpy 生成随机数组,使用 PIL 从数组生成图像本身。

def salt_pepper(density):
imarray = numpy.random.rand(density,density,3) * 255
return Image.fromarray(imarray.astype('uint8')).convert('L')

现在,例如,您可以运行

salt_pepper(500)

生成 500x500 像素的图像文件。

当然,请确保

import numpy
from PIL import Image

我想出了一个矢量化的解决方案,我相信可以改进/简化。虽然界面与请求的界面不完全一样,但代码非常简单(而且快速😬),我相信它可以很容易地适应。

import numpy as np
from PIL import Image
def salt_and_pepper(image, prob=0.05):
# If the specified `prob` is negative or zero, we don't need to do anything.
if prob <= 0:
return image
arr = np.asarray(image)
original_dtype = arr.dtype
# Derive the number of intensity levels from the array datatype.
intensity_levels = 2 ** (arr[0, 0].nbytes * 8)
min_intensity = 0
max_intensity = intensity_levels - 1
# Generate an array with the same shape as the image's:
# Each entry will have:
# 1 with probability: 1 - prob
# 0 or np.nan (50% each) with probability: prob
random_image_arr = np.random.choice(
[min_intensity, 1, np.nan], p=[prob / 2, 1 - prob, prob / 2], size=arr.shape
)
# This results in an image array with the following properties:
# - With probability 1 - prob: the pixel KEEPS ITS VALUE (it was multiplied by 1)
# - With probability prob/2: the pixel has value zero (it was multiplied by 0)
# - With probability prob/2: the pixel has value np.nan (it was multiplied by np.nan)
# We need to to `arr.astype(np.float)` to make sure np.nan is a valid value.
salt_and_peppered_arr = arr.astype(np.float) * random_image_arr
# Since we want SALT instead of NaN, we replace it.
# We cast the array back to its original dtype so we can pass it to PIL.
salt_and_peppered_arr = np.nan_to_num(
salt_and_peppered_arr, nan=max_intensity
).astype(original_dtype)
return Image.fromarray(salt_and_peppered_arr)

你可以像这样加载黑白版本的莉娜:

lena = Image.open("lena.ppm")
bwlena = Image.fromarray(np.asarray(lena).mean(axis=2).astype(np.uint8))

最后,您可以保存几个示例:

salt_and_pepper(bwlena, prob=0.1).save("sp01lena.png", "PNG")
salt_and_pepper(bwlena, prob=0.3).save("sp03lena.png", "PNG")

结果:

https://i.ibb.co/J2y9HXS/sp01lena.png

https://i.ibb.co/VTm5Vy2/sp03lena.png

最新更新