当前位置: 首页 > article >正文

【python】OpenCV—Hand Landmarks Detection

在这里插入图片描述

文章目录

  • 1、功能描述
  • 2、代码实现
  • 3、效果展示
  • 4、完整代码
  • 5、涉及到的库函数
  • 6、参考


更多有趣的代码示例,可参考【Programming】


1、功能描述

基于 opencv-python 和 mediapipe 实现手部关键点的检测(无法检测出手,不过可以根据关键点的信息外扩出来)

在这里插入图片描述

拇指(Thumb):位于手掌的最外侧,通常是最粗、最短的手指,具有对掌功能,使人类能够抓握和操作物体。

食指(Index Finger):又称示指,紧挨着拇指,通常用于指示方向或物体,也是打字和书写时常用的手指。

中指(Middle Finger):位于食指和无名指之间,是手指中最长的一根,有时也被用于表达某些情绪或态度。

无名指(Ring Finger):又称环指,在传统文化中,人们习惯将戒指戴在这根手指上,象征着婚姻或爱情。

小指(Little Finger):又称小拇指,是手指中最细、最短的一根,通常用于支撑或稳定物体。

Pinky 是小指的俗称,尤其在非正式场合或口语中常用。


Landmark 0 (Wrist): The base of the palm (root landmark).
Landmark 1 (Thumb base): The base joint of the thumb, near the wrist.
Landmark 2 (Thumb first joint): The first joint of the thumb.
Landmark 3 (Thumb second joint): The second joint of the thumb.
Landmark 4 (Thumb tip): The tip of the thumb.
Landmark 5 (Index base): The base joint of the index finger.
Landmark 6 (Index first joint): The first joint of the index finger.
Landmark 7 (Index second joint): The second joint of the index finger.
Landmark 8 (Index tip): The tip of the index finger.
Landmark 9 (Middle base): The base joint of the middle finger.
Landmark 10 (Middle first joint): The first joint of the middle finger.
Landmark 11 (Middle second joint): The second joint of the middle finger.
Landmark 12 (Middle tip): The tip of the middle finger.
Landmark 13 (Ring base): The base joint of the ring finger.
Landmark 14 (Ring first joint): The first joint of the ring finger.
Landmark 15 (Ring second joint): The second joint of the ring finger.
Landmark 16 (Ring tip): The tip of the ring finger.
Landmark 17 (Pinky base): The base joint of the pinky finger.
Landmark 18 (Pinky first joint): The first joint of the pinky.
Landmark 19 (Pinky second joint): The second joint of the pinky.
Landmark 20 (Pinky tip): The tip of the pinky finger.

2、代码实现

导入必要的库函数

import cv2
import mediapipe as mp
import time

调用 mediapipe 的手部关键点检测和绘制手部关键点的接口

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

统计时间和帧率,单张图片的话用处不大

pTime = 0
cTime = 0

读取图片,检测手部关键点,结果保存在 results 中,可以通过 help(results) 查看其属性

img = cv2.imread("1.jpg")
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
results = hands.process(imgRGB)

检测结果的三个属性的 help 介绍如下

 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |
 |  multi_hand_landmarks = [landmark {
 |    x: 0.692896
 |    y: 0.489765495
 |    z:...
 |
 |  multi_hand_world_landmarks = [landmark {
 |    x: 0.000626816414
 |    y: 0.08...
 |
 |  multi_handedness = [classification {
 |    index: 1
 |    score: 0.889409304
 |   ...

如果存在检测结果,遍历关键点,可视化出来

if results.multi_hand_landmarks:
    for handLms in results.multi_hand_landmarks:
        for id, lm in enumerate(handLms.landmark):
            #print(id,lm)
            h, w, c = img.shape
            cx, cy = int(lm.x *w), int(lm.y*h)
            #if id ==0:
            cv2.circle(img, (cx,cy), 3, (255,0,255), cv2.FILLED)

        mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)

统计时间,帧率显示在左上角

cTime = time.time()
fps = 1/(cTime-pTime)
pTime = cTime

cv2.putText(img,str(int(fps)), (10,70), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,255), 3)

显示图片,保存结果,退出时候关闭所有窗口

cv2.imshow("Image", img)
cv2.imwrite("result.jpg", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

3、效果展示

输入图片

在这里插入图片描述

输出结果

在这里插入图片描述

输入图片

在这里插入图片描述

输出结果

在这里插入图片描述
输入图片

在这里插入图片描述

输出图片

在这里插入图片描述

输入图片

在这里插入图片描述

输出图片

在这里插入图片描述

4、完整代码

单张图片

import cv2
import mediapipe as mp
import time

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

pTime = 0
cTime = 0


img = cv2.imread("1.jpg")
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
results = hands.process(imgRGB)
#print(results.multi_hand_landmarks)

if results.multi_hand_landmarks:
    for handLms in results.multi_hand_landmarks:
        for id, lm in enumerate(handLms.landmark):
            #print(id,lm)
            h, w, c = img.shape
            cx, cy = int(lm.x *w), int(lm.y*h)
            #if id ==0:
            cv2.circle(img, (cx,cy), 3, (255,0,255), cv2.FILLED)

        mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)


cTime = time.time()
fps = 1/(cTime-pTime)
pTime = cTime

cv2.putText(img,str(int(fps)), (10,70), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,255), 3)

cv2.imshow("Image", img)
cv2.imwrite("result.jpg", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

视频

import cv2
import mediapipe as mp
import time

cap = cv2.VideoCapture(0)

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

pTime = 0
cTime = 0

while True:
    success, img = cap.read()
    img = cv2.flip(img, 1)
    imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    results = hands.process(imgRGB)
    #print(results.multi_hand_landmarks)

    if results.multi_hand_landmarks:
        for handLms in results.multi_hand_landmarks:
            for id, lm in enumerate(handLms.landmark):
                #print(id,lm)
                h, w, c = img.shape
                cx, cy = int(lm.x *w), int(lm.y*h)
                #if id ==0:
                cv2.circle(img, (cx,cy), 3, (255,0,255), cv2.FILLED)

            mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)


    cTime = time.time()
    fps = 1/(cTime-pTime)
    pTime = cTime

    cv2.putText(img,str(int(fps)), (10,70), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,255), 3)

    cv2.imshow("Image", img)
    cv2.waitKey(1)

5、涉及到的库函数

mediapipe.solutions.hands.Hands 是 MediaPipe 框架中用于手部关键点检测的重要接口。

关键参数

static_image_mode:

  • 默认为 False,表示将输入图像视为视频流。在此模式下,接口会尝试在第一个输入图像中检测手,并在成功检测后进一步定位手的坐标。在随后的图像中,它会跟踪这些坐标,直到失去对任何一只手的跟踪。
  • 设置为 True 时,接口会在每个输入图像上运行手部检测,适用于处理一批静态的、可能不相关的图像。

max_num_hands:

  • 表示最多检测几只手,默认为 2。

min_detection_confidence:

  • 手部检测模型的最小置信值(0-1 之间),超过阈值则检测成功。默认为 0.5。

min_tracking_confidence:

  • 坐标跟踪模型的最小置信值(0-1 之间),用于将手部坐标视为成功跟踪。不成功则在下一个输入图像上自动调用手部检测。将其设置为更高的值可以提高解决方案的稳健性,但代价是更高的延迟。如果 static_image_mode 为 True,则忽略这个参数。默认为 0.5。

返回值

Handednessd

  • 表示检测到的手是左手还是右手

Landmarks

  • 手部关键点共有21个,每个关键点由x、y和z坐标组成。x和y坐标通过图像的宽度和高度进行了归一化,范围在[0.0, 1.0]之间。z坐标表示关键点的深度,手腕处的深度被定义为原点。数值越小,表示关键点离摄像机越近。z的大小与x的大小大致相同。

WorldLandmarks

  • 以世界坐标的形式呈现21个手部关键点。每个关键点由x、y和z组成,表示以米为单位的真实世界三维坐标,原点位于手的几何中心。
HandLandmarkerResult:
  Handedness:
    Categories #0:
      index        : 0
      score        : 0.98396
      categoryName : Left   # Left代表左手
  Landmarks:
    Landmark #0:
      x            : 0.638852
      y            : 0.671197
      z            : -3.41E-7
    Landmark #1:
      x            : 0.634599
      y            : 0.536441
      z            : -0.06984
    ... (21 landmarks for a hand)
  WorldLandmarks:
    Landmark #0:
      x            : 0.067485
      y            : 0.031084
      z            : 0.055223
    Landmark #1:
      x            : 0.063209
      y            : -0.00382
      z            : 0.020920
    ... (21 world landmarks for a hand)

6、参考

  • https://ai.google.dev/edge/mediapipe/solutions/vision/hand_landmarker/python
  • MediaPipe实现手指关键点检测及追踪,人脸识别及追踪
  • https://github.com/webdevpathiraja/Hand-Gesture-Sign-Detection-Project/tree/main
  • Mediapipe框架(一)人手关键点检测

更多有趣的代码示例,可参考【Programming】


http://www.kler.cn/a/595263.html

相关文章:

  • 能源监控软件UI界面设计:平衡功能性与审美性的艺术
  • 针对耳鸣患者推荐的一些菜谱和食材
  • 透析Vue的nextTick原理
  • uniapp小程序,输入框限制输入(正整数、小数后几位)
  • Umi-OCR 实践教程:离线、免费、高效的图像文字识别工具
  • 家庭网络安全:智能设备与IoT防护——当“智能家居”变成“僵尸网络”
  • Java 记忆链表,LinkedList 的升级版
  • PostgreSQL_数据表结构设计并创建
  • 使用 Ansys Fluent 评估金属管道腐蚀
  • 1204. 【高精度练习】密码
  • 《Python实战进阶》No42: 多线程与多进程编程详解(上)
  • 【漫话机器学习系列】153.残差平方和(Residual Sum of Squares, RSS)
  • LeetCode 2680.最大或值:位运算
  • 如何在IPhone 16Pro上运行python文件?
  • 【UI设计】一些好用的免费图标素材网站
  • el-select下拉框,搜索时,若是匹配后的数据有且只有一条,则当失去焦点时,默认选中该条数据
  • ngx_http_conf_port_t
  • 每天学一个 Linux 命令(6):shutdown
  • QT学习笔记3
  • ⭐算法OJ⭐二叉树的后序遍历【树的遍历】(C++实现)Binary Tree Postorder Traversal