# Adding noise to a raster

I want to add some fine-grained noise to a raster in an automated python process (i.e. I do not want to use Photoshop or GIMP). I looked at PIL, but unless I'm mistaken, it doesn't seem to have any modules for adding noise. So, I'm thinking of using NumPy to create an array of Gaussian values in the three bands (RGB) and then add that to the raster (imported as an array to NumPy).

However, I'm sure somebody on the forum has done this sort of thing before and I imagine there could be better ways of going about it.

Does anybody have a recipe for adding noise to a raster using python (possibly with GDAL/Numpy/PIL/or something else).

Many thanks

EDIT:
Following Aragon's suggestion, I had a look at the noise module, but I need to use Python 3.2 and this module is quite old (2009) and is for Python 2.x. So I decided to have a go at porting to 3 using the '2to3.py' tool. All goes well until I run setup.py, where I get the following error:

running install
running build
running build_py
creating build
creating build\lib.win32-3.2
creating build\lib.win32-3.2\noise
copying perlin.py -> build\lib.win32-3.2\noise
copying __init__.py -> build\lib.win32-3.2\noise
running build_ext
building 'noise._simplex' extension
creating build\temp.win32-3.2
creating build\temp.win32-3.2\Release
c:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\cl.exe /c /nologo /Ox /MD /W
3 /GS- /DNDEBUG -Ic:\python32\include -Ic:\python32\PC /Tc_simplex.c /Fobuild\te
mp.win32-3.2\Release\_simplex.obj
_simplex.c
_simplex.c(224) : warning C4013: 'Py_InitModule3' undefined; assuming extern ret
urning int
_simplex.c(225) : warning C4047: '=' : 'PyObject *' differs in levels of indirec
tion from 'int'
c:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\link.exe /DLL /nologo /INCRE
MENTAL:NO /LIBPATH:c:\python32\libs /LIBPATH:c:\python32\PCbuild /EXPORT:PyInit_
_simplex build\temp.win32-3.2\Release\_simplex.obj /OUT:build\lib.win32-3.2\nois
e\_simplex.pyd /IMPLIB:build\temp.win32-3.2\Release\_simplex.lib /MANIFESTFILE:b
uild\temp.win32-3.2\Release\_simplex.pyd.manifest
LINK : error LNK2001: unresolved external symbol PyInit__simplex
build\temp.win32-3.2\Release\_simplex.lib : fatal error LNK1120: 1 unresolved ex
ternals
error: command '"c:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\link.exe"'
failed with exit status 1120


Any suggestions (either for an alternative library to try or how to port this one from 2 to 3)? Should I take this to the main Stack Exchange site as we're drifting away from GIS now

Thanks

-
Not knowing your intention for burning the noise into your raster, would it be appropriate to consider creating an equally-sized, transparent image of Perlin noise, then use it as an overlay? –  elrobis Apr 27 '12 at 14:05
What kind of noise do you need? What statistical properties should it have? Beware even simple solutions. After all, merely adding a random amount to each byte is likely to over- and under- flow them, which can produce bizarre artifacts. Statistical requirements for "noise" added for purely visual purposes are small, but if the noise is attempting to model uncertainty, then care is needed in constructing it to match the desired statistical properties. –  whuber Apr 27 '12 at 14:56
That would do and is pretty much the sort of thing I was considering doing using NumPy. I will be happy with overlaying as you suggest or 'noisifying' my raster directly. –  MappaGnosis Apr 27 '12 at 15:04
@whuber This is a purely visual effect for cartographic purposes. I am generating a colourmap from a DTM in GDAL and need to give it a more fuzzy texture to match a proscribed cartographic look - so I am not modelling uncertainty here. Perlin Noise as per Aragon's example with wavelength 1 and frequency 1 is ideal. –  MappaGnosis Apr 27 '12 at 15:07

you can use Perlin noise for Python tool. from wiki:

Perlin noise is a procedural texture primitive, a type of gradient noise used by visual effects artists to increase the appearance of realism in computer graphics. The function has a pseudo-random appearance, yet all of its visual details are the same size (see image). This property allows it to be readily controllable; multiple scaled copies of Perlin noise can be inserted into mathematical expressions to create a great variety of procedural textures. Synthetic textures using Perlin noise are often used in CGI to make computer-generated visual elements - such as fire, smoke, or clouds - appear more natural, by imitating the controlled random appearance of textures of nature. It is also frequently used to generate textures when memory is extremely limited, such as in demos, and is increasingly finding use in Graphics Processing Units for real-time graphics in computer games.

installation:

 pip install noise


example:

other examples:

i hope it helps you...

-
That module looks great, except it doesn't look like it is available for Python 3.2 (which I am restricted to using). I don't see it in the unofficial repositories for 3.x either. Any idea if there is a 3.2 version or equivalent? –  MappaGnosis Apr 27 '12 at 11:22
While I watch this space for any further suggestions, I am going to try porting the noise module to Python 3.2. I managed to port Shapely and this looks a lot smaller. I'll report back... –  MappaGnosis Apr 27 '12 at 11:56
cant you install old version of python for this. and dont forget it that synchronization of modules to python 3.x will take longer... –  Aragon Apr 27 '12 at 15:27
Yes and no. I have to use Python 3.2 because it is the basis for an IDE in another program into which I am importing GDAL etc. So, I could maybe try installing an older version of python, writing a script to do the noise-thing and then calling that in the old python as a subprocess of Python 3.2. While that SHOULD work, it strikes me as a bit nasty. –  MappaGnosis Apr 27 '12 at 15:32
I'm going to mark Aragon's solution as the accepted answer because, for most people it will work and would have worked for me if I wasn't insisting on using Python 3.2! –  MappaGnosis Apr 30 '12 at 9:10

In reply to my own question, using Numpy appears to have some potential. You can very quickly generate a 'noise array' using one of a few different statistical distributions depending on your use-case, having queried your raster first to get the column and row dimensions.

I went for a Gausian distribution using the numpy.random.randn() function. This worked but was not quite the visual effect I really wanted.

In the end I created a small 256x256 noise image in GIMP and applied it as a tiled multiply overlay to my height-field colour raster. This allowed me to apply a very fine grain fuzziness to a raster with a much coarse resolution. I can re-use the same 'noise image' over and over, so this meets my automation criteria.

-