Este es el código fuente y el modelo previamente entrenado para la demostración de la cámara web pix2pix que publiqué recientemente en Twitter y Vimeo. Utiliza aprendizaje profundo, o para agregar algunas palabras de moda: codificador automático de red adversarial generativo condicional convolucional profundo .
vídeo 1
vídeo 2
El código de este repositorio en particular en realidad no tiene nada que ver con pix2pix, GAN o incluso el aprendizaje profundo. Simplemente carga cualquier modelo de tensorflow previamente entrenado (siempre que cumpla con algunas restricciones), le proporciona una entrada de cámara web procesada y muestra la salida del modelo. Da la casualidad de que el modelo que entrené y utilicé es pix2pix (detalles a continuación).
Es decir, los pasos se pueden resumir como:
Saqué colecciones de arte de todo el mundo del Google Art Project en wikimedia. Muchas de las imágenes son retratos clásicos de tipos blancos ricos, por lo que solo utilicé unas 150 colecciones, tratando de mantener los datos lo más diversos geográfica y culturalmente posible (la lista completa que utilicé está aquí). Pero los datos siguen siendo muy eurocéntricos, ya que puede haber cientos o miles de escaneos de un solo museo europeo, pero sólo 8 escaneos de un museo árabe.
Descargué las versiones de 300px de las imágenes y ejecuté un proceso por lotes para:
También ejecuté un proceso por lotes para realizar múltiples recortes de las imágenes (en lugar de un cambio de tamaño no uniforme), pero aún no me he entrenado en eso. En lugar de una detección de bordes astuta, también comencé a investigar la mucho mejor 'Detección de bordes anidada holísticamente' (también conocida como HED) de Xie y Tu (como la utilizan el artículo original de pix2pix), pero tampoco me he entrenado en eso todavía.
Esto se hace mediante el script preprocess.py (lo siento, no hay argumentos en la línea de comando, editar el script para cambiar las rutas y la configuración, debería explicarse por sí mismo).
Aquí se puede ver una pequeña muestra de los datos de entrenamiento, incluidas las predicciones del modelo entrenado. La columna de la derecha es la imagen original, la columna de la izquierda es la versión preprocesada. Estas dos imágenes se introducen en la red pix2pix como un "par" para entrenar. La columna del medio es lo que el modelo aprende a producir dada solo la columna más a la izquierda . (Las imágenes muestran cada iteración de entrenamiento, es decir, el número de la izquierda, que va de 20 000 a 58 000, por lo que mejora gradualmente a medida que avanza en la página).
También entrené una GAN incondicional (es decir, DCGAN normal con estos mismos datos de entrenamiento. A continuación se puede ver un ejemplo de su resultado. (Esto genera imágenes "completamente aleatorias" que se asemejan a los datos de entrenamiento).
La capacitación y la arquitectura son directamente ' Traducción de imagen a imagen con redes adversas condicionales ' de Isola et al (también conocido como pix2pix). Entrené con el puerto tensorflow de @affinelayer (Christopher Hesse), que también es lo que impulsa esa demostración de 'sketch-to-cat' que se volvió viral recientemente. También escribió un bonito tutorial sobre cómo funciona pix2pix. ¡Infinitas gracias a los autores (y a todos los que construyeron) por hacer que su código sea de código abierto!
Solo hice un cambio infinitamente pequeño en el código de entrenamiento de tensorflow-pix2pix, y es agregar tf.Identity a las entradas y salidas del generador con un nombre legible por humanos, para poder alimentar y recuperar los tensores con facilidad. Entonces, si quisieras usar tus propios modelos con esta aplicación, tendrías que hacer lo mismo . (O tome nota de los nombres de los tensores de entrada/salida y modifique el json en consecuencia, más sobre esto a continuación).
Puede descargar mi modelo previamente entrenado desde la pestaña Lanzamientos.
Lo que hace esta aplicación en particular es cargar el modelo previamente entrenado, realizar un preprocesamiento en vivo de la entrada de una cámara web y alimentarlo al modelo. Hago el preprocesamiento con visión por computadora básica antigua, usando opencv. Es realmente muy mínimo y básico. Puede ver la GUI a continuación (la GUI usa pyqtgraph).
Diferentes escenas requieren diferentes escenarios.
Por ejemplo, para 'acción en vivo' encontré astuto para proporcionar mejores resultados (en mi humilde opinión), y es lo que usé en el primer video en la parte superior. Los umbrales (canny_t1, canny_t2) dependen de la escena, la cantidad de detalles y el aspecto deseado.
Si tiene mucho ruido en su imagen, es posible que desee agregar un poquito de pre_blur o pre_median . O juegue con ellos para obtener un "efecto artístico". Por ejemplo, en el primer video, alrededor de 1:05-1:40, agrego una tonelada de mediana (valores alrededor de 30-50).
Para escenas de dibujo (por ejemplo, segundo video), encontré que el umbral adaptativo da resultados más interesantes que el astuto (es decir, deshabilita el astuto y habilita el umbral adaptativo), aunque es posible que no estés de acuerdo.
Para una entrada completamente estática (es decir, si congela la captura y desactiva la actualización de la cámara), es probable que la salida parpadee una cantidad muy pequeña ya que el modelo hace diferentes predicciones para la misma entrada, aunque esto suele ser bastante sutil. Sin embargo, para una transmisión de cámara en vivo , es probable que el ruido en la entrada cree mucho parpadeo en la salida, especialmente debido a la alta susceptibilidad del umbral astuto o adaptativo al ruido, por lo que algo de desenfoque temporal puede ayudar.
accum_w1 y accum_w2 sirven para difuminar temporalmente la entrada, antes de ingresar al modelo: new_image = old_image * w1 + new_image * w2 (por lo que idealmente deberían sumar uno, o cerca).
Prediction.pre_time_lerp y post_time_lerp también realizan suavizado temporal: new_image = old_image * xxx_lerp + new_image * (1 - xxx_lerp) pre_time_lerp es antes de entrar en el modelo y post_time_lerp es después de salir del modelo.
Cero para cualquiera de los desenfoques temporales los desactiva. Los valores de estos dependen de su gusto. Para los dos videos anteriores, tenía todos los desenfoques pre_model (es decir, accum_w1, accum_w2 y pre_time_lerp) configurados en cero, y jugué con diferentes configuraciones post_time_lerp que van desde 0.0 (muy parpadeante y parpadeante) a 0.9 (muy lento, desvanecido y 'de ensueño'). ). Por lo general, mi rango favorito es entre 0,5 y 0,8.
Si desea utilizar un modelo diferente, debe configurar un archivo JSON similar al siguiente. La motivación aquí es que en realidad tengo un montón de archivos JSON en mi carpeta aplicación/modelos que puedo escanear y recargar dinámicamente, y los datos del modelo se almacenan en otros discos, y la aplicación puede cargar e intercambiar entre modelos en tiempo de ejecución y escala. entradas/salidas, etc. automáticamente.
{
"name" : "gart_canny_256", # name of the model (for GUI)
"ckpt_path" : "./models/gart_canny_256", # path to saved model (meta + checkpoints). Loads latest if points to a folder, otherwise loads specific checkpoint
"input" : { # info for input tensor
"shape" : [256, 256, 3], # expected shape (height, width, channels) EXCLUDING batch (assumes additional axis==0 will contain batch)
"range" : [-1.0, 1.0], # expected range of values
"opname" : "generator/generator_inputs" # name of tensor (':0' is appended in code)
},
"output" : { # info for output tensor
"shape" : [256, 256, 3], # shape that is output (height, width, channels) EXCLUDING batch (assumes additional axis==0 will contain batch)
"range" : [-1.0, 1.0], # value range that is output
"opname" : "generator/generator_outputs" # name of tensor (':0' is appended in code)
}
}
Probado solo en Ubuntu 16.04, pero debería funcionar en otras plataformas.
Utilizo la distribución de Python Anaconda que viene con casi todo lo que necesitas, luego es (con suerte) tan simple como:
Descargue e instale anaconda desde https://www.continuum.io/downloads
Instale tensorflow https://www.tensorflow.org/install/ (lo cual, si tiene anaconda, suele ser bastante sencillo ya que la mayoría de las dependencias están incluidas)
Instalar opencv y pyqtgraph
instalación de conda -c menpo opencv3 instalación de conda pyqtgraph
Infinitas gracias una vez más a