当前位置:   article > 正文

人体姿态估计库 mediapipe

mediapipe

在jetson-nx上文件夹中的whl包就能安装了,在PC的windows上直接pip install mediapipe就能安装

目录

1  全身姿态检测

1.1  基本使用

1.2  关键点分析

1.2.1  确定对应关系

1.2.2  通过对应关系判断

1.3  搭配摄像头使用

2  手部姿态检测

2.1  基本使用

2.2  关键点分析

2.2.1  确定对应关系

2.2.2  通过对应关系判断

2.3  搭配摄像头使用


 

1  全身姿态检测

1.1  基本使用

  1. import cv2
  2. import mediapipe as mp
  3. from PIL import ImageFont,ImageDraw,Image
  4. mp_drawing = mp.solutions.drawing_utils
  5. mp_pose = mp.solutions.pose
  6. pose = mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5)
  7. image = cv2.imread('right_foot_aboard.jpg')
  8. image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  9. # image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)
  10. # To improve performance, optionally mark the image as not writeable to
  11. # pass by reference.
  12. image.flags.writeable = False
  13. results = pose.process(image)
  14. # Draw the pose annotation on the image.
  15. image.flags.writeable = True
  16. image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
  17. mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
  18. pose.close()
  19. cv2.imshow('MediaPipe Pose', image)
  20. cv2.waitKey(0)
  21. cv2.destroyAllWindows()

1.2  关键点分析

1.2.1  确定对应关系

我们可以对识别到的点进行操作,比如检测左侧脚尖在上,还是右脚脚尖在上,也就是32点和31点哪一个在y轴值更小

首先打印一下result

一共是33个点,我们看最后的31和32

我们可以根据图与结果分析出来下面几个信息

  • x轴和y轴以图像的左上角为原点,值越大越靠右或靠下。z轴以屏幕为原点,值越小距离屏幕越远
  • x,y,z是比例值。x估计是与图像宽的比例,y估计是与图像高的比例,z不知道
  • visibility是可见度,值越大越可见,值越小说明可能被遮挡

1.2.2  通过对应关系判断

我们可以通过遍历拿到 左脚、右脚脚尖与图像的比例,然后把他们进行比较

我们换一张图测试一下

1.3  搭配摄像头使用

  1. import cv2
  2. import mediapipe as mp
  3. from PIL import ImageFont, ImageDraw, Image
  4. mp_drawing = mp.solutions.drawing_utils
  5. mp_pose = mp.solutions.pose
  6. pose = mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5)
  7. cap = cv2.VideoCapture(0)
  8. while True:
  9. ret, frame = cap.read()
  10. if ret:
  11. image = cv2.cvtColor(cv2.flip(frame, 1), cv2.COLOR_BGR2RGB)
  12. image.flags.writeable = False
  13. results = pose.process(image)
  14. image.flags.writeable = True
  15. image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
  16. mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
  17. cv2.imshow("capture", image)
  18. k = cv2.waitKey(1)
  19. if k == ord(' ') :
  20. break
  21. # 关闭视频捕获器
  22. cap.release()
  23. # 销毁所有窗口
  24. cv2.destroyAllWindows()
  25. pose.close()

测试过在jetson-nx上用GPU是流畅的。在PC上CPU(CPU与内存配置如下图)是流畅的(GPU没测)

2  手部姿态检测

参考 JetBot手势识别实验_from jetbot import robot-CSDN博客

2.1  基本使用

  1. import cv2
  2. import mediapipe as mp
  3. # 初始化MediaPipe Hands模块
  4. mp_hands = mp.solutions.hands
  5. hands = mp_hands.Hands(static_image_mode=True,
  6. max_num_hands=2,
  7. min_detection_confidence=0.5,
  8. min_tracking_confidence=0.5)
  9. mp_drawing = mp.solutions.drawing_utils # 用于绘制关键点的工具
  10. # 读取图片
  11. image_path = '1.jpg' # 这里替换为你的图片路径
  12. image = cv2.imread(image_path)
  13. if image is None:
  14. print("Cannot find the image.")
  15. else:
  16. # 将图像从BGR转换为RGB
  17. image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  18. # 处理图像,检测手部
  19. results = hands.process(image_rgb)
  20. # 将图像从RGB转回BGR以显示
  21. image_bgr = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR)
  22. # 绘制手部关键点
  23. if results.multi_hand_landmarks:
  24. for hand_landmarks in results.multi_hand_landmarks:
  25. mp_drawing.draw_landmarks(image_bgr, hand_landmarks, mp_hands.HAND_CONNECTIONS)
  26. # 显示图像
  27. cv2.imshow('Hand Detection', image_bgr)
  28. cv2.waitKey(0) # 等待按键
  29. cv2.destroyAllWindows()
  30. # # 可选:保存输出图像
  31. # output_image_path = 'path_to_your_output_image.jpg' # 输出文件的路径
  32. # cv2.imwrite(output_image_path, image_bgr)
  33. # print("Output image is saved as", output_image_path)
  34. # 释放资源
  35. hands.close()

2.2  关键点分析

2.2.1  确定对应关系

与全身姿态用法相同了,我们简单说一下

results.multi_hand_landmarks[0]可能会有直接变成列表的方法,我这里就直接用正则取了

  1. import cv2
  2. import mediapipe as mp
  3. import re
  4. p = re.compile(r'landmark {\n x: .*\n y: .*\n z: .*\n}')
  5. # 初始化MediaPipe Hands模块
  6. mp_hands = mp.solutions.hands
  7. hands = mp_hands.Hands(static_image_mode=True,
  8. max_num_hands=2,
  9. min_detection_confidence=0.5,
  10. min_tracking_confidence=0.5)
  11. mp_drawing = mp.solutions.drawing_utils # 用于绘制关键点的工具
  12. # 读取图片
  13. image_path = '1.jpg' # 这里替换为你的图片路径
  14. image = cv2.imread(image_path)
  15. if image is None:
  16. print("Cannot find the image.")
  17. else:
  18. # 将图像从BGR转换为RGB
  19. image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  20. # 处理图像,检测手部
  21. results = hands.process(image_rgb)
  22. # print()
  23. id = 0
  24. for result in p.findall(str(results.multi_hand_landmarks[0])):
  25. print('id',id)
  26. id = id + 1
  27. print(result)
  28. print()
  29. # 将图像从RGB转回BGR以显示
  30. image_bgr = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR)
  31. # 绘制手部关键点
  32. if results.multi_hand_landmarks:
  33. for hand_landmarks in results.multi_hand_landmarks:
  34. mp_drawing.draw_landmarks(image_bgr, hand_landmarks, mp_hands.HAND_CONNECTIONS)
  35. cv2.imshow('Hand Detection', image_bgr)
  36. cv2.waitKey(0) # 等待按键
  37. cv2.destroyAllWindows()
  38. hands.close()

我们重点关注食指,通过点位图来看不是8就16

对比图像来看,食指的顶点应该过图像的一半,所以16不符合。之后考虑8,观察其他点与8点的y值可以看出8点比其他的点的y值要小,基本可以断定8点就是食指的顶点

2.2.2  通过对应关系判断

我们比如要判断食指是否伸展,那么就判断 |8的y-0的y| 是否大于 |7的y-0的y|

  • 上面这个条件仅考虑手掌面对摄像头或背对摄像头的情况,不考虑手掌冲上或冲下的情况

  1. import cv2
  2. import mediapipe as mp
  3. import re
  4. p = re.compile(r'y: (.*)')
  5. # 初始化MediaPipe Hands模块
  6. mp_hands = mp.solutions.hands
  7. hands = mp_hands.Hands(static_image_mode=True,
  8. max_num_hands=2,
  9. min_detection_confidence=0.5,
  10. min_tracking_confidence=0.5)
  11. mp_drawing = mp.solutions.drawing_utils # 用于绘制关键点的工具
  12. # 读取图片
  13. image_path = '6.jpg' # 这里替换为你的图片路径
  14. image = cv2.imread(image_path)
  15. if image is None:
  16. print("Cannot find the image.")
  17. else:
  18. # 将图像从BGR转换为RGB
  19. image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  20. # 处理图像,检测手部
  21. results = hands.process(image_rgb)
  22. y_list = p.findall(str(results.multi_hand_landmarks[0]))
  23. if abs(float(y_list[8])-float(y_list[0]))>abs(float(y_list[7])-float(y_list[0])):
  24. print('食指伸展')
  25. else:
  26. print('食指不伸展')
  27. # 将图像从RGB转回BGR以显示
  28. image_bgr = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR)
  29. # 绘制手部关键点
  30. if results.multi_hand_landmarks:
  31. for hand_landmarks in results.multi_hand_landmarks:
  32. mp_drawing.draw_landmarks(image_bgr, hand_landmarks, mp_hands.HAND_CONNECTIONS)
  33. cv2.imshow('Hand Detection', image_bgr)
  34. cv2.waitKey(0) # 等待按键
  35. cv2.destroyAllWindows()
  36. hands.close()

换一张图测一下

如果要通过5个手指的判断手势是有点复杂的,而且mediapipe也不一定准,所以不建议通过mediapipe做手势识别

2.3  搭配摄像头使用

注意在代码中把static_image_mode改为False

  1. import cv2
  2. import mediapipe as mp
  3. mp_hands = mp.solutions.hands
  4. hands = mp_hands.Hands(static_image_mode=False,
  5. max_num_hands=2,
  6. min_detection_confidence=0.5,
  7. min_tracking_confidence=0.5)
  8. mp_drawing = mp.solutions.drawing_utils
  9. cap = cv2.VideoCapture(0)
  10. while True:
  11. ret, frame = cap.read()
  12. if ret:
  13. image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
  14. results = hands.process(image_rgb)
  15. image_bgr = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR)
  16. if results.multi_hand_landmarks:
  17. for hand_landmarks in results.multi_hand_landmarks:
  18. mp_drawing.draw_landmarks(image_bgr, hand_landmarks, mp_hands.HAND_CONNECTIONS)
  19. cv2.imshow("capture", image_bgr)
  20. k = cv2.waitKey(1)
  21. if k == ord(' '):
  22. break
  23. cap.release()
  24. cv2.destroyAllWindows()

测试环境与全身姿态检测相同,运行流畅。在nx中会出现下面两个warning,就结果来看问题不大

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/988863
推荐阅读
相关标签
  

闽ICP备14008679号