Cómo clasificar patrones de arte generativo por belleza (ejemplo de agrupación simple con python y sklearn)

Introducción

Hace un tiempo creé este pequeño script para convertir números en patrones. No voy a explicar en detalle cómo funciona el guión, pero está inspirado en Autómatas celulares elementales de Stephen Wolfram que convierte números como 30 en binario (00011110) y luego interpreta los dígitos como encendido o apagado de 8 reglas básicas diferentes (en ese caso, hay 4 reglas activadas, regla 4, 5, 6 y 7) que definen cuándo encender y APAGADO un píxel en la imagen.

ElementaryCARule030_1000.gif

Usando esto puedo generar una cantidad infinita de patrones diferentes, el problema es que la mayoría de ellos no son realmente interesantes y no tengo tiempo para revisarlos uno por uno. Por eso en este post explico cómo traté de automatizar el proceso de encontrar los autómatas celulares más interesantes/bonitos.

Clusterización

Mi objetivo es agrupar los patrones por su belleza. Hago esto usando un algoritmo de agrupamiento basado en características frecuentemente atribuidas a la belleza, como la dimensionalidad fractal y la eficiencia de compresión. Puedes leer más sobre estas características aquí: Forsythe, Alex, et al. “Predicción de la belleza: dimensión fractal y complejidad visual en el arte”..

El código

El código completo es aquí pero también lo subí a colab aquí para que pueda ejecutar todo desde su navegador web.

Definición de atributos de agrupación

Primero defino los atributos antes mencionados, dimensión fractal (Código tomado de aquí) y puntuación de compresión (el peso de una imagen tiff sin procesar sobre su peso comprimido como imagen gif).

from fractaldimension import fractal_dimension
import cv2
import os

def fractalDimension(number):
    im = cv2.imread('images/'+str(number)+'.tiff', cv2.IMREAD_GRAYSCALE)
    newDimension = fractal_dimension(im, 0.9)
    return newDimension

def compressionScore(number):
    statinfo = os.stat('images/'+str(number)+'.gif')
    gif = statinfo.st_size # size of the file
    
    statinfo = os.stat('images/'+str(number)+'.tiff')
    tiff = statinfo.st_size # size of the file
    
    return tiff/gif

Agrupación

Hay varios algoritmos de agrupamiento, puede elegir el que mejor se adapte a su caso de uso.

sphx_glr_plot_cluster_comparison_001.png

En mi caso terminé usando Agglomerative Clustering que captura mejor los clusters generados por este conjunto de datos.

Necesitas especificar el número de clusters, probé con diferentes números, al final elegí 5 ya que los agrupaba bien desde patrones nulos hasta patrones locos y caóticos.

from sklearn.cluster import AgglomerativeClustering
import matplotlib.pyplot as plt
from matplotlib import cm

# Applying clustering algorithm
clustering = AgglomerativeClustering(n_clusters=5).fit(df[['Fractal Dimension','Compression Eficciency']].values)
df["cluster"] = clustering.labels_

# Plotting results
fig, ax = plt.subplots()
cmap = cm.get_cmap('gist_rainbow')
ax = df.plot(kind='scatter', x='Fractal Dimension', y='Compression Eficciency',cmap=cmap, c="cluster",ax=ax)
plt.show()

descargar (5).png

Resultados

Aquí muestro algunas muestras de cada clúster. Los clasifiqué desde los más simples hasta los más complejos. Como puede ver, este método es útil para identificar y descartar patrones poco interesantes, como los del Cluster 0. También es útil para identificar los patrones más hermosos, la mayoría de los mejores patrones que encontré son del Cluster 3, el que tiene grandes complejidad pero no la mayor dimensión fractal.

Clúster 0 (patrones nulos)

descargar.png

Grupo 1

descargar (1).png

Grupo 2

descargar (2).png

Grupo 3

descargar.png

Grupo 4 (Patrones locos y caóticos)

descargar (1).png

Similar Posts

Leave a Reply

Your email address will not be published.