利用PerlinNoise实现图像雾化效果的python代码
时间: 2023-12-28 15:04:46 浏览: 102
下面是利用Perlin Noise实现图像雾化效果的Python代码,需要使用到numpy和Pillow库:
```python
import numpy as np
from PIL import Image
# 生成Perlin Noise噪声矩阵
def generate_perlin_noise(shape, res=16):
lin = np.linspace(0, 1, res+1, endpoint=False).reshape(-1, 1)
X, Y = np.meshgrid(lin, lin)
grid = np.stack((X, Y), axis=-1)
grid_shape = (res, res, 1, 2)
grid = np.pad(grid, ((0, 1), (0, 1), (0, 0), (0, 0)), mode='wrap')
grid = np.reshape(grid, grid_shape)
noise_shape = (shape[0]//res, shape[1]//res, 1, 2)
noise = np.random.normal(size=noise_shape)
corners = np.array([[[0,0], [0,1], [1,0], [1,1]]]).repeat(noise_shape[0], axis=0).repeat(noise_shape[1], axis=1)
dot_products = np.sum(np.concatenate((corners, noise), axis=-1) * grid, axis=-1)
weights = fade(np.modf(X*res)[0]), fade(np.modf(Y*res)[0])
weights = np.repeat(np.expand_dims(weights, axis=-1), 2, axis=-1)
noise = np.sum(weights * dot_products, axis=-2)
return noise
# 平滑处理
def smoothstep(x):
return x * x * (3 - 2 * x)
# 加权平均
def lerp(a, b, t):
return a + t * (b - a)
# 淡化函数
def fade(t):
return smoothstep(t)
# 将图像转为灰度图像
def gray_scale(image):
return image.convert('L')
# 二值化处理
def binary(image, threshold):
return image.point(lambda x: 255 if x>threshold else 0)
# 图像雾化
def fog(image, noise_scale=10, noise_res=16, smooth_scale=30, threshold=150):
# 将图像转为灰度图像
gray_image = gray_scale(image)
# 生成Perlin Noise噪声矩阵
noise = generate_perlin_noise(gray_image.size, res=noise_res)
# 平滑处理
smooth_noise = np.zeros_like(noise)
for y in range(smooth_noise.shape[0]):
for x in range(smooth_noise.shape[1]):
smooth_noise[y, x] = np.mean(noise[max(0,y-smooth_scale):min(smooth_noise.shape[0],y+smooth_scale), max(0,x-smooth_scale):min(smooth_noise.shape[1],x+smooth_scale)])
# 加权平均
new_image = Image.new('L', gray_image.size)
for y in range(new_image.size[1]):
for x in range(new_image.size[0]):
t = smooth_noise[y//noise_scale, x//noise_scale]
new_image.putpixel((x, y), int(lerp(gray_image.getpixel((x, y)), 255, t)))
# 二值化处理
new_image = binary(new_image, threshold)
# 叠加原图像
result_image = Image.new('RGBA', image.size, (255, 255, 255, 0))
result_image.paste(image, (0, 0), new_image)
return result_image
# 测试代码
if __name__ == '__main__':
image = Image.open('test.jpg')
result_image = fog(image)
result_image.show()
```
需要说明的是,上述代码中的Perlin Noise算法实现参考自[这里](https://github.com/FlorianWilk/perlin-noise/blob/master/perlin_noise.py)。
阅读全文