¿Cómo harías un programa, con tu lenguaje favorito, que fuese capaz de convertir la foto de la izquierda en la de la derecha?:
O sea, ¿cómo detectarías las personas que hay en la foto y quitarías todo lo demás? para poder sustituirlo 🤔
Es algo muy, muy complicado. Sin embargo, el uso de técnicas de aprendizaje automático basado en redes neuronales hace que sea mucho más sencillo conseguirlo, ya que no le tienes que decir exactamente qué hay que hacer, sino que la red neuronal aprende sola a partir de miles o millones de datos, y genera un modelo que puedes utilizar
Hoy vamos a ver cómo hacerlo con Python, usando un modelo de Machine Learning previamente entrenado. Para ello te dejo un vídeo donde te lo explico en la práctica. A continuación tienes un artículo en el que te detallo por escrito cómo hacerlo.
¿Qué es la segmentación de objetos?
Para lograr nuestro propósito vamos a utilizar la conocida biblioteca Python PixelLib, creada por la desarrolladora nigeriana Ayoola Olafenwa. PixelLib es una biblioteca para Python que sirve para hacer segmentación de objetos en imágenes y vídeos.
Pero antes un poco de teoría: la diferencia entre segmentación de objetos y detección de objetos es que la detección identifica que hay un determinado objeto en una imagen, pero no identifica sus contornos, solo determina un rectángulo que lo rodea. Sin embargo la segmentación va más allá ya que crea máscaras por encima de los objetos, dibujando su contorno, por lo que son más precisas:
La imagen es cortesía del MIT - Fuente
En concreto, para hacer lo que queremos, PixelLib usa por debajo también Tensorflow. Esta es la biblioteca más famosa de Machine Learning, creada por Google para múltiples tareas, pero que es especialmente utilizada para Deep Learning, o sea, redes neuronales avanzadas.
Vamos a utilizar un modelo preentrenado que es capaz de detectar diversos objetos con TensorFlow, y luego PixelLib se encargará de la segmentación para crear una máscara y quitar el resto.
Creación del proyecto
Antes de nada, tenemos que instalar estas dos bibliotecas (PixelLib y Tensorflow) usando nuestro gestor de paquetes favorito, pip
o conda
. En el código de ejemplo te dejo dos archivos .bat para Windows con la línea de comandos que necesitas para instalarlos (en otros sistemas ábrelos y copia y pega la instrucción).
Lo primero es importar lo que necesitamos para hacer el trabajo, en este caso:
import pixellib
from pixellib.tune_bg import alter_bg
O sea, importamos PixelLib y luego la parte concreta de cambio de fondos.
alter_bg
es la clase que tiene los métodos que se encargan de lograr esto. Así que vamos a instanciarla:
quitar_fondo = alter_bg()
Ahora en esta variable tenemos una instancia de esta clase que nos permite usar sus métodos.
Lo primero que tenemos que hacer es usar el modelo ya entrenado para quitar los fondos, para lo cual vamos a utilizar el que ya tiene PixelLib en su zona de "Releases" llamado deeplabv3_xception_tf_dim_ordering_tf_kernels.h5 (te lo tienes que bajar pues no va en la descarga que te dejo con el vídeo).
OJO, pesa un montón (158MB) porque tiene datos entrenados con miles de imágenes para detectar objetos.
Este archivo está en formato .h5
que es un formato especial para almacenamiento de datos jerárquicos que se utiliza mucho en este tipo de proyectos. Pesa mucho porque tiene datos de multitud de imágenes que usa el modelo preentrenado con una herramienta llamada Deep Lab.
Lo que tenemos que hacer, una vez descargado, es cargar el modelo para que pueda funcionar:
cambiar_fondo.load_pascalvoc_model("deeplabv3_xception_tf_dim_ordering_tf_kernels.h5")
Con el modelo cargado sólo resta usarlo con los diferentes métodos de alter_bg
:
color_bg
: quita lo que no segmente y lo sustituye por un color que le indiquemos.
change_bg_img
: cambia el fondo por una imagen que le indiquemos.
gray_bg
: pone el fondo (todo lo que no segmente) en blanco y negro, preservando el color de lo segmentado.
blur_bg
: difumina el fondo, lo no segmentado.
Gracias a estos cuatro métodos podemos hacer cosas muy chulas, por ejemplo:
cambiar_fondo.color_bg("imgs/01.jpg", colors = (0, 255, 0), output_image_name="fondocambiado/03_verde.jpg", detect="person")
cambiar_fondo.change_bg_img("imgs/01.jpg", "./fondo.jpg", output_image_name="fondocambiado/01.jpg", detect="person")
cambiar_fondo.gray_bg("imgs/01.jpg", output_image_name="fondocambiado/01_grises.jpg", detect="person")
cambiar_fondo.blur_bg("imgs/01.jpg", low = True, output_image_name="fondocambiado/01_desenfocado.jpg", detect="person")
El modelo es capaz de detectar personas, pero también muchos otros objetos: coches, aviones, autobuses, trenes, motos, bicicletas, barcos, botellas, gatos, perros, caballos, vacas, ovejas, plantas y alguna cosa más...
Los nombres concretos para indicar son: person, bus, car, aeroplane, bicycle, motorbike, bird, boat, bottle, cat, chair, cow, dinningtable, dog, horse pottedplant, sheep, sofa, train, tv
Como ves es muy sencillo de utilizar, y los resultados son bastante decentes, aunque lógicamente dependerá de la imagen de base utilizada. Por supuesto, si tuviésemos un modelo mejor conseguiríamos mejores resultados. Y ahí está la clave de todo este tipo de algoritmos: tener buenos datos...
En la descarga de este artículo + video (ZIP, 1.35MB) te dejo no sólo estas líneas sino también un programa completo en Python al que le puedes pasar parámetros por línea de comandos para facilitar su uso.
¡Espero que te resulte útil!