Complete Guide to MediaPipe: Computer Vision Made Easy

# Panduan Lengkap MediaPipe: Computer Vision Made Easy MediaPipe adalah framework open-source dari Google untuk membangun pipeline machine learning multimodal. MediaPipe menyediakan solusi siap pakai...

By Ruby Abdullah · · tutorial
PythonMediaPipeComputer VisionMachine LearningOpenCV

Complete Guide to MediaPipe: Computer Vision Made Easy

MediaPipe is an open-source framework from Google for building multimodal machine learning pipelines. MediaPipe provides ready-to-use solutions for various computer vision tasks such as face detection, hand tracking, pose estimation, and much more.

In this tutorial, we'll learn MediaPipe from basics to practical implementation for various real-time applications.

Why MediaPipe?

MediaPipe Advantages:

  • Cross-Platform: Runs on Android, iOS, Web, Desktop (Python/C++)
  • Real-Time Performance: Optimized for real-time inference
  • Pre-trained Models: Ready-to-use models with high accuracy
  • Easy to Use: Simple and intuitive API
  • Production Ready: Used by Google products (Google Meet, etc)
  • Open Source: Free and customizable
  • Available Solutions:

    | Solution | Description |

    |----------|-------------|

    | Face Detection | Detect faces in images/video |

    | Face Mesh | 468 3D face landmarks |

    | Hand Tracking | 21 hand landmarks |

    | Pose Estimation | 33 body landmarks |

    | Holistic | Combination of face, hands, and pose |

    | Object Detection | General object detection |

    | Image Segmentation | Selfie/background segmentation |

    | Gesture Recognition | Hand gesture recognition |

    Installation

    Install MediaPipe

    # Install with pip
    

    pip install mediapipe

    Install with OpenCV (usually included)

    pip install opencv-python

    For GPU version (optional)

    pip install mediapipe-gpu

    Specific version

    pip install mediapipe==0.10.9

    Verify Installation

    import mediapipe as mp
    

    import cv2

    print(f"MediaPipe version: {mp.version}")

    print(f"OpenCV version: {cv2.version}")

    MediaPipe Structure

    import mediapipe as mp
    
    

    Solutions - Pre-built ML pipelines

    mp.solutions.facedetection

    mp.solutions.facemesh

    mp.solutions.hands

    mp.solutions.pose

    mp.solutions.holistic

    mp.solutions.objectron

    mp.solutions.selfiesegmentation

    Drawing utilities

    mp.solutions.drawingutils

    mp.solutions.drawingstyles

    Face Detection

    Basic Face Detection

    import cv2
    

    import mediapipe as mp

    Initialize

    mpfacedetection = mp.solutions.facedetection

    mpdrawing = mp.solutions.drawingutils

    def detectfacesimage(imagepath):

    """Detect faces in a static image."""

    # Read image

    image = cv2.imread(imagepath)

    imagergb = cv2.cvtColor(image, cv2.COLORBGR2RGB)

    # Initialize face detection

    with mpfacedetection.FaceDetection(

    modelselection=1, # 0: short-range (2m), 1: full-range (5m)

    mindetectionconfidence=0.5

    ) as facedetection:

    # Process image

    results = facedetection.process(imagergb)

    # Draw detections

    if results.detections:

    for detection in results.detections:

    mpdrawing.drawdetection(image, detection)

    # Get bounding box

    bbox = detection.locationdata.relativeboundingbox

    h, w, = image.shape

    x = int(bbox.xmin w)

    y = int(bbox.ymin h)

    width = int(bbox.width w)

    height = int(bbox.height h)

    # Get confidence score

    score = detection.score[0]

    print(f"Face detected: confidence={score:.2f}, bbox=({x}, {y}, {width}, {height})")

    cv2.imshow('Face Detection', image)

    cv2.waitKey(0)

    cv2.destroyAllWindows()

    Run

    detectfacesimage('photo.jpg')

    Real-Time Face Detection (Webcam)

    import cv2
    

    import mediapipe as mp

    def realtimefacedetection():

    """Real-time face detection from webcam."""

    mpfacedetection = mp.solutions.facedetection

    mpdrawing = mp.solutions.drawingutils

    # Open webcam

    cap = cv2.VideoCapture(0)

    cap.set(cv2.CAPPROPFRAMEWIDTH, 1280)

    cap.set(cv2.CAPPROPFRAMEHEIGHT, 720)

    with mpfacedetection.FaceDetection(

    modelselection=0,

    mindetectionconfidence=0.5

    ) as facedetection:

    while cap.isOpened():

    success, frame = cap.read()

    if not success:

    continue

    # Flip horizontally for selfie view

    frame = cv2.flip(frame, 1)

    # Convert BGR to RGB

    rgbframe = cv2.cvtColor(frame, cv2.COLORBGR2RGB)

    # Process frame

    results = facedetection.process(rgbframe)

    # Draw detections

    if results.detections:

    for detection in results.detections:

    mpdrawing.drawdetection(frame, detection)

    # Display confidence

    score = detection.score[0]

    cv2.putText(frame, f'{score:.2f}',

    (10, 30), cv2.FONTHERSHEYSIMPLEX,

    1, (0, 255, 0), 2)

    # Display FPS

    cv2.imshow('Face Detection', frame)

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

    break

    cap.release()

    cv2.destroyAllWindows()

    Run

    realtimefacedetection()

    Face Mesh (468 Landmarks)

    Basic Face Mesh

    import cv2
    

    import mediapipe as mp

    import numpy as np

    def facemeshdetection(imagepath):

    """Detect 468 face landmarks."""

    mpfacemesh = mp.solutions.facemesh

    mpdrawing = mp.solutions.drawingutils

    mpdrawingstyles = mp.solutions.drawingstyles

    image = cv2.imread(imagepath)

    imagergb = cv2.cvtColor(image, cv2.COLORBGR2RGB)

    with mpfacemesh.FaceMesh(

    staticimagemode=True,

    maxnumfaces=1,

    refinelandmarks=True, # Include iris landmarks

    mindetectionconfidence=0.5,

    mintrackingconfidence=0.5

    ) as facemesh:

    results = facemesh.process(imagergb)

    if results.multifacelandmarks:

    for facelandmarks in results.multifacelandmarks:

    # Draw face mesh tesselation

    mpdrawing.drawlandmarks(

    image=image,

    landmarklist=facelandmarks,

    connections=mpfacemesh.FACEMESHTESSELATION,

    landmarkdrawingspec=None,

    connectiondrawingspec=mpdrawingstyles.getdefaultfacemeshtesselationstyle()

    )

    # Draw face contours

    mpdrawing.drawlandmarks(

    image=image,

    landmarklist=facelandmarks,

    connections=mpfacemesh.FACEMESHCONTOURS,

    landmarkdrawingspec=None,

    connectiondrawingspec=mpdrawingstyles.getdefaultfacemeshcontoursstyle()

    )

    # Draw irises

    mpdrawing.drawlandmarks(

    image=image,

    landmarklist=facelandmarks,

    connections=mpfacemesh.FACEMESHIRISES,

    landmarkdrawingspec=None,

    connectiondrawingspec=mpdrawingstyles.getdefaultfacemeshirisconnectionsstyle()

    )

    cv2.imshow('Face Mesh', image)

    cv2.waitKey(0)

    cv2.destroyAllWindows()

    Extract Specific Landmarks

    import cv2
    

    import mediapipe as mp

    import numpy as np

    Important landmark indices

    FACELANDMARKS = {

    'nosetip': 1,

    'lefteyeinner': 133,

    'lefteyeouter': 33,

    'righteyeinner': 362,

    'righteyeouter': 263,

    'lefteyebrowinner': 107,

    'righteyebrowinner': 336,

    'upperlip': 13,

    'lowerlip': 14,

    'chin': 152,

    'leftcheek': 234,

    'rightcheek': 454,

    }

    def extractlandmarks(imagepath):

    """Extract specific face landmarks."""

    mpfacemesh = mp.solutions.facemesh

    image = cv2.imread(imagepath)

    h, w, = image.shape

    imagergb = cv2.cvtColor(image, cv2.COLORBGR2RGB)

    with mpfacemesh.FaceMesh(

    staticimagemode=True,

    maxnumfaces=1,

    mindetectionconfidence=0.5

    ) as facemesh:

    results = facemesh.process(imagergb)

    if results.multifacelandmarks:

    facelandmarks = results.multifacelandmarks[0]

    # Extract and draw specific landmarks

    for name, idx in FACELANDMARKS.items():

    landmark = facelandmarks.landmark[idx]

    x = int(landmark.x w)

    y = int(landmark.y h)

    z = landmark.z # Depth

    # Draw point

    cv2.circle(image, (x, y), 3, (0, 255, 0), -1)

    cv2.putText(image, name, (x + 5, y - 5),

    cv2.FONTHERSHEYSIMPLEX, 0.3, (255, 255, 255), 1)

    print(f"{name}: ({x}, {y}, {z:.4f})")

    cv2.imshow('Landmarks', image)

    cv2.waitKey(0)

    cv2.destroyAllWindows()

    import cv2
    

    import mediapipe as mp

    import numpy as np

    from scipy.spatial import distance

    def eyeaspectratio(eyelandmarks):

    """Calculate Eye Aspect Ratio (EAR)."""

    # Vertical distances

    v1 = distance.euclidean(eyelandmarks[1], eyelandmarks[5])

    v2 = distance.euclidean(eyelandmarks[2], eyelandmarks[4])

    # Horizontal distance

    h = distance.euclidean(eyelandmarks[0], eyelandmarks[3])

    ear = (v1 + v2) / (2.0 h)

    return ear

    Eye landmark indices for MediaPipe Face Mesh

    LEFTEYE = [33, 160, 158, 133, 153, 144]

    RIGHTEYE = [362, 385, 387, 263, 373, 380]

    def blinkdetection():

    """Real-time blink detection."""

    mpfacemesh = mp.solutions.facemesh

    cap = cv2.VideoCapture(0)

    blinkcounter = 0

    EARTHRESHOLD = 0.25

    with mpfacemesh.FaceMesh(

    maxnumfaces=1,

    refinelandmarks=True,

    mindetectionconfidence=0.5,

    mintrackingconfidence=0.5

    ) as facemesh:

    while cap.isOpened():

    success, frame = cap.read()

    if not success:

    continue

    frame = cv2.flip(frame, 1)

    h, w, = frame.shape

    rgbframe = cv2.cvtColor(frame, cv2.COLORBGR2RGB)

    results = facemesh.process(rgbframe)

    if results.multifacelandmarks:

    landmarks = results.multifacelandmarks[0].landmark

    # Get eye coordinates

    lefteye = [(int(landmarks[i].x w), int(landmarks[i].y h)) for i in LEFTEYE]

    righteye = [(int(landmarks[i].x w), int(landmarks[i].y h)) for i in RIGHTEYE]

    # Calculate EAR

    leftear = eyeaspectratio(lefteye)

    rightear = eyeaspectratio(righteye)

    avgear = (leftear + rightear) / 2.0

    # Detect blink

    if avgear < EARTHRESHOLD:

    blinkcounter += 1

    cv2.putText(frame, "BLINK!", (50, 100),

    cv2.FONTHERSHEYSIMPLEX, 1.5, (0, 0, 255), 3)

    # Draw eyes

    cv2.polylines(frame, [np.array(lefteye)], True, (0, 255, 0), 1)

    cv2.polylines(frame, [np.array(righteye)], True, (0, 255, 0), 1)

    # Display info

    cv2.putText(frame, f"EAR: {avgear:.2f}", (10, 30),

    cv2.FONTHERSHEYSIMPLEX, 0.7, (255, 255, 255), 2)

    cv2.putText(frame, f"Blinks: {blinkcounter}", (10, 60),

    cv2.FONTHERSHEYSIMPLEX, 0.7, (255, 255, 255), 2)

    cv2.imshow('Blink Detection', frame)

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

    break

    cap.release()

    cv2.destroyAllWindows()

    Hand Tracking (21 Landmarks)

    Basic Hand Detection

    import cv2
    

    import mediapipe as mp

    def handtrackingimage(imagepath):

    """Detect hands in static image."""

    mphands = mp.solutions.hands

    mpdrawing = mp.solutions.drawingutils

    mpdrawingstyles = mp.solutions.drawingstyles

    image = cv2.imread(imagepath)

    imagergb = cv2.cvtColor(image, cv2.COLORBGR2RGB)

    with mphands.Hands(

    staticimagemode=True,

    maxnumhands=2,

    mindetectionconfidence=0.5,

    mintrackingconfidence=0.5

    ) as hands:

    results = hands.process(imagergb)

    if results.multihandlandmarks:

    for idx, handlandmarks in enumerate(results.multihandlandmarks):

    # Get handedness (left/right)

    handedness = results.multihandedness[idx].classification[0].label

    print(f"Hand {idx + 1}: {handedness}")

    # Draw landmarks

    mpdrawing.drawlandmarks(

    image,

    handlandmarks,

    mphands.HANDCONNECTIONS,

    mpdrawingstyles.getdefaulthandlandmarksstyle(),

    mpdrawingstyles.getdefaulthandconnectionsstyle()

    )

    # Print landmark coordinates

    for id, lm in enumerate(handlandmarks.landmark):

    h, w, = image.shape

    cx, cy = int(lm.x w), int(lm.y h)

    print(f" Landmark {id}: ({cx}, {cy})")

    cv2.imshow('Hand Tracking', image)

    cv2.waitKey(0)

    cv2.destroyAllWindows()

    Real-Time Hand Tracking

    import cv2
    

    import mediapipe as mp

    def realtimehandtracking():

    """Real-time hand tracking from webcam."""

    mphands = mp.solutions.hands

    mpdrawing = mp.solutions.drawingutils

    mpdrawingstyles = mp.solutions.drawingstyles

    cap = cv2.VideoCapture(0)

    with mphands.Hands(

    modelcomplexity=0, # 0: Lite, 1: Full

    maxnumhands=2,

    mindetectionconfidence=0.5,

    mintrackingconfidence=0.5

    ) as hands:

    while cap.isOpened():

    success, frame = cap.read()

    if not success:

    continue

    frame = cv2.flip(frame, 1)

    rgbframe = cv2.cvtColor(frame, cv2.COLORBGR2RGB)

    results = hands.process(rgbframe)

    if results.multihandlandmarks:

    for idx, handlandmarks in enumerate(results.multihandlandmarks):

    handedness = results.multihandedness[idx].classification[0].label

    # Draw landmarks

    mpdrawing.drawlandmarks(

    frame,

    handlandmarks,

    mphands.HANDCONNECTIONS,

    mpdrawingstyles.getdefaulthandlandmarksstyle(),

    mpdrawingstyles.getdefaulthandconnectionsstyle()

    )

    # Display handedness

    cv2.putText(frame, handedness, (10, 30 + idx 30),

    cv2.FONTHERSHEYSIMPLEX, 1, (0, 255, 0), 2)

    cv2.imshow('Hand Tracking', frame)

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

    break

    cap.release()

    cv2.destroyAllWindows()

    Finger Counter

    import cv2
    

    import mediapipe as mp

    Landmark indices for fingertips and joints

    FINGERTIPS = [4, 8, 12, 16, 20] # Thumb, Index, Middle, Ring, Pinky

    FINGERPIPS = [3, 6, 10, 14, 18] # PIP joints

    def countfingers(handlandmarks, handedness):

    """Count raised fingers."""

    fingers = []

    # Thumb - special case (horizontal movement)

    if handedness == "Right":

    if handlandmarks.landmark[4].x < handlandmarks.landmark[3].x:

    fingers.append(1)

    else:

    fingers.append(0)

    else: # Left hand

    if handlandmarks.landmark[4].x > handlandmarks.landmark[3].x:

    fingers.append(1)

    else:

    fingers.append(0)

    # Other fingers - check if tip is above PIP joint

    for tip, pip in zip(FINGERTIPS[1:], FINGERPIPS[1:]):

    if handlandmarks.landmark[tip].y < handlandmarks.landmark[pip].y:

    fingers.append(1)

    else:

    fingers.append(0)

    return sum(fingers)

    def fingercounter():

    """Real-time finger counting."""

    mphands = mp.solutions.hands

    mpdrawing = mp.solutions.drawingutils

    cap = cv2.VideoCapture(0)

    with mphands.Hands(

    maxnumhands=2,

    mindetectionconfidence=0.7,

    mintrackingconfidence=0.5

    ) as hands:

    while cap.isOpened():

    success, frame = cap.read()

    if not success:

    continue

    frame = cv2.flip(frame, 1)

    h, w, = frame.shape

    rgbframe = cv2.cvtColor(frame, cv2.COLORBGR2RGB)

    results = hands.process(rgbframe)

    totalfingers = 0

    if results.multihandlandmarks:

    for idx, handlandmarks in enumerate(results.multihandlandmarks):

    handedness = results.multihandedness[idx].classification[0].label

    # Count fingers

    fingercount = countfingers(handlandmarks, handedness)

    totalfingers += fingercount

    # Draw landmarks

    mpdrawing.drawlandmarks(

    frame, handlandmarks, mphands.HANDCONNECTIONS

    )

    # Get wrist position for text

    wrist = handlandmarks.landmark[0]

    wx, wy = int(wrist.x w), int(wrist.y h)

    cv2.putText(frame, f"{handedness}: {fingercount}",

    (wx - 50, wy - 20),

    cv2.FONTHERSHEYSIMPLEX, 0.8, (255, 0, 255), 2)

    # Display total

    cv2.rectangle(frame, (0, 0), (200, 80), (0, 0, 0), -1)

    cv2.putText(frame, f"Total: {totalfingers}", (10, 50),

    cv2.FONTHERSHEYSIMPLEX, 1.5, (0, 255, 0), 3)

    cv2.imshow('Finger Counter', frame)

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

    break

    cap.release()

    cv2.destroyAllWindows()

    Gesture Recognition

    import cv2
    

    import mediapipe as mp

    import numpy as np

    def recognizegesture(handlandmarks, handedness):

    """Recognize common hand gestures."""

    # Get finger states

    fingers = []

    # Thumb

    if handedness == "Right":

    fingers.append(handlandmarks.landmark[4].x < handlandmarks.landmark[3].x)

    else:

    fingers.append(handlandmarks.landmark[4].x > handlandmarks.landmark[3].x)

    # Other fingers

    for tip, pip in zip([8, 12, 16, 20], [6, 10, 14, 18]):

    fingers.append(handlandmarks.landmark[tip].y < handlandmarks.landmark[pip].y)

    # Gesture recognition

    if fingers == [False, False, False, False, False]:

    return "FIST"

    elif fingers == [True, True, True, True, True]:

    return "OPEN HAND"

    elif fingers == [False, True, False, False, False]:

    return "POINTING"

    elif fingers == [False, True, True, False, False]:

    return "PEACE"

    elif fingers == [True, False, False, False, True]:

    return "ROCK"

    elif fingers == [True, True, False, False, False]:

    return "GUN"

    elif fingers == [True, False, False, False, False]:

    return "THUMBS UP"

    elif fingers == [False, True, True, True, True]:

    return "FOUR"

    else:

    return "UNKNOWN"

    def gesturerecognition():

    """Real-time gesture recognition."""

    mphands = mp.solutions.hands

    mpdrawing = mp.solutions.drawingutils

    cap = cv2.VideoCapture(0)

    with mphands.Hands(

    maxnumhands=1,

    mindetectionconfidence=0.7,

    mintrackingconfidence=0.5

    ) as hands:

    while cap.isOpened():

    success, frame = cap.read()

    if not success:

    continue

    frame = cv2.flip(frame, 1)

    rgbframe = cv2.cvtColor(frame, cv2.COLORBGR2RGB)

    results = hands.process(rgbframe)

    if results.multihandlandmarks:

    for idx, handlandmarks in enumerate(results.multihandlandmarks):

    handedness = results.multihandedness[idx].classification[0].label

    # Recognize gesture

    gesture = recognizegesture(handlandmarks, handedness)

    # Draw

    mpdrawing.drawlandmarks(frame, handlandmarks, mphands.HANDCONNECTIONS)

    # Display gesture

    cv2.rectangle(frame, (0, 0), (300, 60), (0, 0, 0), -1)

    cv2.putText(frame, gesture, (10, 45),

    cv2.FONTHERSHEYSIMPLEX, 1.5, (0, 255, 0), 3)

    cv2.imshow('Gesture Recognition', frame)

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

    break

    cap.release()

    cv2.destroyAllWindows()

    Pose Estimation (33 Landmarks)

    Basic Pose Detection

    import cv2
    

    import mediapipe as mp

    def posedetectionimage(imagepath):

    """Detect body pose in image."""

    mppose = mp.solutions.pose

    mpdrawing = mp.solutions.drawingutils

    mpdrawingstyles = mp.solutions.drawingstyles

    image = cv2.imread(imagepath)

    imagergb = cv2.cvtColor(image, cv2.COLORBGR2RGB)

    with mppose.Pose(

    staticimagemode=True,

    modelcomplexity=2, # 0: Lite, 1: Full, 2: Heavy

    enablesegmentation=True,

    mindetectionconfidence=0.5

    ) as pose:

    results = pose.process(imagergb)

    if results.poselandmarks:

    # Draw pose landmarks

    mpdrawing.drawlandmarks(

    image,

    results.poselandmarks,

    mppose.POSECONNECTIONS,

    landmarkdrawingspec=mpdrawingstyles.getdefaultposelandmarksstyle()

    )

    # Print key landmarks

    landmarks = results.poselandmarks.landmark

    h, w, = image.shape

    keypoints = {

    'nose': 0,

    'leftshoulder': 11,

    'rightshoulder': 12,

    'leftelbow': 13,

    'rightelbow': 14,

    'leftwrist': 15,

    'rightwrist': 16,

    'lefthip': 23,

    'righthip': 24,

    'leftknee': 25,

    'rightknee': 26,

    'leftankle': 27,

    'rightankle': 28

    }

    for name, idx in keypoints.items():

    lm = landmarks[idx]

    cx, cy = int(lm.x w), int(lm.y h)

    visibility = lm.visibility

    print(f"{name}: ({cx}, {cy}), visibility: {visibility:.2f}")

    cv2.imshow('Pose Detection', image)

    cv2.waitKey(0)

    cv2.destroyAllWindows()

    Real-Time Pose Tracking

    import cv2
    

    import mediapipe as mp

    def realtimeposetracking():

    """Real-time pose tracking from webcam."""

    mppose = mp.solutions.pose

    mpdrawing = mp.solutions.drawingutils

    mpdrawingstyles = mp.solutions.drawingstyles

    cap = cv2.VideoCapture(0)

    with mppose.Pose(

    mindetectionconfidence=0.5,

    mintrackingconfidence=0.5,

    modelcomplexity=1

    ) as pose:

    while cap.isOpened():

    success, frame = cap.read()

    if not success:

    continue

    frame = cv2.flip(frame, 1)

    rgbframe = cv2.cvtColor(frame, cv2.COLORBGR2RGB)

    results = pose.process(rgbframe)

    if results.poselandmarks:

    mpdrawing.drawlandmarks(

    frame,

    results.poselandmarks,

    mppose.POSECONNECTIONS,

    landmarkdrawingspec=mpdrawingstyles.getdefaultposelandmarksstyle()

    )

    cv2.imshow('Pose Tracking', frame)

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

    break

    cap.release()

    cv2.destroyAllWindows()

    Exercise Counter (Push-up/Squat Counter)

    import cv2
    

    import mediapipe as mp

    import numpy as np

    def calculateangle(a, b, c):

    """Calculate angle between three points."""

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

    """Count squats using pose estimation."""

    mppose = mp.solutions.pose

    mpdrawing = mp.solutions.drawingutils

    cap = cv2.VideoCapture(0)

    counter = 0

    stage = None # 'up' or 'down'

    with mppose.Pose(

    mindetectionconfidence=0.5,

    mintrackingconfidence=0.5

    ) as pose:

    while cap.isOpened():

    success, frame = cap.read()

    if not success:

    continue

    frame = cv2.flip(frame, 1)

    h, w, = frame.shape

    rgbframe = cv2.cvtColor(frame, cv2.COLORBGR2RGB)

    results = pose.process(rgbframe)

    if results.poselandmarks:

    landmarks = results.poselandmarks.landmark

    # Get coordinates

    hip = [landmarks[mppose.PoseLandmark.LEFTHIP.value].x,

    landmarks[mppose.PoseLandmark.LEFTHIP.value].y]

    knee = [landmarks[mppose.PoseLandmark.LEFTKNEE.value].x,

    landmarks[mppose.PoseLandmark.LEFTKNEE.value].y]

    ankle = [landmarks[mppose.PoseLandmark.LEFTANKLE.value].x,

    landmarks[mppose.PoseLandmark.LEFTANKLE.value].y]

    # Calculate knee angle

    angle = calculateangle(hip, knee, ankle)

    # Visualize angle

    cv2.putText(frame, f"Angle: {int(angle)}",

    (int(knee[0] w) + 20, int(knee[1] h)),

    cv2.FONTHERSHEYSIMPLEX, 0.7, (255, 255, 255), 2)

    # Squat logic

    if angle > 160:

    stage = "up"

    if angle < 90 and stage == "up":

    stage = "down"

    counter += 1

    # Draw pose

    mpdrawing.drawlandmarks(

    frame, results.poselandmarks, mppose.POSECONNECTIONS

    )

    # Display counter

    cv2.rectangle(frame, (0, 0), (250, 100), (0, 0, 0), -1)

    cv2.putText(frame, "SQUATS", (10, 30),

    cv2.FONTHERSHEYSIMPLEX, 0.8, (255, 255, 255), 2)

    cv2.putText(frame, str(counter), (10, 80),

    cv2.FONTHERSHEYSIMPLEX, 2, (0, 255, 0), 3)

    cv2.putText(frame, stage if stage else "", (150, 80),

    cv2.FONTHERSHEYSIMPLEX, 1, (255, 255, 0), 2)

    cv2.imshow('Squat Counter', frame)

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

    break

    cap.release()

    cv2.destroyAllWindows()

    Holistic (Face + Hands + Pose)

    Complete Holistic Tracking

    import cv2
    

    import mediapipe as mp

    def holistictracking():

    """Track face, hands, and pose simultaneously."""

    mpholistic = mp.solutions.holistic

    mpdrawing = mp.solutions.drawingutils

    mpdrawingstyles = mp.solutions.drawingstyles

    cap = cv2.VideoCapture(0)

    with mpholistic.Holistic(

    mindetectionconfidence=0.5,

    mintrackingconfidence=0.5,

    modelcomplexity=1,

    refinefacelandmarks=True

    ) as holistic:

    while cap.isOpened():

    success, frame = cap.read()

    if not success:

    continue

    frame = cv2.flip(frame, 1)

    rgbframe = cv2.cvtColor(frame, cv2.COLORBGR2RGB)

    results = holistic.process(rgbframe)

    # Draw face mesh

    if results.facelandmarks:

    mpdrawing.drawlandmarks(

    frame,

    results.facelandmarks,

    mpholistic.FACEMESHCONTOURS,

    landmarkdrawingspec=None,

    connectiondrawingspec=mpdrawingstyles.getdefaultfacemeshcontoursstyle()

    )

    # Draw pose

    if results.poselandmarks:

    mpdrawing.drawlandmarks(

    frame,

    results.poselandmarks,

    mpholistic.POSECONNECTIONS,

    landmarkdrawingspec=mpdrawingstyles.getdefaultposelandmarksstyle()

    )

    # Draw left hand

    if results.lefthandlandmarks:

    mpdrawing.drawlandmarks(

    frame,

    results.lefthandlandmarks,

    mpholistic.HANDCONNECTIONS,

    mpdrawingstyles.getdefaulthandlandmarksstyle(),

    mpdrawingstyles.getdefaulthandconnectionsstyle()

    )

    # Draw right hand

    if results.righthandlandmarks:

    mpdrawing.drawlandmarks(

    frame,

    results.righthandlandmarks,

    mpholistic.HANDCONNECTIONS,

    mpdrawingstyles.getdefaulthandlandmarksstyle(),

    mpdrawingstyles.getdefaulthandconnectionsstyle()

    )

    cv2.imshow('Holistic Tracking', frame)

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

    break

    cap.release()

    cv2.destroyAllWindows()

    Selfie Segmentation

    Background Removal/Replacement

    import cv2
    

    import mediapipe as mp

    import numpy as np

    def selfiesegmentation():

    """Real-time background removal/replacement."""

    mpselfiesegmentation = mp.solutions.selfiesegmentation

    cap = cv2.VideoCapture(0)

    # Load background image (optional)

    bgimage = cv2.imread('background.jpg')

    with mpselfiesegmentation.SelfieSegmentation(

    modelselection=1 # 0: General, 1: Landscape

    ) as selfieseg:

    while cap.isOpened():

    success, frame = cap.read()

    if not success:

    continue

    frame = cv2.flip(frame, 1)

    h, w, = frame.shape

    rgbframe = cv2.cvtColor(frame, cv2.COLORBGR2RGB)

    results = selfieseg.process(rgbframe)

    # Get segmentation mask

    mask = results.segmentationmask

    condition = mask > 0.5

    # Option 1: Blur background

    blurred = cv2.GaussianBlur(frame, (55, 55), 0)

    output = np.where(condition[:, :, np.newaxis], frame, blurred)

    # Option 2: Replace background with image

    # if bgimage is not None:

    # bgresized = cv2.resize(bgimage, (w, h))

    # output = np.where(condition[:, :, np.newaxis], frame, bgresized)

    # Option 3: Replace background with solid color

    # bgcolor = np.zeros(frame.shape, dtype=np.uint8)

    # bgcolor[:] = (0, 255, 0) # Green screen

    Related Articles

    OpenCV + Deep Learning Tutorial: Modern Image Processing with Python

    OpenCV + Deep Learning: Tutorial Komprehensif Daftar Isi Pendahuluan Prasyarat Dasar-Dasar Preprocessing Gambar [T...

    Complete Comet ML Tutorial: MLOps Platform for Experiment Tracking and Model Management

    Tutorial Lengkap Comet ML: Platform MLOps untuk Experiment Tracking dan Model Management Dalam dunia machine learning mo...

    Surya OCR Tutorial: Document AI for Text Detection, OCR, and Layout Analysis

    Tutorial Surya OCR: Document AI untuk Text Detection, OCR, dan Layout Analysis Surya adalah library Document AI open-sou...

    MLX Tutorial: Apple's Machine Learning Framework for Apple Silicon

    Tutorial MLX: Framework Machine Learning Apple untuk Apple Silicon MLX adalah framework machine learning open-source dar...