[Python] My Mediapipe+OpenCV realtime posture analysis doesn't work

Discussão em 'Python' iniciado por Stack, Abril 10, 2025.

  1. Stack

    Stack Membro Participativo

    My code below (I use google colab) shows the posture analysis for still image that was captured by my laptop's webcam, but I want "real-time" posture analysis directly to moving image captured by the same webcam, not the still photo. Please help to figure out what part of my code has to be fixed to achieve this goal. thanks!

    Código:
     !pip install --upgrade --force-reinstall numpy mediapipe opencv-python !pip install numpy==1.23.5 mediapipe==0.10.3 opencv-python==4.7.0.72 --force- reinstall !pip install --upgrade --force-reinstall --no-cache-dir numpy mediapipe opencv-python
    
    from google.colab import output
    from IPython.display import display, clear_output
    import cv2
    import numpy as np
    import PIL.Image
    import io
    import base64
    import mediapipe as mp
    import matplotlib.pyplot as plt
    
    [SIZE=6][B]Mediapipe setup[/B][/SIZE]
    
    
    mp_pose = mp.solutions.pose
    mp_drawing = mp.solutions.drawing_utils
    pose = mp_pose.Pose(static_image_mode=True)
    
    def calculate_angle(a, b, c):
    a = np.array(a)
    b = np.array(b)
    c = np.array(c)
    radians = np.arctan2(c\[1\]-b\[1\], c\[0\]-b\[0\]) - \
    np.arctan2(a\[1\]-b\[1\], a\[0\]-b\[0\])
    angle = np.abs(radians \* 180.0 / np.pi)
    if angle \> 180.0:
    angle = 360 - angle
    return angle
    
    def data_url_to_image(data_url):
    header, encoded = data_url.split(",", 1)
    img_bytes = base64.b64decode(encoded)
    img = PIL.Image.open(io.BytesIO(img_bytes))
    return cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
    
    def process_streamed_image(data_url):
    image_bgr = data_url_to_image(data_url)
    image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
    results = pose.process(image_rgb)
    annotated = image_rgb.copy()
    
        if results.pose_landmarks:
            mp_drawing.draw_landmarks(annotated, results.pose_landmarks,    mp_pose.POSE_CONNECTIONS)
    
            landmarks = results.pose_landmarks.landmark
            h, w, _ = annotated.shape
    
            def get_point(idx):
                return [landmarks[idx].x * w, landmarks[idx].y * h]
    
            shoulder = get_point(mp_pose.PoseLandmark.RIGHT_SHOULDER.value)
            hip = get_point(mp_pose.PoseLandmark.RIGHT_HIP.value)
            ankle = get_point(mp_pose.PoseLandmark.RIGHT_ANKLE.value)
            elbow = get_point(mp_pose.PoseLandmark.RIGHT_ELBOW.value)
            wrist = get_point(mp_pose.PoseLandmark.RIGHT_WRIST.value)
    
            body_angle = calculate_angle(shoulder, hip, ankle)
            arm_angle = calculate_angle(shoulder, elbow, wrist)
    
            if 160 < body_angle < 175 and 160 < arm_angle < 175:
                feedback = "✅ Nice One"
                color = (0, 255, 0)
            else:
                feedback = "⚠️ Not perfect long line body"
                color = (255, 0, 0)
    
            cv2.putText(annotated, feedback, (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 3)
            cv2.putText(annotated, f'Arm: {int(arm_angle)} deg', (20, 80),     cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2)
            cv2.putText(annotated, f'Body: {int(body_angle)} deg', (20, 120), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2)
    
        clear_output(wait=True)
        plt.figure(figsize=(10, 10))
        plt.imshow(annotated)
        plt.axis('off')
        plt.title("Live Pose Feedback")
        plt.show()
    
    [SIZE=6][B]Register callback[/B][/SIZE]
    
    
    output.register_callback('sendImageToPython', process_streamed_image)
    
    from IPython.display import HTML
    
    HTML("""
    \<video id="camera" autoplay playsinline width="640" height="480"\>\</video\>
    \<canvas id="canvas" width="640" height="480" style="display:none;"\>\</canvas\>
    
    <p>Starting webcam...</p>
    
    
    const video = document.getElementById('camera');
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    const statusText = document.getElementById('status');
    
    let sending = false;
    let streamStarted = false;
    
    // 1. Get webcam
    navigator.mediaDevices.getUserMedia({ video: true }).then(stream =\> {
      video.srcObject = stream;
      video.onplaying = () =\> {
        if (!streamStarted) {
          streamStarted = true;
          statusText.textContent = "✅ Webcam is live and capturing!";
          sendFrame();  // start sending automatically
        }
      };
    }).catch(err =\> {
      statusText.textContent = "❌ Webcam error: " + err;
    });
    
    // 2. Send frame to Python every 1 second
    function sendFrame() {
      if (!sending) {
        sending = true;
        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
        const imageData = canvas.toDataURL('image/jpeg');
    
        google.colab.kernel.invokeFunction('sendImageToPython', \[imageData\], {})
          .then(() =\> {
            sending = false;
            setTimeout(sendFrame, 1000);
          })
          .catch(err =\> {
            console.error("Send failed", err);
            sending = false;
            setTimeout(sendFrame, 1500);
          });
      }
    }
    
    
    """)`
    
    
    I have tried to achieve a real-time moving image posture analysis but hasn't been successful`
    
    [url="https://stackoverflow.com/questions/79567501/my-mediapipeopencv-realtime-posture-analysis-doesnt-work"]Continue reading...[/url]

Compartilhe esta Página