En este tutorial, veremos cómo realizar el reconocimiento de objetos con Python utilizando una red neuronal pre-entrenada utilizando deep learning.
En un tutorial anterior vimos cómo reconocer formas simples mediante visión por ordenador. Este método sólo funciona para ciertas formas simples predefinidas. Si quieres reconocer una mayor variedad de objetos, la forma más sencilla es utilizar la inteligencia artificial.
Hardware
- Un ordenador con una instalación de Python3
- Una camera
Principio
La inteligencia artificial es un campo de la informática en el que el propio programa aprende a realizar determinadas tareas. En particular, el reconocimiento visual. En este tutorial, vamos a utilizar una red neuronal entrenada para reconocer determinadas formas.
Se necesitan muchos datos para poder entrenar correctamente una red neuronal. Se ha demostrado que el aprendizaje es más rápido en una red neuronal entrenada para otra cosa. Por ejemplo, una red neuronal entrenada para reconocer perros se entrenará más fácilmente para reconocer gatos.
Configuración de Python
Si no, puedes descargar e instalar Python 3
A continuación, puede instalar las bibliotecas OpenCV, numpy e imutils necesarias.
pip3 install opencv-python numpy imutils
o
python3 -m pip install opencv-python numpy imutils
Descargar el modelo ModelNet-SSD
- archivo prototxt : https://github.com/nikmart/pi-object-detection/blob/master/MobileNetSSD_deploy.prototxt.txt
- archivo caffemodel : https://github.com/nikmart/pi-object-detection/blob/master/MobileNetSSD_deploy.caffemodel
Coloca los archivos del modelo en una carpeta y crea el archivo ObjectRecognition.py
Script en Python para el reconocimiento de objetos
En primer lugar, creamos un flujo de vídeo (vs) utilizando la biblioteca imutils, que recuperará las imágenes de la cámara.
vs = VideoStream(src=0, resolution=(1600, 1200)).start()
Inicializamos una red neuronal con los parámetros ModelNet-SSD (net) utilizando la biblioteca OpenCV.
net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"])
A continuación, crearemos un bucle que, en cada iteración, leerá la imagen de la cámara y la pasará a la entrada de la red neuronal para la detección y el reconocimiento de objetos.
while True:
# Get video stream. max width 800 pixels
frame = vs.read()
blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 0.007843, (300, 300), 127.5)
# Feed input to neural network
net.setInput(blob)
detections = net.forward()
Por último, el código muestra la casilla de detección y la probabilidad de reconocimiento en la imagen.
label = "{}: {:.2f}%".format(CLASSES[idx],confidence * 100)
cv2.rectangle(frame, (startX, startY), (endX, endY),COLORS[idx], 2)
y = startY - 15 if startY - 15 > 15 else startY + 15
cv2.putText(frame, label, (startX, y),cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2)
#!/usr/bin/env python # -*- coding: utf-8 -*- # # ObjectRecognition.py # Description: # Use ModelNet-SSD model to detect objects # # www.aranacorp.com # import packages import sys from imutils.video import VideoStream from imutils.video import FPS import numpy as np import argparse import imutils import time import cv2 # Arguments construction if len(sys.argv)==1: args={ "prototxt":"MobileNetSSD_deploy.prototxt.txt", "model":"MobileNetSSD_deploy.caffemodel", "confidence":0.2, } else: #lancement à partir du terminal #python3 ObjectRecognition.py --prototxt MobileNetSSD_deploy.prototxt.txt --model MobileNetSSD_deploy.caffemodel ap = argparse.ArgumentParser() ap.add_argument("-p", "--prototxt", required=True, help="path to Caffe 'deploy' prototxt file") ap.add_argument("-m", "--model", required=True, help="path to Caffe pre-trained model") ap.add_argument("-c", "--confidence", type=float, default=0.2, help="minimum probability to filter weak detections") args = vars(ap.parse_args()) # ModelNet SSD Object list init CLASSES = ["arriere-plan", "avion", "velo", "oiseau", "bateau", "boteille", "autobus", "voiture", "chat", "chaise", "vache", "table", "chien", "cheval", "moto", "personne", "plante en pot", "moton", "sofa", "train", "moniteur"] COLORS = np.random.uniform(0, 255, size=(len(CLASSES), 3)) # Load model file print("Load Neural Network...") net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"]) if __name__ == '__main__': # Camera initialisation print("Start Camera...") vs = VideoStream(src=0, resolution=(1600, 1200)).start() #vs = VideoStream(usePiCamera=True, resolution=(1600, 1200)).start() #vc = cv2.VideoCapture('./img/Splash - 23011.mp4') #from video time.sleep(2.0) fps = FPS().start() #Main loop while True: # Get video sttream. max width 800 pixels frame = vs.read() #frame= cv2.imread('./img/two-boats.jpg') #from image file #ret, frame=vc.read() #from video or ip cam frame = imutils.resize(frame, width=800) # Create blob from image (h, w) = frame.shape[:2] blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 0.007843, (300, 300), 127.5) # Feed input to neural network net.setInput(blob) detections = net.forward() # Detection loop for i in np.arange(0, detections.shape[2]): # Compute Object detection probability confidence = detections[0, 0, i, 2] # Suppress low probability if confidence > args["confidence"]: # Get index and position of detected object idx = int(detections[0, 0, i, 1]) box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) (startX, startY, endX, endY) = box.astype("int") # Create box and label label = "{}: {:.2f}%".format(CLASSES[idx], confidence * 100) cv2.rectangle(frame, (startX, startY), (endX, endY), COLORS[idx], 2) y = startY - 15 if startY - 15 > 15 else startY + 15 cv2.putText(frame, label, (startX, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2) # enregistrement de l'image détectée cv2.imwrite("detection.png", frame) # Show video frame cv2.imshow("Frame", frame) key = cv2.waitKey(1) & 0xFF # Exit script with letter q if key == ord("q"): break # FPS update fps.update() # Stops fps and display info fps.stop() print("[INFO] elapsed time: {:.2f}".format(fps.elapsed())) print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) cv2.destroyAllWindows() vs.stop() vc.release()
Salidas de imagen para la detección de objetos
Puede utilizar este script con distintos tipos de imagen. Para ello, es necesario adaptar ligeramente el código anterior para modificar la variable «frame» que contiene la imagen que se va a analizar.
- La cámara web de tu ordenador
vs = VideoStream(src=0, resolution=(1600, 1200)).start() while True: frame = vs.read()
- Una camera IP
vc = cv2.VideoCapture('rtsp://user:password@ipaddress:rtspPort') while True: ret, frame=vc.read() #from ip cam
- La Raspberry Pi Picam
vs = VideoStream(usePiCamera=True, resolution=(1600, 1200)).start() while True: frame = vs.read()
- Un archivo de vídeo
vc = cv2.VideoCapture('./img/Splash - 23011.mp4') #from video while True: ret, frame=vc.read() #from video
- Un archivo de imagen
frame= cv2.imread('./img/two-boats.jpg')
Resultados
Para este ejemplo, enviamos a la red neuronal una imagen de dos barcos que son reconocidos correctamente. Para obtener resultados ligeramente diferentes, puede modificar el parámetro de confianza para evitar falsos positivos.
Puedes probar este código con tu webcam o con fotos, por ejemplo, para ver cómo funcionan el modelo y el reconocimiento de objetos.
Una vez que tu script funcione, puedes entrenar tu modelo para detectar otros objetos.
Paquetes y modelos
En este tutorial, hemos utilizado el modelo preentrenado ModelNet-SSD. Ten en cuenta que existen otros modelos de reconocimiento como Coco y otras librerías de reconocimiento visual como ImageIA.
No dudes en dejarnos un comentario para compartir las herramientas que utilizas o conoces.