Generate white noise in 2D
Update:
Just for fun, here's the process I think you were trying to implement. Wikipedia suggested to me that it was called pink noise, so we'll use pink names.
pinkify =
Compile[
{{data, _Complex, 2}, {center, _Real, 1}, {p, _Real}},
MapIndexed[
#/(Norm[#2 - center]^p) &,
data,
{2}
]
];
pinkNoiseTransform[
data : {{__}, ___},
center : {_?NumericQ, _?NumericQ} | Automatic : Automatic,
p : _?NumericQ : 1,
fn : Except[_?NumericQ] : Abs
] :=
Map[
fn,
InverseFourier@
pinkify[Fourier[data],
If[IntegerQ[#], # + .8, #] & /@
Replace[center, Automatic :> Dimensions[data]/2],
p
],
{2}
];
pinkNoiseTransform[i : _Integer | {_Integer, _Integer}, r___] :=
pinkNoiseTransform[whiteNoise2D[i], r]
I think the center point we assign minus the position in the matrix is f
, so that's what I'm using 1/f
.
Here's an example:
dims = {100, 100};
data = whiteNoise2D[dims];
centralFrequency = dims/2;
power = 1.8;
pinky = pinkNoiseTransform[data, centralFrequency, power, Norm];
Image[
Rescale[pinky, MinMax[pinky], {1, 0}],
ColorSpace -> "Grayscale",
ImageSize -> {300, 300},
Interleaving -> True
]
One cool thing is that we can use the Re
and Im
parts of our data as different channels:
rePink =
pinkNoiseTransform[data, centralFrequency, power, Re];
imPink =
pinkNoiseTransform[data, centralFrequency, power, Im];
Image[
MapThread[
List,
{
Rescale[pinky, {0, 1}, {1, 0}],
Rescale[rePink, {0, 1}, {1, 0}],
Rescale[imPink, {0, 1}, {1, 0}]
},
2],
ColorSpace -> "RGB",
ImageSize -> {300, 300},
Interleaving -> True
]
Finally, here's some 3D terrain from a smaller version of this (note that anything except PerformanceGoal->"Speed"
gives too jagged as surface):
terrain =
Join @@
MapIndexed[
Append[#2, #] &,
pinkNoiseTransform[350, centralFrequency, power],
{2}
];
ListPlot3D[terrain,
ColorFunction -> "GreenBrownTerrain",
PerformanceGoal -> "Speed"
]
I think you've got the wrong idea about what it's generating. The 2
simply means do 2 traces.
Try this:
whiteNoise2D[n_Integer] :=
whiteNoise2D[{n, n}];
whiteNoise2D[{n_, m_}] :=
RandomFunction[WhiteNoiseProcess[], {0, n}, m]["ValueList"];
whiteNoiseImage[{n_, m_}, size_: Automatic] :=
Image[whiteNoise2D[{n, m}],
ImageSize -> Replace[size, Automatic :> {n, m}]
]
Image[Rescale[whiteNoise2D[{500, 500}]],
ImageSize -> {250, 250}]
We can use RandomVariate
like this to generate white noise:
RandomVariate[UniformDistribution[], {256, 256}] // Image
RandomVariate[NormalDistribution[], {256, 256}] // Image
To just get the image, there is also RandomImage
:
RandomImage[]
RandomImage[NormalDistribution[]]
The underlying data can be retrieved using ImageData
.
The 3D visualization in the screenshot in the question is the same underlying data visualized with a ListPlot3D
like function:
ListPlot3D[
RandomVariate[UniformDistribution[], {256, 256}],
ColorFunction -> GrayLevel
]
ListPlot3D[
RandomVariate[NormalDistribution[], {256, 256}],
ColorFunction -> GrayLevel
]