How to generate noise in an image using python?

11

How to generate periodic noise of type Moiré in a grayscale image using Python?

    
asked by anonymous 22.02.2014 / 02:17

2 answers

1

This was the solution I came up with (it may not be the most elegant, or the most efficient, but served its purpose):

    from scipy import misc
    import numpy as np

    orig = misc.imread('bear_original.jpg')
    sh = orig.shape[0], orig.shape[1]
    noise = np.zeros(sh, dtype='float64')

    X, Y = np.meshgrid(range(0, sh[0]), range(0, sh[1]))

    A = 40
    u0 = 45
    v0 = 50

    noise += A*np.sin(X*u0 + Y*v0)

    A = -18
    u0 = -45
    v0 = 50

    noise += A*np.sin(X*u0 + Y*v0)

    noiseada = orig+noise
    misc.imsave('bearnoise.jpg', noiseada)

Noise

Noise applied to the image

    
26.02.2014 / 01:07
9

Based on the concept of Moiré from Wikipedia and a little of Analytical Geometry , I created a small routine to apply the effect to an image overlapping with itself.

Follow the routine:

from PIL import Image
import math

def moire(source, target, angle, distance, offsetx = 2, offsety = 2):

    #imagem de entrada
    img = Image.open(source)
    pm = img.load()
    # imagem de saída (usando a mesma para gerar sobreposição)
    imgout = Image.open(source)
    pmout = imgout.load()

    # valores para as transformações    
    cosseno = math.cos(angle)
    seno = math.sin(angle)
    # distância em cada eixo
    dx = distance * cosseno 
    dy = distance * seno

    for x in range(0, img.size[0], offsetx):
        for y in range(0, img.size[1], offsety):
            # calcula coordenada transformada (rotação + deslocamento)
            x2, y2 = dx + math.floor(x * cosseno - y * seno), dy + math.floor(x * seno + y * cosseno)
            # ajusta valores fora da imagem (como se a mesma repetisse infinitamente)
            if x2 < 0:
                x2 = img.size[0] + x2
            elif x2 >= img.size[0]:
                x2 = x2 - img.size[0]
            if y2 < 0:
                y2 = img.size[1] + y2
            elif y2 >= img.size[1]:
                y2 = y2 - img.size[1]
            # desenha ponto transformado 
            pmout[x, y] = pm[x2, y2] 

    # salva a imagem
    imgout.save(target)

Note that in the first line I do the import of the Pillow image library.

Next is the function that receives the following parameters:

  • source : input image
  • target : location where to save result
  • angle : moiré angle, that is, how much the image will be rotated
  • distance : distance of the moiré, that is, how much the image will be shifted from its origin in relation to the angle informed
  • offsetx : how often the moiré points will be applied in the x coordinate, that is, the 1 value indicates that all pixels will be processed, the 2 value indicates that one pixel is simulated and another is not and so on.
  • offsety : idem to previous in coordinate y
  • Examples

    Date the image:

    Example1

    # gira a imagem em 45º e aplica o efeito em todos os pontos moire(r'linhas.png', r'linhas-output-1.png', math.pi / 4, 0, 1, 1)

    Example2

    # gira 30º, ponto sim, ponto não, e desloca 50 pixels nesse ângulo moire(r'linhas.png', r'linhas-output-2.png', math.pi / 3, 50, 2, 2)

    Example3

    # gira 18º e desenha apenas a cada 5 pontos moire(r'linhas.png', r'linhas-output-3.png', math.pi / 5, 0, 5, 5)

        
    24.02.2014 / 18:27