Rumah > pembangunan bahagian belakang > Tutorial Python > Projek Python Permulaan: Bina Apl Lukisan Realiti Diperkukuh Menggunakan OpenCV dan Mediapipe

Projek Python Permulaan: Bina Apl Lukisan Realiti Diperkukuh Menggunakan OpenCV dan Mediapipe

Linda Hamilton
Lepaskan: 2025-01-02 14:47:38
asal
743 orang telah melayarinya

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

Dalam projek Python ini, kami akan mencipta apl lukisan AR yang ringkas. Menggunakan kamera web dan gerak isyarat tangan anda, anda boleh melukis secara maya pada skrin, menyesuaikan berus anda dan juga menyimpan ciptaan anda!

Persediaan

Untuk bermula, buat folder baharu dan mulakan persekitaran maya baharu menggunakan:

python -m venv venv
Salin selepas log masuk
./venv/Scripts/activate
Salin selepas log masuk

Seterusnya pasang perpustakaan yang diperlukan menggunakan pip atau pemasang pilihan anda:

pip install mediapipe
Salin selepas log masuk
pip install opencv-python
Salin selepas log masuk

Nota

Anda mungkin menghadapi masalah memasang mediapipe dengan versi terkini pada python. Semasa saya menulis blog ini saya menggunakan python 3.11.2. Pastikan anda menggunakan versi yang serasi pada python.

Langkah 1: Tangkap Suapan Webcam

Langkah pertama ialah menyediakan kamera web anda dan memaparkan suapan video. Kami akan menggunakan VideoCapture OpenCV untuk mengakses kamera dan memaparkan bingkai secara berterusan.

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()

Salin selepas log masuk

Tahukah Anda?

Apabila menggunakan cv2.waitKey() dalam OpenCV, kod kunci yang dikembalikan mungkin termasuk bit tambahan bergantung pada platform. Untuk memastikan anda mengesan penekanan kekunci dengan betul, anda boleh menutup hasilnya dengan 0xFF untuk mengasingkan 8 bit yang lebih rendah (nilai ASCII sebenar). Tanpa ini, perbandingan utama anda mungkin gagal pada sesetengah sistem—jadi sentiasa gunakan & 0xFF untuk tingkah laku yang konsisten!

Langkah 2: Sepadukan Pengesanan Tangan

Menggunakan penyelesaian Mediapipe's Hands, kami akan mengesan tangan dan mengekstrak kedudukan tanda tempat utama seperti jari telunjuk dan tengah.

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()

Salin selepas log masuk

Langkah 3: Jejaki Kedudukan Jari dan Lukis

Kami akan menjejaki jari telunjuk dan membenarkan lukisan hanya apabila jari telunjuk dan jari tengah dipisahkan oleh jarak ambang.

Kami akan mengekalkan senarai koordinat jari telunjuk untuk dilukis pada bingkai asal dan setiap kali jari tengah cukup dekat, kami akan menambahkan Tiada pada tatasusunan koordinat ini yang menunjukkan kerosakan.

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()

Salin selepas log masuk

Langkah 4: Penambahbaikan

  • Gunakan OpenCV rectangle() dan putText() untuk butang togol saiz dan warna berus.
  • Tambah pilihan untuk menyimpan bingkai.
  • Tambah alat pemadam, gunakan koordinat baharu untuk mengubah suai tatasusunan draw_points.

Atas ialah kandungan terperinci Projek Python Permulaan: Bina Apl Lukisan Realiti Diperkukuh Menggunakan OpenCV dan Mediapipe. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan