使用 OpenCV 和 Mediapipe 库实现手指计数

1. 引言

手指计数是一种常见的计算机视觉任务,广泛应用于人机交互、手势识别等领域。本教程介绍如何使用 OpenCV 和 Mediapipe 库实现手指计数,并提供详细的代码示例。

2. 环境准备

2.1 安装依赖库

在开始之前,我们需要安装 OpenCV 和 Mediapipe。这两个库可以通过 pip 轻松安装。

pip install opencv-python mediapipe numpy

2.2 导入库

import cv2
import mediapipe as mp
import numpy as np

3. Mediapipe Hands 模型介绍

Mediapipe 提供了一个高效的手部检测和关键点识别模型,能够检测 21 个手部关键点。

mp_hands = mp.solutions.hands
mp_draw = mp.solutions.drawing_utils
hands = mp_hands.Hands(static_image_mode=False, max_num_hands=2, min_detection_confidence=0.5)

4. 处理摄像头输入

我们使用 OpenCV 读取摄像头视频流,并将其传递给 Mediapipe 进行处理。

cap = cv2.VideoCapture(0)

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    # 反转图像,使其符合人眼视觉习惯
    frame = cv2.flip(frame, 1)
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    
    results = hands.process(rgb_frame)
    
    if results.multi_hand_landmarks:
        for hand_landmarks in results.multi_hand_landmarks:
            mp_draw.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
    
    cv2.imshow('Hand Tracking', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

5. 识别手指数量

手指计数的核心思路是判断手指是否伸直,我们可以使用关键点的 Y 坐标进行判断。

def count_fingers(hand_landmarks):
    finger_tips = [8, 12, 16, 20]  # 食指、中指、无名指、小指的指尖索引
    thumb_tip = 4  # 拇指指尖索引
    
    finger_count = 0
    for tip in finger_tips:
        if hand_landmarks.landmark[tip].y < hand_landmarks.landmark[tip - 2].y:
            finger_count += 1
    
    # 处理拇指,判断是否张开
    if hand_landmarks.landmark[thumb_tip].x > hand_landmarks.landmark[3].x:
        finger_count += 1
    
    return finger_count

6. 显示手指计数结果

我们在摄像头画面上显示手指数量。

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    frame = cv2.flip(frame, 1)
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = hands.process(rgb_frame)
    
    if results.multi_hand_landmarks:
        for hand_landmarks in results.multi_hand_landmarks:
            mp_draw.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
            fingers = count_fingers(hand_landmarks)
            cv2.putText(frame, f'Fingers: {fingers}', (50, 50),
                        cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)
    
    cv2.imshow('Hand Tracking', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

7. 进一步优化

7.1 处理多个手的情况

如果希望同时检测多只手,可以遍历 results.multi_hand_landmarks 并分别处理每只手。

7.2 提高准确性

  • 增加 min_detection_confidence
  • 结合历史数据平滑输出

7.3 添加手势识别

可以扩展手指数量识别,实现“点赞”或“OK”手势识别。

8. 总结

本教程介绍了如何使用 OpenCV 和 Mediapipe 实现手指计数。通过 Mediapipe 提供的手部关键点,我们可以高效识别手指数量,并可扩展到更复杂的手势识别任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是一个对称矩阵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值