使用MediaPipe和OpenCV的Python实现手势识别

手势识别

手势识别技术是一种非常有用的技术,它可以将人类的手势转化为计算机可以理解的形式,从而实现更加自然、快速和直观的交互方式。本文将介绍一种基于MediaPipe和OpenCV的手势识别技术,可以实现对手势的实时识别和分析。

MediaPipe

MediaPipe是一种开源的机器学习框架,可以用于构建计算机视觉和机器学习应用,并且提供了很多预训练的模型和工具。在本文中,我们将使用MediaPipe中的Hands模型,它可以实现对手部的实时跟踪和关键点检测。OpenCV是一个开源的计算机视觉库,可以用于图像处理和分析。

在本文中,我们将使用MediaPipe和OpenCV来实现手势识别技术,并且将其应用于实际场景中。

首先,我们需要引入MediaPipe和OpenCV的库,并且创建一个Hands模型的实例:

import cv2
import mediapipe as mp

mpHands = mp.solutions.hands
hands = mpHands.Hands(static_image_mode=False,
                      max_num_hands=2,
                      min_detection_confidence=0.5,
                      min_tracking_confidence=0.5)
mpDraw = mp.solutions.drawing_utils

然后,我们需要打开摄像头,并且开始对图像进行处理:

cap = cv2.VideoCapture(0)
while True:
    ok, img = cap.read()
    if ok:
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        results = hands.process(imgRGB)
        # print(results.multi_hand_landmarks)
        # ...

在循环中,我们首先从摄像头中读取一帧图像,并且将其转换为RGB格式。然后,我们将图像传递给Hands模型进行处理,并且得到处理结果。接下来,我们将对处理结果进行分析,并且将结果可视化。

在Hands模型中,每个检测到的手部都会被表示为一个HandLandmark对象,其中包含了21个关键点的位置信息。我们可以通过遍历HandLandmark对象中的关键点,并且在图像中绘制出关键点的位置,来实现对手部的跟踪和分析。例如,我们可以使用下面的代码来绘制出每个关键点的位置:

for handLms in results.multi_hand_landmarks:
    for id, lm in enumerate(handLms.landmark):
        h, w, c = img.shape
        cx, cy = int(lm.x * w), int(lm.y * h)
        cv2.circle(img, (cx, cy), int(w / 50), (200, 0, 200), cv2.FILLED)

在这段代码中,我们遍历了所有检测到的手部,然后遍历每个关键点,并且计算出其在图像中的位置。最后,我们使用cv2.circle函数在图像中绘制一个圆圈表示该关键点的位置。

除了手部的跟踪和分析之外,我们还可以使用Hands模型来实现手势识别。例如,我们可以根据手指的弯曲程度来判断手势类型。在本文的代码中,我们使用了一个简单的算法来实现手指的弯曲程度的判断,具体实现如下:

finger_count = 0
for id in [4, 8, 12, 16, 20]:
    if handLms.landmark[id].y < handLms.landmark[id - 2].y:
        finger_count += 1

在这段代码中,我们遍历了五个手指的关键点,并且通过比较当前关键点的位置和前一个关键点的位置,来判断手指是否弯曲。如果当前关键点的位置比前一个关键点的位置低,那么就说明手指弯曲了。最后,我们统计了弯曲的手指数量,并且根据手指数量来判断手势类型。

最后,我们可以将手势类型输出到屏幕上,并且实现对手势的实时识别和分析。例如,我们可以使用下面的代码将手势类型输出到屏幕上:

gesture_dict = {
    
    
    1: "Fist",
    2: "One",
    3: "Two",
    4: "Three",
    5: "Four",
    6: "Five"
}
prev_fingers = [0, 0, 0, 0, 0]
for handLms in results.multi_hand_landmarks:
    finger_count = 0
    for id in [4, 8, 12, 16, 20]:
        if handLms.landmark[id].y < handLms.landmark[id - 2].y:
            finger_count += 1
            cv2.circle(img, (cx, cy), int(w / 50), (0, 255, 0), cv2.FILLED)
    prev_fingers.pop(0)
    prev_fingers.append(finger_count)
    if prev_fingers == [0, 5, 5, 5, 5]:
        gesture_type = 6
    elif prev_fingers[1:] == [1, 1, 1, 1]:
        gesture_type = 2
    elif prev_fingers[1:] == [2, 2, 2, 2]:
        gesture_type = 3
    elif prev_fingers[1:] == [3, 3, 3, 3]:
        gesture_type = 4
    elif prev_fingers[1:] == [4, 4, 4, 4]:
        gesture_type = 5
    else:
        gesture_type = 1
    cv2.putText(img, gesture_dict[gesture_type], (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

在这段代码中,我们定义了一个手势类型的字典,其中包含了六种手势类型。然后,我们使用一个列表来记录前四帧中每个手指弯曲的情况,并且根据弯曲的手指数量来判断当前手势类型。最后,我们将手势类型输出到屏幕上,并且用不同的颜色和大小来表示每个关键点的位置和手指的弯曲情况。

总结

本文介绍了一种基于MediaPipe和OpenCV的手势识别技术,可以实现对手势的实时识别和分析。该技术具有很高的实用价值,可以应用于很多领域,例如智能家居、游戏控制、人机交互等。未来,随着计算机视觉和人工智能技术的不断发展,手势识别技术将会变得更加先进和智能,为人们的生活和工作带来更多便利和创新。

猜你喜欢

转载自blog.csdn.net/qq_46556714/article/details/130952761