Heim > Backend-Entwicklung > Python-Tutorial > Python-Projekt für Anfänger: Erstellen Sie eine Augmented Reality-Zeichen-App mit OpenCV und Mediapipe

Python-Projekt für Anfänger: Erstellen Sie eine Augmented Reality-Zeichen-App mit OpenCV und Mediapipe

Linda Hamilton
Freigeben: 2025-01-02 14:47:38
Original
743 Leute haben es durchsucht

Beginner Python Project: Build an Augmented Reality Drawing App Using OpenCV and Mediapipe

In diesem Python-Projekt erstellen wir eine einfache AR-Zeichen-App. Mithilfe Ihrer Webcam und Handgesten können Sie virtuell auf dem Bildschirm zeichnen, Ihren Pinsel anpassen und sogar Ihre Kreationen speichern!

Aufstellen

Erstellen Sie zunächst einen neuen Ordner und initialisieren Sie eine neue virtuelle Umgebung mit:

python -m venv venv
Nach dem Login kopieren
./venv/Scripts/activate
Nach dem Login kopieren

Als nächstes installieren Sie die erforderlichen Bibliotheken mit pip oder einem Installationsprogramm Ihrer Wahl:

pip install mediapipe
Nach dem Login kopieren
pip install opencv-python
Nach dem Login kopieren

Hinweis

Möglicherweise haben Sie Probleme bei der Installation von mediapipe mit der neuesten Version auf Python. Während ich diesen Blog schreibe, verwende ich Python 3.11.2. Stellen Sie sicher, dass Sie die kompatible Version auf Python verwenden.

Schritt 1: Erfassen Sie den Webcam-Feed

Der erste Schritt besteht darin, Ihre Webcam einzurichten und den Video-Feed anzuzeigen. Wir verwenden VideoCapture von OpenCV, um auf die Kamera zuzugreifen und kontinuierlich Frames anzuzeigen.

import cv2  

# The argument '0' specifies the default camera (usually the built-in webcam).
cap = cv2.VideoCapture(0)

# Start an infinite loop to continuously capture video frames from the webcam
while True:
    # Read a single frame from the webcam
    # `ret` is a boolean indicating success; `frame` is the captured frame.
    ret, frame = cap.read()

    # Check if the frame was successfully captured
    # If not, break the loop and stop the video capture process.
    if not ret:
        break

    # Flip the frame horizontally (like a mirror image)
    frame = cv2.flip(frame, 1)

    # Display the current frame in a window named 'Webcam Feed'
    cv2.imshow('Webcam Feed', frame)

    # Wait for a key press for 1 millisecond
    # If the 'q' key is pressed, break the loop to stop the video feed.
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Release the webcam resource to make it available for other programs
cap.release()

# Close all OpenCV-created windows
cv2.destroyAllWindows()

Nach dem Login kopieren

Wussten Sie schon?

Bei Verwendung von cv2.waitKey() in OpenCV kann der zurückgegebene Schlüsselcode je nach Plattform zusätzliche Bits enthalten. Um sicherzustellen, dass Sie Tastendrücke korrekt erkennen, können Sie das Ergebnis mit 0xFF maskieren, um die unteren 8 Bits (den tatsächlichen ASCII-Wert) zu isolieren. Ohne dies könnten Ihre Schlüsselvergleiche auf einigen Systemen fehlschlagen – verwenden Sie daher immer & 0xFF für konsistentes Verhalten!

Schritt 2: Integrieren Sie die Handerkennung

Mithilfe der Hands-Lösung von Mediapipe erkennen wir die Hand und extrahieren die Position wichtiger Orientierungspunkte wie Zeige- und Mittelfinger.

import cv2  
import mediapipe as mp

# Initialize the MediaPipe Hands module
mp_hands = mp.solutions.hands  # Load the hand-tracking solution from MediaPipe
hands = mp_hands.Hands(
    min_detection_confidence=0.9,
    min_tracking_confidence=0.9 
)

cap = cv2.VideoCapture(0)
while True:
    ret, frame = cap.read()
    if not ret:
        break 

    # Flip the frame horizontally to create a mirror effect
    frame = cv2.flip(frame, 1)

    # Convert the frame from BGR (OpenCV default) to RGB (MediaPipe requirement)
    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    # Process the RGB frame to detect and track hands
    result = hands.process(frame_rgb)

    # If hands are detected in the frame
    if result.multi_hand_landmarks:
        # Iterate through all detected hands
        for hand_landmarks in result.multi_hand_landmarks:
            # Get the frame dimensions (height and width)
            h, w, _ = frame.shape

            # Calculate the pixel coordinates of the tip of the index finger
            cx, cy = int(hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP].x * w), \
                     int(hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP].y * h)

            # Calculate the pixel coordinates of the tip of the middle finger
            mx, my = int(hand_landmarks.landmark[mp_hands.HandLandmark.MIDDLE_FINGER_TIP].x * w), \
                     int(hand_landmarks.landmark[mp_hands.HandLandmark.MIDDLE_FINGER_TIP].y * h)

            # Draw a circle at the index finger tip on the original frame
            cv2.circle(frame, (cx, cy), 10, (0, 255, 0), -1)  # Green circle with radius 10

    # Display the processed frame in a window named 'Webcam Feed'
    cv2.imshow('Webcam Feed', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break  # Exit the loop if 'q' is pressed

# Release the webcam resources for other programs
cap.release()
cv2.destroyAllWindows()

Nach dem Login kopieren

Schritt 3: Fingerposition verfolgen und zeichnen

Wir verfolgen den Zeigefinger und erlauben das Zeichnen nur, wenn Zeige- und Mittelfinger einen Mindestabstand voneinander haben.

Wir führen eine Liste der Koordinaten der Zeigefinger, die auf dem Originalrahmen gezeichnet werden sollen, und jedes Mal, wenn der Mittelfinger nahe genug ist, hängen wir None an dieses Koordinatenarray an, was auf einen Bruch hinweist.

import cv2  
import mediapipe as mp  
import math  

# Initialize the MediaPipe Hands module
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(
    min_detection_confidence=0.9,  
    min_tracking_confidence=0.9   
)

# Variables to store drawing points and reset state
draw_points = []  # A list to store points where lines should be drawn
reset_drawing = False  # Flag to indicate when the drawing should reset

# Brush settings
brush_color = (0, 0, 255)  
brush_size = 5 


cap = cv2.VideoCapture(0)
while True:
    ret, frame = cap.read()  
    if not ret:
        break 

    frame = cv2.flip(frame, 1) 
    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 
    result = hands.process(frame_rgb)  

    # If hands are detected
    if result.multi_hand_landmarks:
        for hand_landmarks in result.multi_hand_landmarks:
            h, w, _ = frame.shape  # Get the frame dimensions (height and width)

            # Get the coordinates of the index finger tip
            cx, cy = int(hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP].x * w), \
                     int(hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP].y * h)

            # Get the coordinates of the middle finger tip
            mx, my = int(hand_landmarks.landmark[mp_hands.HandLandmark.MIDDLE_FINGER_TIP].x * w), \
                     int(hand_landmarks.landmark[mp_hands.HandLandmark.MIDDLE_FINGER_TIP].y * h)

            # Calculate the distance between the index and middle finger tips
            distance = math.sqrt((mx - cx) ** 2 + (my - cy) ** 2)

            # Threshold distance to determine if the fingers are close (used to reset drawing)
            threshold = 40 

            # If the fingers are far apart
            if distance > threshold:
                if reset_drawing:  # Check if the drawing was previously reset
                    draw_points.append(None)  # None means no line
                    reset_drawing = False  
                draw_points.append((cx, cy))  # Add the current point to the list for drawing
            else:  # If the fingers are close together set the flag to reset drawing
                reset_drawing = True  # 

    # Draw the lines between points in the `draw_points` list
    for i in range(1, len(draw_points)):
        if draw_points[i - 1] and draw_points[i]:  # Only draw if both points are valid
            cv2.line(frame, draw_points[i - 1], draw_points[i], brush_color, brush_size)


    cv2.imshow('Webcam Feed', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Release the webcam and close all OpenCV windows
cap.release()
cv2.destroyAllWindows()

Nach dem Login kopieren

Schritt 4: Verbesserungen

  • Verwenden Sie OpenCV rechteck() und putText() für Schaltflächen, um Pinselgröße und -farbe umzuschalten.
  • Fügen Sie eine Option zum Speichern des Rahmens hinzu.
  • Fügen Sie ein Radiergummi-Werkzeug hinzu und verwenden Sie die neuen Koordinaten, um das Array „draw_points“ zu ändern.

Das obige ist der detaillierte Inhalt vonPython-Projekt für Anfänger: Erstellen Sie eine Augmented Reality-Zeichen-App mit OpenCV und Mediapipe. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage