Crea Arte Generativo con una fotografía

He pensado que puede ser una buena idea crear arte generativo a partir de una fotografía para el segundo tutorial de la nueva categoría de arte generativo con Python.

Convertiremos una imagen PIL en un array Numpy.
Si nunca has oído hablar de estas librerías de Python no te preocupes, el ejemplo que vamos a crear es muy sencillo.

Modificar fotografía con Python

Antes de nada debemos entender la fotografía digital que vamos a utilizar como una serie de píxeles representados en pantalla, y cada uno de ellos relleno de un determinado color que se forma con 3 valores (RGB). Para rellenar estos valores RGB emplearemos la misma forma que hemos utilizado en el tutorial de arte generativo anterior.

Si abrimos una fotografía con algún editor de fotografías como por ejemplo Gymp (OpenSource y maravilloso) y haces mucho MUCHO zoom, podrás observar que cualquier fotografía digital «está formada por píxeles de diferentes colores repartidos».

En la mitad derecha de esta imagen se aprecia perfectamente esto que te digo.

¿Y si cambiamos el color de algunos de estos píxeles?

Para poder modificar el color de estos píxeles lo primero que debemos tener es acceso a ellos, la mejor forma es guardarlos en un array, que será lo siguiente que hagamos.

Imagen PIL en Array Numpy

Para transformar nuestra imagen en un array trabajaremos con las librerías PIL y Numpy.

import numpy as np
from PIL import Image

Ahora guardaremos la información correspondiente de cada píxel dentro de nuestro array.

image = Image.open('EneaRadio.png')
arr = np.array(image)

La fotografía base sin modificar con la que voy a trabajar es esta, un simple .png de 400 x 400 px.

Si accedemos a los valores del array y le modificamos su valor, podremos cambiar de color cada uno de los píxeles de nuestra imagen, dejando el resto sin modificar. No podemos olvidar que el valor de cada píxel está compuesto por un array de 3 valores (RGB).

Con la siguiente línea de código accederemos a las posiciones de nuestro array avanzando de 10 en 10 y cada píxel lo rellenaremos con un color RGB (100, 200, 100). Quedando la imagen como veremos a continuación.

arr[::10, ::10] = [100, 200, 100]

Recorremos nuestra imagen de izquierda a derecha y de arriba hasta abajo, para dar el salto de 10 en 10 píxeles y modificar el color recorremos el array utilizando [::10, ::10], haciendo referencia a los 2 ejes (x,y).

Vamos a configurar nuestros saltos de dos formas diferentes:

  • [::1, ::10]
  • [::10, ::1]
[::1, ::10]
[::10, ::1]

Ahora añadiremos un par de estructuras for para recorrer los 400 píxeles de nuestra imagen (ancho y alto).

for i in range(400):
    for j in range(400):
        arr[random.randint(i, 400), random.randint(j, 400)] = [100, 200, 100]

A nuestro diseño anterior le agregamos una línea más de código para dibujar píxeles con un color azul.

for i in tqdm(range(imagen_size)):
    for j in range(imagen_size):
         arr[random.randint(i, 400), random.randint(j, 400)] = [100, 200, 100]
         arr[random.randint(1, 400), random.randint(1, 400)] = [50, 50, 200]

Podríamos decir que ya va tomando un aspecto bastante divertido. Los colores verde y azul de nuestra obra de arte generativo con Python están definidos de la siguiente forma.

  • Para el verde [100, 200, 100]
  • Para el azul [50, 50, 200]

Ahora vamos a indicarle que el relleno de colores sea completamente aleatorio y que cubra todo el rango de 0 a 255 para cada uno de estos dos colores. Quedando nuestro código de la siguiente forma.

Generative Art Python

Así ha quedado nuestro ejemplo, espero que disfrutes creando tus propias obras.

import numpy as np
from numpy import random
from PIL import Image
from tqdm import tqdm

image = Image.open('EneaRadio.png')
arr = np.array(image)

for i in tqdm(range(400)):
    for j in range(400):
         arr[random.randint(i, 400), random.randint(j, 400)] = [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]
         arr[random.randint(1, 400), random.randint(1, 400)] = [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]

pil_image=Image.fromarray(arr)
pil_image.save('Untitled-generative.png')
pil_image.show()

Arte Generativo

Arte generativo con Python

Este es el primer ejemplo de una serie de tutoriales de arte generativo que tengo en mente crear. Empezaré con Arte generativo con Python pero tengo pensado utilizar varios lenguajes de programación.

Por si no sabes qué es el arte generativo.

Generative Art with Python

El objetivo principal de que esté creando esta entrada sobre arte generativo es la misma que en tutoriales anteriores para otras tecnologías, poder consultar en el futuro y no tener que volverme loco navegando por diferentes carpetas y sitios web.

Para este ejemplo en concreto trabajaremos con las librerías de Python: PIL, numpy y tqdm.

Descubre más: Librería PIL para PythonLibrería numpyLibrería para barras de progreso tqdm.

Sencillo ejemplo para crear Arte generativo con Python.

  • Importamos librerías necesarias para este ejemplo de arte generativo con Python.
  • Creamos el array de píxeles y los rellenamos de color (veremos 3 variantes).
  • Formamos la imagen con los píxeles que hemos rellenado anteriormente.
  • Mostramos la imagen.
  • Guardamos la imagen con el nombre de generative numpy.

Importamos las librerías

from PIL import Image, ImageDraw
import numpy as np
from numpy import random
from tqdm import tqdm

Generamos el array y formamos la imagen

imagen_size = 1000
arr = np.zeros([imagen_size, imagen_size, 3], dtype=np.uint8)

for i in tqdm(arr):
    arr[::1, ::random.randint(1, imagen_size/2)] = [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]

img = Image.fromarray(arr)
dibujar_imagen = ImageDraw.Draw(img)
img.show()
img.save('generative-numpy.png')

Si ejecutamos nuestro archivo .py con este script sin modificar nada obtendríamos un resultado similar a la Imagen 1. Digo similar porque el color de las barras verticales es aleatorio, así que me extraña que salgan dos iguales.

generative art numpy
Imagen 1

En el bucle for he añadido una sencilla barra de progreso para que la impaciencia no se apodere de nuestro cuerpo con algunos ejemplos más pesados.

Para que veas lo sencillo que es ver algunas modificaciones en el resultado, voy a modificar una sola línea de código, exactamente la que está dentro de nuestro bucle for.

arr[::1, ::random.randint(1, imagen_size/2)] = [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]

Con esta línea que acabamos de ver le indicamos a nuestro array los valores RGB que van a formar nuestra imagen de la siguiente forma:

En cada posición que recorremos en nuestro array:

arr[::1, ::random.randint(1, imagen_size/2)] =

Generamos tres números aleatorios de entre 0 y 255

[random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]

Generative Image 2

Vamos a ver el resultado en la Imagen 2, modificando estos tres valores, dejaré aleatorio únicamente el último, para los otros dos colocaré el valor 0, quedando la línea de la siguiente forma:

arr[::1, ::random.randint(1, imagen_size/2)] = [0, 0, random.randint(0, 255)]

No es muy de extrañar que una imagen que tiene sus píxeles configurados de esta forma salga azul.

  • Red = 0
  • Green = 0
  • Blue = número aleatorio entre 0 y 255
Imagen 2

Generative Image 3

Por último cambiaré la configuración para que salga mucho más verde la imagen 3.

arr[::1, ::random.randint(1, imagen_size/2)] = [0, random.randint(0, 255), 0]
  • Red = 0
  • Green = número aleatorio entre 0 y 255
  • Blue = 0
Imagen 3

Con este pequeño ejemplo sobre arte generativo con Python doy por terminado el tutorial. Recuerda que aparte de modificar el valor de los colores para cada pixel, puedes modificar también la forma de recorrer el array con numpy y mucho más.