馃惁 Detecci贸n de 20 objetos con modelo pre-entrenado usando DNN de OpenCV | Python

Por Administrador

En el anterior tutorial vimos como detectar rostros en una imagen con ayuda del m贸dulo dnn de OpenCV, con este pudimos leer un modelo pre entrenado y ubicar el rostro en la imagen. En este tutorial veremos algo similar, solo que ha diferencia de las caras, podremos detectar varios objetos a la vez.

CONTENIDO

  • Detectando objetos usando el m贸dulo dnn de OpenCV
    • Instalaci贸n de packages
    • Descargar arquitectura y pesos del modelo para detectar objetos con dnn
    • 隆Vamos con la programaci贸n!
    • Referencias

Detectando objetos usando el m贸dulo dnn de OpenCV

Nuestro objetivo en esta ocasi贸n ser谩 detectar objetos dentro de una imagen o fotograma. Para ello usaremos la red MobileNetSSD. Los pesos asignados para esta aplicaci贸n han sido entrenados por terceros y nos permitir谩n determinar la ubicaci贸n de los objetos en la imagen, y adem谩s asignar las etiquetas que le corresponden. 

Esta red pre entrenada nos permitir谩 detectar 20 objetos: 

  • Aviones
  • Bicicletas
  • P谩jaros
  • Barcos
  • Botellas
  • Autobuses
  • Autos
  • Gatos
  • Sillas
  • Vacas
  • Comedores
  • Perros
  • Caballos
  • Motos
  • Personas
  • Plantas en macetas
  • Ovejas
  • Sof谩s
  • Trenes
  • Televisores

As铆 que vamos a empezar por la instalaci贸n de los packages que necesitamos.

Instalaci贸n de packages

Vamos a instalar OpenCV con pip install opencv-contrib-python. Si digitamos pip freeze podremos ver todos los paquetes instalados.

Figura 1: Lista de los m贸dulos instalados.

Te preguntar谩s, 驴de d贸nde sale Numpy?, si no lo hab铆amos instalado. Pues bien, al momento de instalar OpenCV, tambi茅n se instala Numpy.

IMPORTANTE: Hay que tomar en cuenta que para el uso del m贸dulo dnn, debemos contar con versiones igual o superiores a OpenCV 3.3. 

Descargar arquitectura y pesos del modelo para detectar objetos con dnn

Para descargar la arquitectura (MobileNetSSD_deploy.prototxt.txt) y pesos pre entrenados (MobileNetSSD_deploy.caffemodel) de la red por favor dir铆gete a este link.

隆Vamos con la programaci贸n!

Para una explicaci贸n m谩s detallada de los programas que veremos a continuaci贸n, por favor dir铆gete al video que he preparado en mi canal, en donde explico paso a pasito cada procedimiento efectuado. 隆An铆mate a verlo 馃槈!.

El primer programa que veremos es para aplicar el detector de objetos sobre una imagen (recuerda que para probarlo tendr谩s que cambiar los paths de la imagen, la arquitectura y los pesos):

import cv2

# ----------- READ DNN MODEL -----------
# Model architecture
prototxt = "model/MobileNetSSD_deploy.prototxt.txt"
# Weights
model = "model/MobileNetSSD_deploy.caffemodel"
# Class labels
classes = {0:"background", 1:"aeroplane", 2:"bicycle",
          3:"bird", 4:"boat",
          5:"bottle", 6:"bus",
          7:"car", 8:"cat",
          9:"chair", 10:"cow",
          11:"diningtable", 12:"dog",
          13:"horse", 14:"motorbike",
          15:"person", 16:"pottedplant",
          17:"sheep", 18:"sofa",
          19:"train", 20:"tvmonitor"}

# Load the model
net = cv2.dnn.readNetFromCaffe(prototxt, model)

# ----------- READ THE IMAGE AND PREPROCESSING -----------
image = cv2.imread("ImagesVideos/imagen_0004.jpg")
height, width, _ = image.shape
image_resized = cv2.resize(image, (300, 300))

# Create a blob
blob = cv2.dnn.blobFromImage(image_resized, 0.007843, (300, 300), (127.5, 127.5, 127.5))
print("blob.shape:", blob.shape)

# ----------- DETECTIONS AND PREDICTIONS -----------
net.setInput(blob)
detections = net.forward()

for detection in detections[0][0]:
     print(detection)

     if detection[2] > 0.45:
          label = classes[detection[1]]
          print("Label:", label)
          box = detection[3:7] * [width, height, width, height]
          x_start, y_start, x_end, y_end = int(box[0]), int(box[1]), int(box[2]), int(box[3])

          cv2.rectangle(image, (x_start, y_start), (x_end, y_end), (0, 255, 0), 2)
          cv2.putText(image, "Conf: {:.2f}".format(detection[2] * 100), (x_start, y_start - 5), 1, 1.2, (255, 0, 0), 2)
          cv2.putText(image, label, (x_start, y_start - 25), 1, 1.2, (255, 0, 0), 2)
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Luego tenemos el programa para que puedas probar este detector de objetos en video:

import cv2

# ----------- READ DNN MODEL -----------
# Model architecture
prototxt = "model/MobileNetSSD_deploy.prototxt.txt"
# Weights
model = "model/MobileNetSSD_deploy.caffemodel"
# Class labels
classes = {0:"background", 1:"aeroplane", 2:"bicycle",
          3:"bird", 4:"boat",
          5:"bottle", 6:"bus",
          7:"car", 8:"cat",
          9:"chair", 10:"cow",
          11:"diningtable", 12:"dog",
          13:"horse", 14:"motorbike",
          15:"person", 16:"pottedplant",
          17:"sheep", 18:"sofa",
          19:"train", 20:"tvmonitor"}

# Load the model
net = cv2.dnn.readNetFromCaffe(prototxt, model)

# ----------- READ THE IMAGE AND PREPROCESSING -----------
cap = cv2.VideoCapture("ImagesVideos/video_0004.mp4")

while True:
     ret, frame, = cap.read()
     if ret == False:
          break

     height, width, _ = frame.shape
     frame_resized = cv2.resize(frame, (300, 300))

     # Create a blob
     blob = cv2.dnn.blobFromImage(frame_resized, 0.007843, (300, 300), (127.5, 127.5, 127.5))
     #print("blob.shape:", blob.shape)

     # ----------- DETECTIONS AND PREDICTIONS -----------
     net.setInput(blob)
     detections = net.forward()

     for detection in detections[0][0]:
          #print(detection)

          if detection[2] > 0.45:
               label = classes[detection[1]]
               #print("Label:", label)
               box = detection[3:7] * [width, height, width, height]
               x_start, y_start, x_end, y_end = int(box[0]), int(box[1]), int(box[2]), int(box[3])

               cv2.rectangle(frame, (x_start, y_start), (x_end, y_end), (0, 255, 0), 2)
               cv2.putText(frame, "Conf: {:.2f}".format(detection[2] * 100), (x_start, y_start - 5), 1, 1.2, (255, 0, 0), 2)
               cv2.putText(frame, label, (x_start, y_start - 25), 1, 1.5, (0, 255, 255), 2)


     cv2.imshow("Frame", frame)
     if cv2.waitKey(1) & 0xFF == 27:
          break
cap.release()
cv2.destroyAllWindows()

Si pruebas estos programas podr谩s obtener algo como lo siguiente:

Figura 2: Detecci贸n de objetos con dnn de OpenCV, en im谩genes.

Figura 3: Detecci贸n de objetos con dnn de OpenCV, en videos.

Y bien, esto ha sido todo por el tutorial de hoy. 隆Espero que te haya gustado! 馃槉 Nos vemos en el siguiente鈥 隆Qu茅 te vaya s煤per bien!.

Referencias

馃敆 https://github.com/opencv/opencv/blob/4.x/samples/dnn/models.yml
馃敆 https://www.geeksforgeeks.org/deep-learning-with-python-opencv/
馃敆 https://pyimagesearch.com/2017/09/11/object-detection-with-deep-learning-and-opencv/
馃敆 https://github.com/opencv/opencv/blob/4.x/samples/data/dnn/object_detection_classes_pascal_voc.txt
馃敆 https://github.com/opencv/opencv/wiki/Deep-Learning-in-OpenCV