馃 Detecci贸n de objetos con YOLOv3 (80 categor铆as) usando DNN de OpenCV | Python

Por Administrador

Hemos venido trabajando con el m贸dulo dnn de OpenCV para la detecci贸n de rostros y de objetos (20 categor铆as) en im谩genes. En esta ocasi贸n veremos como aplicar detecci贸n de objetos usando YOLOv3, que nos permitir谩 detectarlos de entre 80 categor铆as. As铆 que… 隆Vamos con la programaci贸n!

CONTENIDO

Detecci贸n de objetos con YOLOv3 (80 categor铆as) usando DNN de OpenCV

  • Instalaci贸n de packages
  • 隆Vamos con la programaci贸n!
  • Referencias

Detecci贸n de objetos con YOLOv3 (80 categor铆as) usando DNN de OpenCV

Nuestro objetivo en esta ocasi贸n ser谩 usar YOLOv3 junto con el m贸dulo DNN de OpenCV para detectar objetos en im谩genes, para ello necesitaremos de 3 archivos.

Puedes dar clic en estos archivos y se descargar谩n autom谩ticamente. O podr铆as visitar el tutorial de OpenCV para el uso de YOLO que te dejo a continuaci贸n: https://opencv-tutorial.readthedocs.io/en/latest/yolo/yolo.html

Por otro lado, si te sientes atra铆do por la construcci贸n de la red, puedes visitar este post: https://towardsdatascience.com/yolo-v3-object-detection-53fb7d3bfe6b El cual posee una explicaci贸n m谩s extendida de toda la estructura y procedimiento para construir YOLOv3.

Este detector de objetos nos permitir谩 detectar objetos de entre 80 categor铆as. Cada una de ellas se encuentra descrita en el archivo coco.names. Estas son: person, bicycle, car, motorbike, aeroplane, bus, train, truck, boat, traffic light, fire hydrant, stop sign, parking meter, bench, bird, cat, dog, horse, sheep, cow, elephant, bear, zebra, giraffe, backpack, umbrella, handbag, tie, suitcase, frisbee, skis, snowboard, sports ball, kite, baseball bat, baseball glove, skateboard, surfboard, tennis racket, bottle, wine glass, cup, fork, knife, spoon, bowl, banana, apple, sandwich, orange, broccoli, carrot, hot dog, pizza, donut, cake, chair, sofa, pottedplant, bed, diningtable, toilet, tvmonitor, laptop, mouse, remote, keyboard, cell phone, microwave, oven, toaster, sink, refrigerator, book, clock, vase, scissors, teddy bear, hair drier, toothbrush.

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. 

隆Vamos con la programaci贸n!

Para una explicaci贸n m谩s detallada del programa 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 馃槈!.

import cv2
import numpy as np

# --------------- READ DNN MODEL ---------------
# Model configuration
config = "model/yolov3.cfg"
# Weights
weights = "model/yolov3.weights"
# Labels
LABELS = open("model/coco.names").read().split("\n")
#print(LABELS, len(LABELS))
colors = np.random.randint(0, 255, size=(len(LABELS), 3), dtype="uint8")
#print("colors.shape:", colors.shape)

# Load model
net = cv2.dnn.readNetFromDarknet(config, weights)

# --------------- READ THE IMAGE AND PREPROCESSING ---------------
image = cv2.imread("Images/imagen_0005.jpg")
height, width, _ = image.shape

# Create a blob
blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416),
                              swapRB=True, crop=False)
#print("blob.shape:", blob.shape)

# --------------- DETECTIONS AND PREDICTIONS ---------------
ln = net.getLayerNames()
#print("ln:", ln)

# ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()] 
ln = [ln[i - 1] for i in net.getUnconnectedOutLayers()]
#print("ln:", ln)

net.setInput(blob)
outputs = net.forward(ln)
#print("outputs:", outputs)

boxes = []
confidences = []
classIDs = []

for output in outputs:
     for detection in output:
          #print("detection:", detection)
          scores = detection[5:]
          classID = np.argmax(scores)
          confidence = scores[classID]

          if confidence > 0.5:
               #print("detection:", detection)
               #print("classID:", classID)
               box = detection[:4] * np.array([width, height, width, height])
               #print("box:", box)
               (x_center, y_center, w, h) = box.astype("int")
               #print((x_center, y_center, w, h))
               x = int(x_center - (w / 2))
               y = int(y_center - (h / 2))
               #cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

               boxes.append([x, y, w, h])
               confidences.append(float(confidence))
               classIDs.append(classID)

idx = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.5)
print("idx:", idx)

if len(idx) > 0:
     for i in idx:
          (x, y) = (boxes[i][0], boxes[i][1])
          (w, h) = (boxes[i][2], boxes[i][3])

          color = colors[classIDs[i]].tolist()
          text = "{}: {:.3f}".format(LABELS[classIDs[i]], confidences[i])
          cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
          cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX,
                         0.5, color, 2)

cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Al probar el programa podremos obtener resultados como los siguientes:

Figura 2: Detecci贸n de objetos con YOLOv3.

Como podemos visualizar, tenemos distintos colores para los cuadros delimitadores que rodean los objetos y para las etiquetas. Estos colores variar谩n cada vez que ejecutemos el programa, pero se mantendr谩n para cada objeto.

Figura 3: Detecci贸n de objetos con YOLOv3.

Figura 4: Detecci贸n de objetos con YOLOv3.

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

馃敆 Tutorial OpenCV para YOLO: https://opencv-tutorial.readthedocs.io/en/latest/yolo/yolo.html
馃敆 Post YOLOv3: https://towardsdatascience.com/yolo-v3-object-detection-53fb7d3bfe6b

馃敆 https://docs.opencv.org/4.5.3/d6/d0f/group__dnn.html#ga29f34df9376379a603acd8df581ac8d7
馃敆 https://docs.opencv.org/3.4/d6/d0f/group__dnn.html#ga9d118d70a1659af729d01b10233213ee
馃敆 https://pyimagesearch.com/2018/11/12/yolo-object-detection-with-opencv/
馃敆 https://learnopencv.com/deep-learning-based-object-detection-using-yolov3-with-opencv-python-c/
馃敆 https://stackoverflow.com/questions/66701910/why-nmsboxes-is-not-eleminating-multiple-bounding-boxes