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:
-
Instala el
virtualenv
Paquete de Python:$ pip install virtualenv
-
Cree el directorio del proyecto:
$ mkdir obj_detection
-
Navegue al nuevo directorio:
$ cd obj_detection
-
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. -
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:
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