Sistema de seguimiento manual mediante OpenCV

Share on facebook
Share on twitter
Share on linkedin
Share on telegram
Share on whatsapp

Contenidos

Este artículo fue publicado como parte del Blogatón de ciencia de datos

OpenCV es una biblioteca utilizada para aplicaciones de visión por computadora. Con la ayuda de OpenCV, podemos crear una enorme cantidad de aplicaciones que funcionan mejor en tiempo real. Se utiliza principalmente para el procesamiento de imágenes y videos.

Puede obtener más información sobre OpenCV aquí (https://opencv.org/)

Junto con OpenCV, usaremos la biblioteca MediaPipe.

MediaPipe

MediaPipe es un marco que se utiliza principalmente para crear audio, video o cualquier dato de series de tiempo. Con la ayuda del marco MediaPipe, podemos construir pipelines muy impresionantes para diferentes funciones de procesamiento de medios.

Algunas de las principales aplicaciones de MediaPipe.

  • Seguimiento de varias manos
  • Detección de rostro
  • Detección y seguimiento de objetos
  • Objectron: detección y seguimiento de objetos 3D
  • AutoFlip: canalización automática de recorte de video, etc.

Modelo de hito de mano

Básicamente, MediaPipe utiliza un modelo de detección de palma de un solo disparo y, una vez hecho, realiza una localización precisa del punto clave de 21 coordenadas 3D de la palma en la región de la mano detectada.

La canalización de MediaPipe utiliza varios modelos, como un modelo de detección de palma que devuelve un cuadro delimitador de mano orientado a partir de la imagen completa. La región de la imagen recortada se alimenta a un modelo de referencia de mano definido por el detector de palma y devuelve puntos clave de mano 3D de alta fidelidad.

Ahora implementemos el modelo de seguimiento de manos.

Instale los módulos necesarios

-> pip instalar opencv-python

-> pip instalar mediapipe

Primero, verifiquemos el funcionamiento de la cámara web.

import cv2
import time
cap = cv2.VideoCapture(0)
pTime = 0
while True:
    success, img = cap.read()
    imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    cTime = time.time()
    fps = 1 / (cTime - pTime)
    pTime = cTime
    cv2.putText(img, f'FPS:{int(fps)}', (20, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
    cv2.imshow("Test", img)
    cv2.waitKey(1))
1424745-5875185

El código anterior mostrará una ventana emergente si hay una cámara web conectada a su PC y también muestra los fotogramas por segundo (fps) en la esquina superior izquierda de la ventana de salida.

Ahora comencemos la implementación. Importe los módulos necesarios e inicialice las variables necesarias.

import cv2
import mediapipe as mp
import time
cap = cv2.VideoCapture(0)

mpHands = mp.solutions.hands
hands = mpHands.Hands(static_image_mode=False,
                      max_num_hands=2,
                      min_detection_confidence=0.5,
                      min_tracking_confidence=0.5)
mpDraw = mp.solutions.drawing_utils

pTime = 0
cTime = 0

En el fragmento de código anterior, declaramos un objeto llamado «manos» de mp.solutions.hand para detectar las manos, por defecto, si miras dentro de la clase «Manos()“, El número de manos a detectar se establece en 2, la confianza de detección mínima se establece en 0.5 y la confianza de seguimiento mínima se establece en 0.5. Y usaremos mpDraw para dibujar los puntos clave.

Ahora escribamos un ciclo while para ejecutar nuestro código.

while True:
    success, img = cap.read()
    imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    results = hands.process(imgRGB)
    #print(results.multi_hand_landmarks)
    if results.multi_hand_landmarks:
        for handLms in results.multi_hand_landmarks:
            for id, lm in enumerate(handLms.landmark):
                #print(id,lm)
                h, w, c = img.shape
                cx, cy = int(lm.x *w), int(lm.y*h)
                #if id ==0:
                cv2.circle(img, (cx,cy), 3, (255,0,255), cv2.FILLED)

            mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)

    cTime = time.time()
    fps = 1/(cTime-pTime)
    pTime = cTime

    cv2.putText(img,str(int(fps)), (10,70), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,255), 3)

    cv2.imshow("Image", img)
    cv2.waitKey(1)

Aquí, en el código anterior, leemos los fotogramas de la cámara web y convertimos la imagen a RGB. Luego detectamos las manos en el marco con la ayuda de «hands.process () ” función. Una vez que se detectan las manos, ubicaremos los puntos clave y luego resaltaremos los puntos en los puntos clave usando cv2.circle, y conecta los puntos clave usando mpDraw.draw_landmarks.

El código completo se da a continuación

import cv2
import mediapipe as mp
import time
cap = cv2.VideoCapture(0)

mpHands = mp.solutions.hands
hands = mpHands.Hands(static_image_mode=False,
                      max_num_hands=2,
                      min_detection_confidence=0.5,
                      min_tracking_confidence=0.5)
mpDraw = mp.solutions.drawing_utils

pTime = 0
cTime = 0

while True:
    success, img = cap.read()
    imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    results = hands.process(imgRGB)
    #print(results.multi_hand_landmarks)

    if results.multi_hand_landmarks:
        for handLms in results.multi_hand_landmarks:
            for id, lm in enumerate(handLms.landmark):
                #print(id,lm)
                h, w, c = img.shape
                cx, cy = int(lm.x *w), int(lm.y*h)
                #if id ==0:
                cv2.circle(img, (cx,cy), 3, (255,0,255), cv2.FILLED)

            mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)


    cTime = time.time()
    fps = 1/(cTime-pTime)
    pTime = cTime

    cv2.putText(img,str(int(fps)), (10,70), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,255), 3)

    cv2.imshow("Image", img)
    cv2.waitKey(1)

La salida es:

6647846-4774798
Salida del modelo de seguimiento manual

Ahora creemos un módulo de seguimiento de manos, para que podamos usarlo en otros proyectos.

Cree un nuevo archivo de Python. Primero, creemos una clase llamada handDetector con dos funciones miembro en él, llamadas findHands y findPosition.

La función findHands aceptará una imagen RGB y detectará la mano en el marco y ubicará los puntos clave y dibujará los puntos de referencia, la función findPosition le dará la posición de la mano junto con la identificación.

Luego, la función principal donde inicializamos nuestro módulo y también escribimos un ciclo while para ejecutar el modelo. Aquí puede importar esta configuración o el módulo a cualquier otro proyecto relacionado.

El código completo se da a continuación

import cv2
import mediapipe as mp
import time
class handDetector():
    def __init__(self, mode = False, maxHands = 2, detectionCon = 0.5, trackCon = 0.5):
        self.mode = mode
        self.maxHands = maxHands
        self.detectionCon = detectionCon
        self.trackCon = trackCon

        self.mpHands = mp.solutions.hands
        self.hands = self.mpHands.Hands(self.mode, self.maxHands, self.detectionCon, self.trackCon)
        self.mpDraw = mp.solutions.drawing_utils
        
    def findHands(self,img, draw = True):
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        self.results = self.hands.process(imgRGB)
        # print(results.multi_hand_landmarks)

        if self.results.multi_hand_landmarks:
            for handLms in self.results.multi_hand_landmarks:
                if draw:
                    self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS)
        return img

    def findPosition(self, img, handNo = 0, draw = True):

        lmlist = []
        if self.results.multi_hand_landmarks:
            myHand = self.results.multi_hand_landmarks[handNo]
            for id, lm in enumerate(myHand.landmark):
                h, w, c = img.shape
                cx, cy = int(lm.x * w), int(lm.y * h)
                lmlist.append([id, cx, cy])
                if draw:
                    cv2.circle(img, (cx, cy), 3, (255, 0, 255), cv2.FILLED)
        return lmlist

def main():
    pTime = 0
    cTime = 0
    cap = cv2.VideoCapture(0)
    detector = handDetector()

    while True:
        success, img = cap.read()
        img = detector.findHands(img)
        lmlist = detector.findPosition(img)
        if len(lmlist) != 0:
            print(lmlist[4])

        cTime = time.time()
        fps = 1 / (cTime - pTime)
        pTime = cTime

        cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3)

        cv2.imshow("Image", img)
        cv2.waitKey(1)


if __name__ == "__main__":
    main()

La salida será la misma que se muestra arriba junto con las posiciones de las manos rastreadas.

8826047-9873258

El código completo también está disponible aquí.

Referencia:

https://www.youtube.com/watch?v=NZde8Xt78Iw

https://google.github.io/mediapipe/

Mi LinkedIn

Gracias.

Los medios que se muestran en este artículo no son propiedad de DataPeaker y se utilizan a discreción del autor.

Suscribite a nuestro Newsletter

No te enviaremos correo SPAM. Lo odiamos tanto como tú.