DEV Community

Beck_Moulton
Beck_Moulton

Posted on

Stop Slouching! Build a Real-Time Spine Posture Monitor using MediaPipe and Python

We’ve all been there: hunched over a keyboard at 3 AM, neck craned forward like a turtle, debugging a race condition. "Tech neck" isn't just a meme; it’s a productivity killer. As developers, our spine is our most underrated hardware.

In this tutorial, we are going to build a Real-Time Spine Posture Monitor. We will leverage real-time human pose estimation and MediaPipe Python libraries to track your posture via your webcam. By the end of this guide, you'll have a system that detects when you're slouching and sends a system notification to keep your ergonomics in check. This project is perfect for those looking into OpenCV computer vision and developer ergonomics solutions.

The Architecture 🏗️

The logic is straightforward: we capture video frames, process them through a pre-trained neural network to find body landmarks, and apply some basic geometry to determine if your posture is healthy.

graph TD
    A[Webcam Feed] --> B[OpenCV Frame Processing]
    B --> C[MediaPipe Pose Landmark Detection]
    C --> D{Extract Shoulder & Ear Coordinates}
    D --> E[Calculate Neck Inclination Angle]
    E --> F{Angle > Threshold?}
    F -- Yes --> G[Trigger System Notification]
    F -- No --> H[Continue Monitoring]
    G --> B
    H --> B
Enter fullscreen mode Exit fullscreen mode

Prerequisites 🛠️

Before we dive into the code, ensure you have the following installed:

  • Python 3.9+
  • MediaPipe: Google’s framework for cross-platform ML.
  • OpenCV: For video stream handling.
  • PyObjC: (For macOS) to trigger native system alerts.
pip install mediapipe opencv-python pyobjc
Enter fullscreen mode Exit fullscreen mode

Step 1: Initialize the Pose Engine

MediaPipe makes pose estimation incredibly easy. We’ll use the Pose solution, which provides 33 3D landmarks for the human body.

import cv2
import mediapipe as mp
import math

# Initialize MediaPipe Pose
mp_pose = mp.solutions.pose
pose = mp_pose.Pose(
    static_image_mode=False,
    model_complexity=1,
    enable_segmentation=False,
    min_detection_confidence=0.5
)
mp_drawing = mp.solutions.drawing_utils
Enter fullscreen mode Exit fullscreen mode

Step 2: Calculating the "Slouch" Angle 📐

To detect a slouch, we measure the angle between the ear and the shoulder. In a perfect posture, your ear should be vertically aligned with your shoulder. As you lean forward, that angle increases.

def calculate_angle(a, b):
    """Calculates the angle between two points relative to the vertical axis."""
    # a: Ear, b: Shoulder
    radians = math.atan2(a.y - b.y, a.x - b.x)
    angle = abs(radians * 180.0 / math.pi)
    return angle
Enter fullscreen mode Exit fullscreen mode

Step 3: The Main Loop & Alert System

We will capture the webcam feed and use PyObjC to send a notification if the user stays in a bad posture for more than 3 seconds.

import Foundation
import objc

def send_notification(title, subtitle, info_text):
    """Sends a native macOS notification."""
    NSUserNotification = objc.lookUpClass('NSUserNotification')
    NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')

    notification = NSUserNotification.alloc().init()
    notification.setTitle_(title)
    notification.setSubtitle_(subtitle)
    notification.setInformativeText_(info_text)

    center = NSUserNotificationCenter.defaultUserNotificationCenter()
    center.deliverNotification_(notification)

cap = cv2.VideoCapture(0)

while cap.isOpened():
    success, image = cap.read()
    if not success: break

    # Convert BGR to RGB
    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    results = pose.process(image_rgb)

    if results.pose_landmarks:
        landmarks = results.pose_landmarks.landmark

        # Get coordinates for left ear and left shoulder
        ear = landmarks[mp_pose.PoseLandmark.LEFT_EAR]
        shoulder = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER]

        # Calculate neck angle
        neck_angle = calculate_angle(ear, shoulder)

        # Visual feedback: Draw landmarks
        mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)

        # Logic: If angle is less than 70 (or your specific threshold), alert!
        if neck_angle < 70:
            cv2.putText(image, "SLOUCHING DETECTED!", (50, 50), 
                        cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
            # Add a frame counter here to avoid spamming notifications
            send_notification("Posture Alert ⚠️", "Sit up straight!", "Your spine will thank you.")

    cv2.imshow('ErgoMonitor v1.0', image)
    if cv2.waitKey(5) & 0xFF == 27: break

cap.release()
Enter fullscreen mode Exit fullscreen mode

The "Official" Way to Build Health Tech 🥑

While this script is a great weekend project, building production-ready health monitoring tools involves handling edge cases like lighting conditions, multi-person detection, and battery optimization.

For more production-ready examples and advanced computer vision patterns, I highly recommend checking out the technical deep-dives at WellAlly Blog. They cover how to scale AI-driven ergonomic solutions for enterprise environments.

Conclusion 🚀

Congratulations! You’ve just built a personal AI coach for your spine. This project demonstrates how accessible MediaPipe and OpenCV have become for solving real-world, everyday problems.

Next Steps:

  1. Calibration: Add a feature to "calibrate" what a good posture looks like for you.
  2. Dashboard: Save your "slouch time" to a CSV and visualize your posture trends over a week using Matplotlib.
  3. Cross-Platform: Swap the notification system to win10toast for Windows support!

Don't forget to subscribe for more "Learning in Public" tutorials, and let me know in the comments: what's your biggest "desk habit" struggle? 👇

Top comments (0)