DEV Community

wellallyTech
wellallyTech

Posted on

Stop the Slouch! Build a Privacy-First AI Posture Monitor with MediaPipe and React

We’ve all been there: hunched over a laptop for eight hours, only to realize by 5 PM that our necks feel like they’ve been supporting a bowling ball at a 45-degree angle. This "Tech Neck" isn't just uncomfortable; it’s a productivity killer. As developers, we love solving problems with code, so why not build a personal AI health assistant to fix our posture? 🚀

In this tutorial, we are diving deep into real-time pose estimation, MediaPipe, and TensorFlow.js to create a sedentary correction system. By leveraging WebRTC health monitoring techniques, we can analyze neck pressure directly in the browser. Best of all? It’s 100% private. No images ever leave your device. 💻🥑

The Architecture: Privacy-First Vision logic

The core philosophy of this build is "Local-Only." We use the user's webcam via WebRTC, process the frames through a pre-trained model, and trigger alerts based on trigonometric calculations.

graph TD
    A[Webcam Feed / WebRTC] --> B[React UseRef Hook]
    B --> C[MediaPipe Pose Engine]
    C --> D{Keypoint Detection}
    D -->|Coordinates| E[Neck Angle Calculation]
    E --> F{Threshold Exceeded?}
    F -->|Yes| G[Local Browser Notification]
    F -->|No| H[Continue Monitoring]
    G --> I[Visual Feedback Overlay]
Enter fullscreen mode Exit fullscreen mode

Prerequisites

To follow along, you'll need a basic grasp of React and a desire to save your cervical spine. Our tech stack includes:

  • React: For the UI layer.
  • MediaPipe Pose: To detect body landmarks.
  • WebRTC: To access the camera stream.
  • TensorFlow.js: The backbone for browser-based AI.

Step 1: Setting up the Video Stream

First, we need to capture the camera feed. We’ll use the getUserMedia API and pipe it into a hidden video element that MediaPipe can read from.

// PostureMonitor.jsx
import React, { useRef, useEffect } from 'react';

const PostureMonitor = () => {
  const videoRef = useRef(null);
  const canvasRef = useRef(null);

  useEffect(() => {
    async function setupCamera() {
      const stream = await navigator.mediaDevices.getUserMedia({
        video: { width: 640, height: 480 },
        audio: false,
      });
      videoRef.current.srcObject = stream;
      videoRef.current.play();
    }
    setupCamera();
  }, []);

  return (
    <div className="relative">
      <video ref={videoRef} className="hidden" />
      <canvas ref={canvasRef} className="rounded-lg shadow-xl" />
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Step 2: Initializing MediaPipe Pose

MediaPipe provides a highly optimized Pose model. We’ll initialize it to track specific landmarks: the ears (to represent the head position) and the shoulders.

import { Pose } from "@mediapipe/pose";

const pose = new Pose({
  locateFile: (file) => `https://cdn.jsdelivr.net/npm/@mediapipe/pose/${file}`,
});

pose.setOptions({
  modelComplexity: 1,
  smoothLandmarks: true,
  minDetectionConfidence: 0.5,
  minTrackingConfidence: 0.5,
});
Enter fullscreen mode Exit fullscreen mode

Step 3: The Math Behind the "Tech Neck"

To detect a slouch, we calculate the angle between the Tragus (ear) and the Acromion (shoulder). When your head leans forward, this angle decreases relative to the vertical axis.

const calculateNeckAngle = (ear, shoulder) => {
  // Simple trigonometry: atan2 gives us the angle in radians
  const radians = Math.atan2(shoulder.y - ear.y, shoulder.x - ear.x);
  const angle = Math.abs(radians * 180.0 / Math.PI);
  return angle;
};

// Inside the pose estimation loop:
pose.onResults((results) => {
  if (!results.poseLandmarks) return;

  const leftEar = results.poseLandmarks[7];
  const leftShoulder = results.poseLandmarks[11];

  const angle = calculateNeckAngle(leftEar, leftShoulder);

  if (angle < 75) { // Threshold for "slouching"
    console.warn("Sit up straight! 🦴");
    triggerAlert();
  }
});
Enter fullscreen mode Exit fullscreen mode

The "Official" Way: Advanced Patterns

While this demo gets you started with browser-based vision, building production-ready health apps requires handling edge cases like lighting variations, multi-user detection, and performance optimization for mobile devices.

For a deeper dive into production-grade AI architectures and more robust computer vision implementations, I highly recommend checking out the technical breakdowns at WellAlly Tech Blog. They cover advanced patterns for integrating AI into everyday workflows that go far beyond basic tutorials.

Step 4: Visual Feedback with Canvas

Users need to see what's happening. We can draw the skeleton and the calculated angle directly onto a canvas overlay.

const drawResults = (ctx, landmarks) => {
  ctx.save();
  ctx.clearRect(0, 0, canvasRef.current.width, canvasRef.current.height);

  // Draw only the points we care about for the neck
  const points = [7, 8, 11, 12]; 
  points.forEach(index => {
    const point = landmarks[index];
    ctx.beginPath();
    ctx.arc(point.x * ctx.canvas.width, point.y * ctx.canvas.height, 5, 0, 2 * Math.PI);
    ctx.fillStyle = "#00FF00";
    ctx.fill();
  });
  ctx.restore();
};
Enter fullscreen mode Exit fullscreen mode

Conclusion

We’ve just built a real-time, privacy-friendly AI posture corrector! 🧘‍♂️ By using MediaPipe and React, we turned a standard webcam into a sophisticated health tool without ever sending a single pixel to a server.

Next Steps for You:

  1. Gamification: Add a "Posture Score" that earns points for every minute you sit straight.
  2. Audio Alerts: Use the Web Audio API to play a gentle "ding" when you slouch.
  3. Persistence: Save your daily posture trends to LocalStorage.

If you enjoyed this build, drop a comment below! How are you using Computer Vision to improve your daily life? And don't forget to visit wellally.tech/blog for more high-level AI engineering insights!

Keep coding, and stay upright! 🚀✨

Top comments (0)