Todos sabemos que la Inteligencia Artificial se está volviendo cada vez más real y está llenando las brechas entre las capacidades de los humanos y las máquinas día a día. Ya no es solo una palabra elegante. Ha tenido muchos avances a lo largo de los años en muchos campos y una de esas áreas es el dominio de la Visión por Computador.
Cuando se trata de la Visión por Computador, su objetivo es entrenar las máquinas para ver y reconocer el mundo como lo hacen los humanos. Y también reúne conocimientos lo suficientemente grandes como para realizar reconocimiento de imágenes y video, análisis y clasificación de imágenes, recreación de medios, procesamiento de lenguaje natural, etc.
Redes neuronales convolucionales
El avance en la Visión por Computador se ha implementado y perfeccionado gradualmente con el tiempo. Principalmente sobre un algoritmo en particular, una Red Neural Convolucional (CNN o ConvNets).
Que es un tipo especial de red de avance que se usa principalmente para analizar imágenes visuales. Las redes neuronales convolucionales son muy similares a las redes neuronales comunes. Pero están formadas por neuronas que tienen pesos y sesgos que se pueden aprender.
ConvNets funciona mejor que las otras arquitecturas de redes neuronales profundas debido a su proceso único. En lugar de mirar la imagen un píxel a la vez, ConvNets agrupa varios píxeles para que puedan entender un patrón temporal.
De otra manera, ConvNets puede “ver” el grupo de píxeles que forman una línea o curva. Debido a la naturaleza profunda de las redes neuronales profundas, en el siguiente nivel no verán el grupo de píxeles, sino los grupos de líneas y curvas que forman algunas formas. Y así sucesivamente hasta formar un cuadro completo.
Transferencia de aprendizaje
Sin embargo, las CNN requieren grandes conjuntos de datos y mucho tiempo de cómputo para entrenar. Algunos pueden tardar hasta 2-3 semanas en múltiples GPU.
Hay muchas cosas que necesita aprender si quiere entender las CNN, desde las cosas más básicas, como un núcleo, agrupar capas, etc. Pero hoy en día, solo puede bucear y usar muchos proyectos de código abierto para esta tecnología.
Esto es realmente cierto debido a la tecnología llamada Transfer Learning. Transfer Learning es una técnica muy práctica y poderosa que utiliza un modelo entrenado en lugar de entrenar la red desde cero. El aprendizaje por transferencia utiliza un modelo capacitado en un conjunto de datos diferente. Y lo adapta al problema que estamos tratando de resolver.
Para desarrollar nuestra aplicación, seguiremos la técnica de transferencia de aprendizaje y utilizaremos un modelo capacitado, que se entrenó utilizando el marco de Caffe.
Un marco de aprendizaje profundo hecho con la expresión, la velocidad y la modularidad en mente. Caffe viene con un repositorio que es usado por investigadores y practicantes de aprendizaje automático para compartir sus modelos entrenados. Esta biblioteca se llama Model Zoo.
Puedes leer todo sobre esto revisando su documentación .
Empezando
El código de python, el modelo de caffe entrenado y el archivo de prototxt. Que incluye la descripción de texto de la red y algunas imágenes de ejemplo para usar con nuestra aplicación. Están disponibles en el repositorio de github si desea echar un vistazo.
En nuestra aplicación, utilizaremos las siguientes bibliotecas:
- OpenCV Python, que admite una gran cantidad de algoritmos relacionados con la Visión por Computador y el Aprendizaje Automático. Sin mencionar que está construido en Deep Neural Network. Que usaremos en nuestra aplicación.
- Numpy, que es un paquete utilizado para la computación científica con python.
- Sistema operativo, que proporciona una forma portátil de utilizar la funcionalidad dependiente del sistema operativo
Por lo tanto, para instalarlos, puede ejecutar los siguientes comandos en una ventana del símbolo del sistema. pip install opencv-python
para instalar OpenCV Python, pip install numpy
para instalar Numpy y no tiene que instalar específicamente la biblioteca del sistema operativo como viene con su instalación de Python, pero todavía debe importarla.
Construyendo la aplicación
Primero, creemos un archivo llamado faceDetection.py e importemos nuestras bibliotecas.
#import libraries import os import cv2 import numpy
Ahora, obtendremos la ruta absoluta del directorio de trabajo, donde colocaremos todas nuestras imágenes:
#import libraries import os import cv2 import numpy
#get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__))
Ahora, crearemos una carpeta llamada “Salida” para colocar nuestras imágenes finales si aún no existe.
#import libraries import os import cv2 import numpy
#get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__))
#create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output')
Después de eso, cargaremos nuestro modelo pre-entrenado y el archivo de prototxt del directorio de trabajo actual.
#import libraries import os import cv2 import numpy
#get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__))
#create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output')
#Reads the network model stored in Caffe framework's format. model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel')
Luego, recorreremos los archivos disponibles en la carpeta actual para verificar si hay archivos con las extensiones, .png, .jpg y .jpeg.
#import libraries import os import cv2 import numpy
#get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__))
#create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output')
#Reads the network model stored in Caffe framework's format. model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel')
for file in os.listdir(dir_path): #split the file name and the extension into two variales filename, file_extension = os.path.splitext(file)
#check if the file extension is .png,.jpeg or .jpg if (file_extension in ['.png','.jpg','.jpeg']):
Si se encuentra una imagen con las extensiones anteriores, leeremos la imagen utilizando OpenCV Python y obtendremos su altura y anchura accediendo a la tupla de image.shape y tomando los primeros dos elementos para dibujar el rectángulo alrededor de la cara más adelante.
#import libraries import os import cv2 import numpy
#get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__))
#create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output')
#Reads the network model stored in Caffe framework's format. model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel')
for file in os.listdir(dir_path): #split the file name and the extension into two variales filename, file_extension = os.path.splitext(file)
#check if the file extension is .png,.jpeg or .jpg if (file_extension in ['.png','.jpg','.jpeg']): #read the image using cv2 image = cv2.imread(file)
#accessing the image.shape tuple and taking the elements (h, w) = image.shape[:2]
Y luego, obtendremos nuestro blob usando la cv2.dnn.blobFromImage
función dando la imagen como entrada. Con la cv2.dnn.blobFromImage
función redimensionamos la imagen a una dimensión de 300×300, 1.0 es un factor de escala y aquí usamos el valor predeterminado, por lo que no hay escala, después de eso es el tamaño espacial que la red neuronal convolucional espera, los últimos valores son valores de resta promedio en la tupla y son medios RGB, y al final, la función devuelve un “blob” que es nuestra imagen de entrada después del cambio de tamaño, la resta de la media y la normalización.
Después de eso, ingresaremos el blob en el modelo y obtendremos las detecciones usando la model.foreward
función.
#import libraries import os import cv2 import numpy
#get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__))
#create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output')
#Reads the network model stored in Caffe framework's format. model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel')
for file in os.listdir(dir_path): #split the file name and the extension into two variales filename, file_extension = os.path.splitext(file)
#check if the file extension is .png,.jpeg or .jpg if (file_extension in ['.png','.jpg','.jpeg']): #read the image using cv2 image = cv2.imread(file)
#accessing the image.shape tuple and taking the elements (h, w) = image.shape[:2] #get our blob which is our input image blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0)) #input the blob into the model and get back the detections model.setInput(blob) detections = model.forward()
Luego, recorreremos todas las caras detectadas y extraeremos sus puntos de inicio y final.
Extraeremos la confianza y la compararemos con el umbral de confianza para poder filtrar las detecciones que son débiles. Si el algoritmo tiene más de 16.5% de confianza de que la detección es una cara, le mostraremos un rectángulo verde.
#import libraries import os import cv2 import numpy
#get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__))
#create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output')
#Reads the network model stored in Caffe framework's format. model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel')
for file in os.listdir(dir_path): #split the file name and the extension into two variales filename, file_extension = os.path.splitext(file)
#check if the file extension is .png,.jpeg or .jpg if (file_extension in ['.png','.jpg','.jpeg']): #read the image using cv2 image = cv2.imread(file)
#accessing the image.shape tuple and taking the elements (h, w) = image.shape[:2]
#get our blob which is our input image blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0))
#input the blob into the model and get back the detections model.setInput(blob) detections = model.forward() #Iterate over all of the faces detected and extract their start and end points count = 0 for i in range(0, detections.shape[2]): box = detections[0, 0, i, 3:7] * numpy.array([w, h, w, h]) (startX, startY, endX, endY) = box.astype("int") confidence = detections[0, 0, i, 2] #if the algorithm is more than 16.5% confident that the detection is a face, show a rectangle around it if (confidence > 0.165): cv2.rectangle(image, (startX, startY), (endX, endY), (0, 255, 0), 2) count = count + 1
Finalmente, guardaremos la imagen de salida en la carpeta de salida que creamos e imprimiremos un mensaje de éxito para que el usuario sepa que está listo.
#import libraries import os import cv2 import numpy
#get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__))
#create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output')
#Reads the network model stored in Caffe framework's format. model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel')
for file in os.listdir(dir_path): #split the file name and the extension into two variales filename, file_extension = os.path.splitext(file)
#check if the file extension is .png,.jpeg or .jpg if (file_extension in ['.png','.jpg','.jpeg']): #read the image using cv2 image = cv2.imread(file)
#accessing the image.shape tuple and taking the elements (h, w) = image.shape[:2]
#get our blob which is our input image blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0))
#input the blob into the model and get back the detections model.setInput(blob) detections = model.forward() #Iterate over all of the faces detected and extract their start and end points count = 0 for i in range(0, detections.shape[2]): box = detections[0, 0, i, 3:7] * numpy.array([w, h, w, h]) (startX, startY, endX, endY) = box.astype("int")
confidence = detections[0, 0, i, 2] #if the algorithm is more than 16.5% confident that the detection is a face, show a rectangle around it if (confidence > 0.165): cv2.rectangle(image, (startX, startY), (endX, endY), (0, 255, 0), 2) count = count + 1
#save the modified image to the Output folder cv2.imwrite('Output/' + file, image)
#print out a success message print("Face detection complete for image "+ file + " ("+ str(count) +") faces found!")
Espero que hayan disfrutado los resultados! Ahora, siempre puedes jugar un poco con el código para tener una idea de lo que hace cada función. OpenCV Python proporciona una excelente documentación y tutoriales si quieres leer y obtener más información también.
Conclusión
En este artículo, caminamos a través,
- El concepto de redes neuronales convolucionales y cómo podemos ahorrar mucho tiempo y esfuerzo con Transfer Learning y los modelos pre-entrenados.
- Los modelos de Caffe y cómo vamos a utilizar un modelo de Caffe pre-entrenado para implementar nuestra aplicación.
- instalando las bibliotecas requeridas y configurando el entorno.
Y finalmente, implementamos un programa de python que puede detectar usando una imagen.
Si tiene alguna pregunta, no dude en dejar un comentario a continuación. ¡Gracias!