Detección de objetos con Tensorflow en un Vultr Cloud Servidor

Introducción

La detección de objetos es una tecnología de visión por computadora que identifica/ubica instancias de objetos de una clase determinada, como humanos, edificios o vehículos, en imágenes o videos digitales. La detección de objetos tiene usos en varias tareas de visión por computadora, incluida la anotación de imágenes, la detección de rostros, el seguimiento de objetos, el reconocimiento de actividades y el conteo de vehículos.

Tensorflow es una plataforma integral de código abierto para crear aplicaciones basadas en aprendizaje automático. Contiene ricas herramientas y bibliotecas enfocadas principalmente en el entrenamiento y la inferencia de redes neuronales.

Esta guía usa Tensorflow para crear una aplicación de detección de objetos.

requisitos previos

Necesitarás lo siguiente:

  • Conocimiento práctico de Python

  • Una cadena de herramientas de Python correctamente instalada y configurada, incluido pip (versión de Python >= 3.8)

  • los ultima versión de Protobuf para Python instalado

Cómo funciona la detección de objetos

La detección de objetos generalmente se lleva a cabo mediante la generación de pequeños segmentos de la imagen de entrada, con la extracción de características utilizada para validar si el segmento es un objeto válido y la combinación de cuadros de segmentos superpuestos en un solo rectángulo delimitador.

La detección de objetos generalmente tiene dos enfoques: enfoques no neuronales y basados ​​en redes neuronales. Los enfoques no neurales incluyen:

  • Marco de detección de objetos de Viola-Jones – que se basa en las funciones de Haar que se propusieron originalmente para la detección de rostros, pero que se pueden ampliar para la detección de otros objetos. Al calcular las intensidades de píxeles de dos regiones rectangulares vecinas y encontrar diferencias entre la suma, se pueden capturar las características de una sección de imagen.

  • Funciones de histograma de gradientes orientados (HOG) – Este método es un descriptor de funciones que cuenta las ocurrencias de orientación de degradado en partes localizadas de una imagen. El descriptor de características HOG no solo se enfoca en la estructura o forma del objeto, sino que también puede proporcionar la dirección del borde. Las orientaciones de degradado se calculan en porciones localizadas, dividiendo la imagen en regiones más pequeñas, con los degradados y la orientación calculados para cada región. Este método funciona bien para la detección de peatones.

  • Transformación de características de escala invariable (SIFT) – consiste en detectar puntos clave (características locales) en una imagen. Se extrae un conjunto de puntos clave de objetos de las imágenes de referencia y se almacena en una base de datos; los objetos de las nuevas imágenes se reconocen comparando individualmente las características de la nueva imagen con la base de datos. Las características coincidentes se encuentran en función de la distancia euclidiana de sus vectores de características. SIFT tiene una ventaja adicional ya que no se ve afectado por el tamaño o la orientación de la imagen.

La detección de objetos basada en redes neuronales generalmente implica diseñar y entrenar una arquitectura de red neuronal desde cero o aprovechar una red preentrenada ya entrenada en un gran conjunto de datos utilizando conjuntos de datos personalizados (llamado transferencia de aprendizaje). El aprendizaje por transferencia es un método para reutilizar el conocimiento previo obtenido al resolver un problema y aplicar el mismo conocimiento a un problema separado pero asociado. Los enfoques de redes neuronales incluyen:

  • Solo se mira una vez (YOLO) – es un sistema de detección de objetos en tiempo real de última generación que funciona aplicando una única red neuronal a una imagen completa. La red neuronal divide la imagen en regiones separadas y predice cuadros delimitadores y probabilidades para cada región. Los cuadros delimitadores están ponderados por las probabilidades predichas. YOLO es muy rápido ya que pasa por la imagen una sola vez.

  • Redes neuronales convolucionales basadas en regiones (R-CNN) – utilizar propuestas de región para localizar objetos dentro de una imagen utilizando un algoritmo de búsqueda selectiva. La CNN extrae características, y la capa densa de salida consiste en características extraídas de la imagen, alimentadas a una SVM para clasificar la presencia del objeto dentro de la región específica propuesta. Los R-CNN son una serie de algoritmos que incluyen R-CNN, R-CNN rápido y R-CNN más rápido.

  • RetinaNet – es un modelo de detección de objetos de una etapa que utiliza una función de pérdida focal para resolver los desequilibrios de clase durante el entrenamiento. RetinaNet es una única red unificada compuesta por una red troncal responsable de calcular un mapa de características convolucionales sobre toda la imagen de entrada y dos subredes específicas de tareas. La primera subred realiza la clasificación de objetos convolucionales en la salida de la red troncal. La segunda subred realiza una regresión de cuadro delimitador convolucional.

La detección de objetos basada en redes neuronales es más frecuente en los escenarios modernos, ya que produce mejores resultados y es más avanzada.

Configuración del entorno virtual del proyecto

Cree un entorno virtual aislado para la aplicación:

  1. Instala el virtualenv Paquete de Python:

                              
                                $ pip install virtualenv
    
                              
                            
  2. Cree el directorio del proyecto:

                              
                                $ mkdir obj_detection
    
                              
                            
  3. Navegue al nuevo directorio:

                              
                                $ cd obj_detection
    
                              
                            
  4. Crear el entorno virtual:

                              
                                $ python3 -m venv env
    
                              
                            

    Esto crea una nueva carpeta llamada env que contiene scripts para controlar el entorno virtual, incluidas las bibliotecas de programas.

  5. Activar el entorno virtual:

                              
                                $ source env/bin/activate
    
                              
                            

Instalación de TensorFlow

Para instalar TensorFlow, ingrese el siguiente comando:

                      
                        $ pip install tensorflow

                      
                    

API de detección de objetos de TensorFlow

La API de detección de objetos de TensorFlow es un marco de código abierto que simplifica la construcción, el entrenamiento y la implementación de modelos de detección de objetos basados ​​en TensorFlow. Contiene un conjunto de modelos preentrenados en su marco, denominado Model Zoo. Estos modelos preentrenados se entrenan en varios conjuntos de datos, que incluyen:

  • Objetos comunes en contexto (COCO) – es un conjunto de datos de detección, subtítulos y segmentación de objetos a gran escala con una plétora de funciones, incluido el reconocimiento en contexto, 1,5 millones de instancias de objetos y más de 220 000 imágenes etiquetadas.

  • Instituto de Tecnología de Karlsruhe e Instituto Tecnológico de Toyota (KIITI) – es un conjunto de datos para uso en conducción autónoma y robótica móvil.

Esta guía hace uso de un modelo previamente entrenado entrenado en el conjunto de datos COCO.

Instalación de la API de detección de objetos de TensorFlow

Para instalar la API de detección de objetos de TensorFlow, clona el repositorio dentro del directorio del proyecto:

                      
                        $ git clone https://github.com/tensorflow/models

                      
                    

El directorio del proyecto debe tener un modelos directorio dentro de él. Navegue al directorio de investigación:

                      
                        $ cd models/research

                      
                    

La API de detección de objetos de TensorFlow usa Protobufs para configurar el modelo y los parámetros de entrenamiento. Usando el comando protoc:

                      
                        $ protoc object_detection/protos/*.proto --python_out=.

                      
                    

Instalación de la API de COCO

los pycocotools El paquete es la API oficial para el conjunto de datos de COCO y es una dependencia de la API de detección de objetos de TensorFlow. Para instalar, navegue de regreso al directorio del proyecto:

                      
                        $ cd ../..

                      
                    

Clonar el cacaopi repositorio:

                      
                        $ git clone https://github.com/cocodataset/cocoapi.git

                      
                    

Cambiar directorio:

                      
                        $ cd cocoapi/PythonAPI

                      
                    

ejecutar el hacer comando para construir la biblioteca:

                      
                        $ make

                      
                    

Después de que la compilación se ejecute correctamente, copie el pycocotools subcarpeta en el investigar carpeta del repositorio clonado de la API de detección de objetos de TensorFlow:

                      
                        $ cp -r pycocotools ../../models/research

                      
                    

Instalación de la API de detección de objetos

Para instalar la API de detección de objetos, ejecute los siguientes comandos dentro del modelos/investigación carpeta:

                      
                        $ cp object_detection/packages/tf2/setup.py . && python -m pip install .

                      
                    

Esto instala todas las dependencias del proyecto.

Construcción del detector de objetos

Esta guía utiliza un modelo de detección de objetos preentrenado entrenado en el conjunto de datos COCO. Para empezar, crea el main.py archivo dentro del directorio del proyecto:

                      
                        $ touch main.py

                      
                    

Importar bibliotecas

Importe las bibliotecas requeridas agregando las siguientes líneas:

                      
                        import tensorflow as tf

import numpy as np

from PIL import Image

from object_detection.utils import label_map_util

from object_detection.utils import visualization_utils as viz_utils

                      
                    

Numpy se utiliza para la aritmética y el cálculo de matrices, y el Image La clase de la biblioteca de almohadas se utiliza para la manipulación de imágenes. Las clases importadas de detección_de_objetos tienen las siguientes funciones:

  • label_map_util : se utiliza para cargar un mapa de etiquetas para el trazado. Los mapas de etiquetas correlacionan los números de índice con los nombres de categoría, si la detección de un objeto tiene un índice de 1, esto mapea la detección como una persona.

  • visualization_utils : contiene funciones para superponer cuadros etiquetados sobre objetos detectados.

Descargando el modelo

Varios modelos entrenados previamente en el conjunto de datos COCO se pueden descargar y usar de forma inmediata, como se indica en el repositorio de modelos . En esta guía, el modelo pre-entrenado utilizado es el SSD ResNet152 V1 FPN 1024×1024 (RetinaNet152) .

Cree una función de descarga de modelo:

                      
                        def download_model(model_name, model_date):

    base_url="https://download.tensorflow.org/models/object_detection/tf2/"

    model_file = model_name + '.tar.gz'

    model_dir = tf.keras.utils.get_file(fname=model_name,

                                        origin=base_url + model_date + "https://www.vultr.com/" + model_file,

                                        untar=True)

    return str(model_dir)

                      
                    

Esta función toma el nombre del modelo y la fecha del modelo como argumento y descarga el modelo especificado usando el get_file función de TensorFlow. Devuelve el directorio del modelo descargado como una cadena.

Usando la función, descargue el modelo dado:

                      
                        # Download model

model_name = "ssd_resnet152_v1_fpn_1024x1024_coco17_tpu-8"

model_date = "20200711"

PATH_TO_MODEL_DIR = download_model(model_name, model_date)

                      
                    

Esto descarga el modelo pasado y guarda la ruta del modelo en una variable. Para cargar el modelo para su uso dentro de la aplicación, agregue la siguiente línea:

                      
                        # Load model

model_fn = tf.saved_model.load(PATH_TO_MODEL_DIR + "/saved_model")

                      
                    

los load la función carga un SavedModel del directorio pasado como argumento. Esto devuelve un objeto rastreable con un firmas mapeo de atributos desde claves de firma a funciones. Este objeto se puede llamar como una función en una imagen para la inferencia de objetos. Aquí el modelo_guardado El directorio dentro del modelo descargado se pasa como argumento.

Cargar etiquetas

Como se mencionó anteriormente, los mapas de etiquetas correlacionan números de índice con nombres de categorías. Cuando un objeto detectado devuelve un número de índice, los mapas de etiquetas clasifican el objeto. Para examplelos objetos detectados con un índice de 1 se clasifican como una persona.

Para cargar el mapa de etiquetas utilizado para correlacionar números de índice con nombres de categorías, agregue las siguientes líneas:

                      
                        # Load labels

PATH_TO_LABELS = 'models/research/object_detection/data/mscoco_label_map.pbtxt'

category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)

                      
                    

La ruta al archivo del mapa de etiquetas se guarda en una variable y se pasa al create _category_index_from_labelmap función. Esta función lee un mapa de etiquetas y devuelve una lista de categorías que contiene diccionarios que representan todas las categorías posibles.

Cargar imagen

Esta guía utiliza las siguientes imágenes:

Descarga las imágenes, guárdalas como image1.jpg y image2.jpg respectivamente, luego colóquelos dentro del directorio del proyecto. El directorio del proyecto debería verse así:

                      
                        .

├── env/

└── models/

└── cocoapi/

└── main.py

└── image1.jpg

└── image2.jpg

                      
                    

Agregue las siguientes líneas al principal.py expediente:

                      
                        # Images to run detection

images = ["image1.jpg", "image2.jpg"]



for image in images:

    print(f"Running inference for image - {image}")



    # Load image into a numpy array

    image_np = np.array(Image.open(image))



    # Convert image to tensor

    input_tensor = tf.convert_to_tensor(image_np)



    # Add an axis

    input_tensor = input_tensor[tf.newaxis, ...]

                      
                    

Utilizando el Imagen.abierto función, la imagen se abre y se carga en una matriz numpy usando el formación función de numpy. El detector de objetos toma tensores como entrada, por lo que la imagen debe convertirse en un tensor usando el convert_to_tensor función. También se agrega un nuevo eje ya que el modelo espera un lote de imágenes.

Inferencia en ejecución

Para inferir objetos de la imagen, agregue la siguiente línea:

                      
                            # Run inference

    detections = model_fn(input_tensor)

                      
                    

El modelo se llama con el tensor de entrada como argumento, esto ejecuta el tensor a través del modelo y la detección se lleva a cabo devolviendo salidas como lotes de tensor que marcan los límites de los objetos detectados.

                      
                            # Outputs are tensor batches.

    # Convert to numpy arrays, and take index [0] to remove the batch dimension.

    num_detections = int(detections.pop('num_detections'))

    detections = {key: value[0, :num_detections].numpy()

                  for key, value in detections.items()}

    detections['num_detections'] = num_detections



    # detection_classes cast as ints.

    detections['detection_classes'] = detections['detection_classes'].astype(np.int64)

                      
                    

Las líneas anteriores convierten los lotes de tensor en matrices numpy, eliminan la dimensión del lote ya que no es necesaria y actualizan la cantidad de detecciones después de la limpieza. A continuación, las clases de detección se convierten en números enteros a partir de sus representaciones flotantes.

Visualización de detecciones

Para dibujar cuadros alrededor de los objetos detectados de la imagen, agregue las siguientes líneas:

                      
                            image_np_with_detections = image_np.copy()



    viz_utils.visualize_boxes_and_labels_on_image_array(

            image_np_with_detections,

            detections['detection_boxes'],

            detections['detection_classes'],

            detections['detection_scores'],

            category_index,

            use_normalized_coordinates=True,

            max_boxes_to_draw=200,

            min_score_thresh=.30,

            agnostic_mode=False,

            line_thickness=8)

                      
                    

Se realiza una copia de la imagen utilizando el Copiar método, y el visualize_boxes_and_labels_on_image_array Función: superpone cuadros etiquetados en la imagen con los nombres y puntajes de las etiquetas formateadas. Se necesitan 5 argumentos:

  • Imagen – la imagen que se superpondrá con cuadros como una matriz numpy uint8.

  • Cajas – una matriz numpy con una forma [N, 4].

  • Clases – una matriz numpy con una forma [N]. Los índices de clase coinciden con las claves en el mapa de etiquetas y están basados ​​en 1.

  • Puntuaciones – una gran variedad de formas [N] o Ninguno. Si se establece en Ninguno, la función asume que los cuadros que se van a trazar son verdaderos y también traza los cuadros sin clases o puntajes en negro.

  • Índice de categorías – un diccionario que contiene diccionarios de categorías compuestos por ID de índice y nombres de categoría, codificados por índices.

Los argumentos requeridos se pasan con argumentos opcionales adicionales. En esto exampleutilizando los argumentos opcionales, el número máximo de cuadros para dibujar se establece en 200 y el grosor de la línea se establece en 8.

Guardar la imagen con detecciones

Para guardar la imagen con los cuadros superpuestos que representan las detecciones, agregue las siguientes líneas:

                      
                            # Save image with detections

    img = Image.fromarray(image_np_with_detections)

    img_filename = image[0:-4] + "_detect" + image[-4:]

    img.save(img_filename)

                      
                    

La nueva imagen se guarda con _detectar añadido a su nombre original.

Código final

Para fines de referencia, el código completo:

                      
                        import tensorflow as tf

import numpy as np

from PIL import Image

from object_detection.utils import label_map_util

from object_detection.utils import visualization_utils as viz_utils



def download_model(model_name, model_date):

    base_url="https://download.tensorflow.org/models/object_detection/tf2/"

    model_file = model_name + '.tar.gz'

    model_dir = tf.keras.utils.get_file(fname=model_name,

                                        origin=base_url + model_date + "https://www.vultr.com/" + model_file,

                                        untar=True)

    return str(model_dir)



# Download model

model_name = "ssd_resnet152_v1_fpn_1024x1024_coco17_tpu-8"

model_date = "20200711"

PATH_TO_MODEL_DIR = download_model(model_name, model_date)



# Load model

model_fn = tf.saved_model.load(PATH_TO_MODEL_DIR + "/saved_model")



# Load labels

PATH_TO_LABELS = 'models/research/object_detection/data/mscoco_label_map.pbtxt'

category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)



# Images to run detection

images = ["image1.jpg", "image2.jpg"]



for image in images:

    print(f"Running inference for image - {image}")



    # Load image into a numpy array

    image_np = np.array(Image.open(image))



    # Convert image to tensor

    input_tensor = tf.convert_to_tensor(image_np)



    # Add an axis

    input_tensor = input_tensor[tf.newaxis, ...]



    # Run inference

    detections = model_fn(input_tensor)



    # Outputs are tensor batches.

    # Convert to numpy arrays, and take index [0] to remove the batch dimension.

    num_detections = int(detections.pop('num_detections'))

    detections = {key: value[0, :num_detections].numpy()

                  for key, value in detections.items()}

    detections['num_detections'] = num_detections



    # detection_classes cast as ints.

    detections['detection_classes'] = detections['detection_classes'].astype(np.int64)



    image_np_with_detections = image_np.copy()



    viz_utils.visualize_boxes_and_labels_on_image_array(

            image_np_with_detections,

            detections['detection_boxes'],

            detections['detection_classes'],

            detections['detection_scores'],

            category_index,

            use_normalized_coordinates=True,

            max_boxes_to_draw=200,

            min_score_thresh=.30,

            agnostic_mode=False,

            line_thickness=8)



    # Save image with detections

    img = Image.fromarray(image_np_with_detections)

    img_filename = image[0:-4] + "_detect" + image[-4:]

    img.save(img_filename)

                      
                    

Ejecutar el código

Para ejecutar el código, ingrese el siguiente comando desde el directorio del proyecto:

                      
                        $ python main.py

                      
                    

Producción:

                      
                        Downloading data from https://download.tensorflow.org/models/object_detection/tf2/20200711/ssd_resnet152_v1_fpn_1024x

1024_coco17_tpu-8.tar.gz

504180168/504180168 [==============================] - 133s 0us/step



Running inference for image - image1.jpg

Running inference for image - image2.jpg

                      
                    

El código descarga con éxito el modelo e infiere objetos de las imágenes. Dentro del directorio del proyecto, las imágenes guardadas detectadas por objetos están presentes:

                      
                        .

├── env/

└── models/

└── cocoapi/

└── main.py

└── image1.jpg

└── image1_detect.jpg

└── image2.jpg

└── image2_detect.jpg

                      
                    

Abre las nuevas imágenes:

Foto de playa de personas y objetos detectados.

Foto de 3 perros detectados

En la primera imagen, el detector de objetos etiqueta correctamente todos los objetos, mientras que en la segunda imagen reconoció 3 animales pero clasificó al perro en el medio como un oso debido a características sorprendentemente similares.

Conclusión

Esta guía cubrió la detección de objetos y cómo construir un detector de objetos en TensorFlow.

Título del artículo Nombre (opcional) Correo electrónico (opcional) Descripción

Enviar sugerencia

Related Posts