Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I implement red noise?

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

enter image description here

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?

like image 247
Martin Thoma Avatar asked Jan 19 '16 22:01

Martin Thoma


People also ask

What does red noise do?

Some people use the term "red noise" to refer to a system in which power density decreases as frequencies increase.

What is red noise data?

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.

Why is it called red noise?

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.


1 Answers

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.

like image 123
cr1msonB1ade Avatar answered Oct 11 '22 12:10

cr1msonB1ade