我没有成功地尝试生成粉红噪声的二维数组。谁能解释我该怎么做?否则,是否有一个Python库可以生成2D(或更高维度)有色噪声(1/f噪声)?
此处和相关问题中给出的答案(如何生成粉红噪声图像?)为您提供了大部分图片 - 但我想我应该列出完整的逐步步骤来展示一切是如何发生的一起。
尤其是人们似乎在理解“频率矩阵”时遇到了问题。
将白噪声转换为粉红噪声
whitenoise = np.random.uniform(0, 1, (256, 256))
ft_arr = np.fft.fftshift(np.fft.fft2(whitenoise))
np.meshgrid
和 np.hypot
生成: _x, _y = np.mgrid[0:ft_arr.shape[0], 0:ft_arr.shape[1]]
f = np.hypot(_x - ft_arr.shape[0] / 2, _y - ft_arr.shape[1] / 2)
pink_ft_arr = ft_arr / f
pink_ft_arr = np.nan_to_num(pink_ft_arr, nan=0, posinf=0, neginf=0)
pinknoise = np.fft.ifft2(np.fft.ifftshift(pink_ft_arr)).real
plt.imshow
绘制此图,或将其缩放到某个合理的范围并将其写为图像。
np.random.randn
numpy.fft.fft2
)
1/f**2
矩阵,计算方式如下:
1/f_along_x * 1/f_along_y
。
这就是我如何解释N 维粉红噪声的定义,但我不确定我是否正确! 编辑:Cris Luengo 版本(请参阅下面的评论) -
1/sqrt(f_x**2+f_y**2)
- 对我来说似乎更好,但由你决定使用哪种 2d 粉红噪声定义。
,它使用 matplotlib 绘制 3D 景观。我使用正常的白噪声,而不是均匀的白噪声,并且我使用现代的 NumPy random 界面。 在我的测试中,使用
np.hypot
的频率绘制的图太尖了。正如维基百科的
粉红噪声的幂律谱中所建议的,使用这些频率的平方似乎可以给出更好的结果。
""" Pink noise surface in matplotlib
Written by PM 2Ring 2023.10.20
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
def pink_noise(size, rand, roughness):
white = rand(size=(size, size))
white_ft = np.fft.fftshift(np.fft.fft2(white))
hsize = size / 2
y, x = np.ogrid[-hsize:hsize, -hsize:hsize]
freq = (x**2 + y**2) ** (1 / roughness)
pink_ft = np.divide(white_ft, freq,
out=np.zeros_like(white_ft), where=freq!=0)
pink = np.fft.ifft2(np.fft.ifftshift(pink_ft)).real
lo, hi = np.min(pink), np.max(pink)
return (pink - lo) / (hi - lo)
def test(size=128, seed=None, roughness=1, scale=1/4):
rng = np.random.default_rng(seed)
Z = pink_noise(size, rng.normal, roughness)
Y, X = np.ogrid[0:size, 0:size]
#plt.style.use('dark_background')
fig, ax = plt.subplots(subplot_kw={"projection": "3d"}, figsize=(8, 8), constrained_layout=True)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, antialiased=False, cmap=cm.terrain)
ax.set_box_aspect((1, 1, scale))
plt.axis('off')
plt.show()
test(size=128, seed=137, roughness=1, scale=1/4)
输出
size
和
seed
的结果,但使用 roughness=2
,因此它使用上图中使用的频率的平方根。这是一个,还有一些需要调整的参数。它运行在 SageMath 服务器上,但代码大部分是纯 Python。它只是使用 Sage 来获取参数并进行交互式 3D 渲染(实际上是由 Three.js 在浏览器中完成的)。 这是
相机控件
// Orbit - left mouse / touch: one-finger move
// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish
// Pan - right mouse, or left mouse + ctrl/meta/shiftKey, or arrow keys / touch: two-finger move
右下角有一个信息菜单,可用于保存屏幕截图,或保存 HTML,以便您可以在没有 Sage 的情况下查看景观。
要生成云景,请选择“Blues_r”颜色图,然后将
scale
设置为较小的值,例如 1/20(如果您想从下面查看云,请将比例设为负值)。将
gamma
参数增加到 2 或 3 以获得更蓝的天空。