I've just read the red noise article after a professor mentioned it in a lecture.
My idea was to start with a random number in {0,..., 255}. Then I finish the first row from left to right by adding a random offset in {0, ..., 255}. As soon as the first line is finished, I will take the average of the upper and the left element and add a random offset for the next pixel.
This way, I create the image from left to right, top to bottom.
I've implemented it like this:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Create a red noise RGB image of the dimensions you want."""
import numpy
import Image
import random
def create_red_noise(outfile, width, height, r=10):
"""
Create red noise RGB image
Parameters
----------
outfile : str
width : int
height : int
r : int
Random maximum offset compared to the last pixel
"""
array = numpy.random.rand(height, width, 3) * 255
for x in range(width):
for y in range(height):
if y == 0:
if x == 0:
continue
else:
for i in range(3):
array[y][x][i] = (array[y][x-1][i] +
random.randint(-r, r))
else:
if x == 0:
for i in range(3):
array[y][x][i] = (array[y-1][x][i] +
random.randint(-r, r))
else:
for i in range(3):
array[y][x][i] = (((array[y-1][x][i] +
array[y-1][x-1][i]) / 2.0 +
random.randint(-r, r)))
im_out = Image.fromarray(array.astype('uint8')).convert('RGBA')
im_out.save(outfile)
def get_parser():
"""Get parser object for create_random_image.py."""
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
parser = ArgumentParser(description=__doc__,
formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument("-f", "--file",
dest="filename",
help="write red noise image to FILE",
default="red-noise.jpg",
metavar="FILE")
parser.add_argument("-x", "--width",
dest="width",
default=1280,
type=int,
help="width of the image")
parser.add_argument("-y", "--height",
dest="height",
default=960,
type=int,
help="height of the image")
parser.add_argument("-o", "--offset",
dest="offset",
default=10,
type=int,
help="maximum offset compared to the neighbors")
return parser
if __name__ == "__main__":
args = get_parser().parse_args()
create_red_noise(args.filename, args.width, args.height, args.offset)
which gives
It looks cool. However, I think it should look more like this: https://commons.wikimedia.org/wiki/File:Red.noise.col.png
What am I doing wrong / how can I fix it?
Some people use the term "red noise" to refer to a system in which power density decreases as frequencies increase.
Such an autocorrelation model is called red noise, or a first order Markov process, or damped persistence. The latter term refers to the fact that as the correlation increases the equation approximates more and more closely persistence with some added noise. It represents a stochastic (noisy) process with some memory.
The term "red noise" comes from the "white noise"/"white light" analogy; red noise is strong in longer wavelengths, similar to the red end of the visible spectrum.
I think the issue might be when you are calculating the correlated value when you have a valid position to the left and above. You have:
array[y][x][i] = (((array[y-1][x][i] +
array[y-1][x-1][i]) / 2.0 +
random.randint(-r, r)))
I think this should be:
array[y][x][i] = (((array[y-1][x][i] +
array[y][x-1][i]) / 2.0 +
random.randint(-r, r)))
In your version you are taking the average of the pixel above and diagonlly above and to the left when you actually want the pixel above and the pixel to the left.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With