- Curvas RGB no lineales
- Desaturación de color
- Rotación de tono
Ya he hecho en el pasado ejercicios de este tipo con curvas, pero solo sirven para procesados que respondan a una curva. Aquí vamos a por todas (cambios de saturación y color sin contemplaciones).
En definitiva es un procesado que convierte una foto así...
...en este churro (lo bonito o feo de la imagen es lo de menos, se trata de ponérselo difícil a la red neuronal):
El proceso es el siguiente: se le "enseña" a la red neuronal cómo se transforma cada combinación (R, G, B) de entrada en una combinación (R', G', B') de salida; este conjunto de datos es lo que se llama training set. Para ello he tomado una imagen que tiene todos los posibles colores de 8 bits (la original es de 17Mpx):
Y le he aplicado el procesado anterior:
Aunque hablemos de imágenes, la red neuronal no tiene ni idea de que está tratando con imágenes. Ella lo único que hace es un modelo de regresión para una función de R3 -> R3 (es decir, es un ejercicio puro de aproximación de funciones, un punto fuerte de las redes neuronales).
Entonces se entrena la red con ciertos parámetros (en concreto he usado una red de una sola capa oculta con 32 nodos, teniendo las capas de entrada y salida 3 nodos, los correspondientes a los canales RGB):
- Código: Seleccionar todo
# NN training hyperparameters
regr = MLPRegressor(solver='adam', # solver 'sgd', lbfgs'
alpha=0, # no L2 (ridge regression) regularization
hidden_layer_sizes=32, # nodes
activation='logistic', # hidden layer activation function (default 'relu')
# 'logistic' (sigmoid) seems more adequate to model continuous functions
max_iter=30, # max epochs
tol=0.00001, # tolerance for early stopping
n_iter_no_change=10, # number of epochs to check tol
verbose=True) # tell me a story
regr.out_activation_ = 'relu' # output layer activation function (default 'identity')
# 'relu' seems a good idea since RGB values can only be positive
Ésta sería una red de solo 6 nodos en la capa oculta; en el ejercicio he usado 32 que sigue siendo una red muy simple para las barbaridades que se ven por ahí en otros ámbitos:
Una vez entrenada queda configurada la red. Aunque el proceso que está modelando es muy complejo, la red se define de manera muy sencilla con apenas unos ~200 números (menos que una curva de Luminosidad de Photoshop). Hay que pensar que estamos modelando 17 millones de posibles transformaciones con solo esos 200 valores, es la magia de las redes neuronales que logran cosas bastante complejas con tan solo aplicar esta simple operación de sumatorio + función de activación en cada nodo (esos pesos wi son los valores numéricos que comentaba):
El paso final es aplicar la red a imágenes que le son desconocidas (la red nunca las ha "visto"), lo que se llama un test set, para comparar la aproximación que hace la red con el procesado exacto que se obtiene en Photoshop y decidir cómo de bien hace la red neuronal su aproximación. Me queda por probar más cosas y optimizar, pero los resultados son prometedores (donde peor funciona es en las sombras profundas y también diluye contraste, pero los colores son muy próximos).
La precisión de los modelos se puede medir numéricamente con varios indicadores, pero como aquí se trata de imágenes es mucho más visual y divertido simplemente mirarlas para ver si la aproximación es buena o mala. 2 ejemplos:
Imagen original:
Procesado exacto:
Predicción de la red neuronal:
Imagen original:
Procesado exacto:
Predicción de la red neuronal:
Aplicaciones que se me ocurren:
- Emular el procesado JPEG de cámara de cualquier modelo
- Copiarle a fulanito ese procesado que deja las imágenes molonas y que fulanito no quiere contar
- Hacer la ingeniería inversa de filtros de cine que dan ese look tan cinematográfico
- Hacer ingeniería inversa de cualquier tipo de filtros (Instagram, NIK,...)
- Emular películas antiguas (Kodachrome, Velvia,...)
- Modelar procesos cruzados de película
Si tenéis algún procesado que os gusta mucho me lo podéis pasar; eso sí, necesito imagen con y sin el procesado (es lo que se llama aprendizaje supervisado: para poder modelar un sistema, necesitamos muestras de la salida exacta que producen determinadas combinaciones de las variables de entrada del sistema).
Salu2!