用Python编写程序生成叶子纹理效果
发布时间:2023-12-29 18:51:50
叶子纹理是指模拟叶子表面的纹理效果,常见的有网状纹理、脉络纹理等。在Python中,可以使用一些库和算法来生成叶子纹理效果。
一种常用的方法是使用Perlin噪声生成叶子纹理。Perlin噪声是一种可以生成自然连续随机噪声的数学算法。它可以用来模拟自然界中的纹理、地貌、云层等。
下面是一个使用Python和Perlin噪声生成叶子纹理效果的例子:
import numpy as np
from PIL import Image
def perlin_noise_2d(shape, res):
def smoothstep(t):
return t * t * (3 - 2 * t)
def lerp(t, a, b):
return a + t * (b - a)
def gradient(h, x, y):
vectors = np.array([[0, 1], [0, -1], [1, 0], [-1, 0]])
g = vectors[h % 4]
return g[:, :, 0] * x + g[:, :, 1] * y
def fade(t):
return 6 * t ** 5 - 15 * t ** 4 + 10 * t ** 3
shape = (shape[0] // res[0], shape[1] // res[1], res[0] + 1, res[1] + 1)
delta = (np.random.rand(shape[0], shape[1], 2, 2) * 2 - 1) * 2
px = np.arange(shape[2], dtype=np.uint8)
py = np.arange(shape[3], dtype=np.uint8)
fx = fade(px / res[0] % 1)
fy = fade(py / res[1] % 1)
x = np.repeat(np.repeat(px, shape[0], axis=0), shape[1], axis=1).reshape(shape[:2] + (-1,))
y = np.repeat(np.repeat(py, shape[0], axis=0), shape[1], axis=1).reshape(shape[:2] + (-1,))
g00 = gradient(np.random.randint(0, len(gp)), x, y)
g10 = gradient(np.random.randint(0, len(gp)), x - 1, y)
g11 = gradient(np.random.randint(0, len(gp)), x - 1, y - 1)
g01 = gradient(np.random.randint(0, len(gp)), x, y - 1)
n00 = np.sum(g00 * delta[:, :, 0, 0], 2) * (fx - 0) + np.sum(g00 * delta[:, :, 0, 1], 2) * (fy - 0)
n10 = np.sum(g10 * delta[:, :, 1, 0], 2) * (fx - 1) + np.sum(g10 * delta[:, :, 1, 1], 2) * (fy - 0)
n11 = np.sum(g11 * delta[:, :, 2, 0], 2) * (fx - 1) + np.sum(g11 * delta[:, :, 2, 1], 2) * (fy - 1)
n01 = np.sum(g01 * delta[:, :, 3, 0], 2) * (fx - 0) + np.sum(g01 * delta[:, :, 3, 1], 2) * (fy - 1)
return lerp(lerp(smoothstep(fx), n00, n10), lerp(smoothstep(fx), n01, n11), smoothstep(fy))
def leaf_texture(width, height, scale_x=0.02, scale_y=0.02, noise_scale=0.1):
# 生成纹理噪声图像
noise = perlin_noise_2d((height, width), (int(width * scale_x), int(height * scale_y)))
noise = (noise + 1) / 2 # 将噪声值映射到[0, 1]范围
# 根据噪声图像生成叶子纹理
texture = np.zeros((height, width, 3), dtype=np.uint8) # 创建纹理图像
noise = np.clip(noise * 255, 0, 255).astype(np.uint8) # 将噪声值映射到[0, 255]范围
texture[:, :, 1] = noise # 将噪声值作为绿色通道值
# 添加叶子脉络效果
veins = int(min(width, height) * noise_scale)
for _ in range(veins):
x = np.random.randint(0, width)
y = np.random.randint(0, height)
radius = np.random.randint(2, 5)
value = np.random.randint(50, 150)
for i in range(x - radius, x + radius + 1):
for j in range(y - radius, y + radius + 1):
if i >= 0 and i < width and j >= 0 and j < height:
intensity = (radius - np.sqrt((i - x) ** 2 + (j - y) ** 2)) / radius
texture[j, i, 0] = int(intensity * value)
return texture
# 生成叶子纹理图像并保存
texture = leaf_texture(512, 512)
image = Image.fromarray(texture)
image.save("leaf_texture.png")
上述代码中,perlin_noise_2d函数用于生成2D Perlin噪声图像。函数首先定义了一些辅助函数和参数,如smoothstep函数用于平滑插值,lerp函数用于线性插值,gradient函数用于计算梯度,fade函数用于平滑变换。然后,函数通过生成随机向量和插值计算生成2D Perlin噪声图像。
leaf_texture函数中,首先调用perlin_noise_2d函数生成纹理噪声图像,然后根据噪声图像生成叶子纹理。生成的纹理噪声图像通过映射到[0, 1]范围后,作为绿色通道值。接着,通过添加叶子脉络效果,即随机在图像上生成一些半径为2-5像素的圆形区域,并将圆形区域内的像素值设置为随机强度值,以模拟叶子的脉络效果。
运行以上代码,将生成一张512x512像素的叶子纹理图像,并保存为"leaf_texture.png"文件。
综上所述,使用Python和Perlin噪声可以快速生成叶子纹理效果。可以根据需要调整生成纹理的尺寸、比例和噪声参数等,以获得不同风格和细节的叶子纹理效果。
