【姿态估计】MediaPipe部分solution(手势,人体姿态,面部动作)的用法

[复制链接]
查看897 | 回复0 | 2023-8-23 12:04:53 | 显示全部楼层 |阅读模式
Mediapipe先容

MediaPipe是个基于图形的跨平台框架,用于构建多模式应用的呆板学习管道。
MediaPipe可在移动装备,工作站和服务器上跨平台运行,并支持移动GPU加速。利用MediaPipe,可以将应用的呆板学习管道构建为模块化组件的图形。
MediaPipe专为呆板学习从业者而设计包罗研究职员,门生,和软件开发职员,他们实行生产就绪的ML应用步调,发布伴随研究工作的代码,以及构建技术原型。MediaPipe的紧张用例上利用推理模型和其他可重用组件对应用呆板学习管道举行快速原型设计。MediaPipe还有助于呆板学习技术摆设到各种不消硬件平台上的演示和应用步调中。
MediaPipe Solutions是基于特定的预练习TensorFlow或TFLite模型的开源预构建示例,他提供了多个Solutions,如下图所示。

本篇紧张对手势辨认,人体姿态估计,面部辨认的方法举行演示,领导入门者入门。
1. 手势辨认

通过MediaPipe,可以获取手部关节的21个点(如下图),以及每个点对应的坐标,那么我们就可以用坐标点来做一下项目的现实应用了, 比如手语的翻译,手势指令之类的。

首先导入包
  1. import mediapipe as mp
  2. import cv2
  3. import numpy as np
  4. import time
复制代码
手势检测代码如下,再次我们只是展示了大拇指与食指之间的距离,然后举行了可视化展示。
获取了20个点的坐标,可以实现本身想要手势手语辨认。
  1. # 定义一个函数,计算两个点的距离
  2. def findDis(pts1,pts2):
  3.     return ((pts2[0]-pts1[0])**2 + (pts2[1]-pts1[1])**2)**0.5
  4. # 创建手势检测模型
  5. mpHands = mp.solutions.hands  # 检测人的手
  6. hand_mode = mpHands.Hands(max_num_hands=2,min_detection_confidence=0.5,
  7.                         min_tracking_confidence=0.5)
  8. # static_image_mode:默认为False,如果设置为false, 就是把输入看作一个视频流,在检测到手之后对手加了一个目标跟踪(目标检测+跟踪),
  9. # 无需调用另一次检测,直到失去对任何手的跟踪为止。如果设置为True,则手部检测将在每个输入图像上运行(目标检测),非常适合处理一批静态的,
  10. # 可能不相关的图像。(如果检测的是图片就要设置成True)
  11. # 检测手的模式参数设置,max_num_hands:可以检测到的手的数量最大值,默认是2
  12. # min_detection_confidence: 手部检测的最小置信度值,大于这个数值被认为是成功的检测,
  13. # min_tracking_confidence:目标踪模型的最小置信度值,大于这个数值将被视为已成功跟踪的手部,如果static_image_mode设置为true,则忽略此操作。
  14. mpDraw = mp.solutions.drawing_utils  # 绘图
  15. cap = cv2.VideoCapture(0)
  16. while True:
  17.     success,img = cap.read()
  18.     img = cv2.flip(img,1)
  19.     results = hand_mode.process(img)# 将图片导入模型,获取20个点的坐标进行分析
  20.     if results.multi_hand_landmarks:
  21.         for handLms in results.multi_hand_landmarks:
  22.             point4_8 = []
  23.             for id,lm in enumerate(handLms.landmark):
  24.                 h,w,c = img.shape
  25.                 cx,cy = int(lm.x*w),int(lm.y*h)
  26.                 cv2.circle(img,(cx,cy),10,(255,0,0),-1)
  27.                 if id in [4,8]:# 获取点4,8的坐标
  28.                     point4_8.append([cx,cy])
  29.             mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)
  30.             # 求点4,8的坐标,进行可视化展示
  31.             cv2.line(img,(point4_8[0][0],point4_8[0][1]),(point4_8[1][0],point4_8[1][1]),(0,0,255),5)
  32.             distance = round(findDis((point4_8[0][0],point4_8[0][1]),(point4_8[1][0],point4_8[1][1])),2)
  33.             cv2.putText(img,"distance:{}".format(distance),(50,50),cv2.FONT_HERSHEY_PLAIN, 3,(0,0,255),3)
  34.             cv2.rectangle(img,(20,250),(20+10,250-int(distance)),(255,0,255),20)
  35.     cv2.imshow("img",img)
  36.     if cv2.waitKey(1)&0xFF == ord("q"):
  37.         break
  38. cap.release()
  39. cv2.destroyAllWindows()
复制代码
结果如下:

2. 人体姿势辨认

人体姿势辨认便是辨认人体身上的32个点,本部分通过辨认点23,25的位置来辨认是否举行抬腿动作。通过这部分,各人可以去制作像深蹲计数、跳绳计数、摆臂等如许的功能。

代码如下:
  1. mpPose = mp.solutions.pose  # 检测人的手
  2. pose_mode = mpPose.Pose(min_detection_confidence=0.5,min_tracking_confidence=0.5)  # 模式参数设置
  3. mpDraw = mp.solutions.drawing_utils  # 绘图
  4. cap = cv2.VideoCapture(0)
  5. biaoji = 0
  6. i = 0
  7. while True:
  8.     success,img = cap.read()
  9.     img = cv2.flip(img,1)
  10.     results = pose_mode.process(img)
  11.     if results.pose_landmarks:
  12.         point23_25 = []
  13.         for id,lm in enumerate(results.pose_landmarks.landmark):
  14.             h,w,c = img.shape
  15.             cx,cy = int(lm.x*w),int(lm.y*h)
  16.             cv2.circle(img,(cx,cy),10,(255,0,0),-1)
  17.             if id in [23,25]:
  18.                 point23_25.append([cx,cy])
  19.         mpDraw.draw_landmarks(img, results.pose_landmarks, mpPose.POSE_CONNECTIONS)
  20.         cv2.line(img,(point23_25[0][0],point23_25[0][1]),(point23_25[1][0],point23_25[1][1]),(0,0,255),5)
  21.         if point23_25[0][1]>point23_25[1][1]:
  22.             if biaoji == 1:
  23.                 i += 1
  24.                 biaoji = 0
  25.                 cv2.putText(img,"Leg up--{}".format(i),(10,50),cv2.FONT_HERSHEY_PLAIN, 3,(0,0,255),3)
  26.         else:
  27.             biaoji = 1
  28.             cv2.putText(img,"Leg down--{}".format(i),(10,450),cv2.FONT_HERSHEY_PLAIN, 3,(0,0,255),3)
  29.     cv2.imshow("img",img)
  30.     if cv2.waitKey(1)&0xFF == ord("q"):
  31.         break
  32. cap.release()
  33. cv2.destroyAllWindows()
复制代码
结果可视化展示:

3. 面部动作辨认

mediapip的人脸关键点一共有468个我在图中只看到467最大值,但是现实代码输出的478的关键点,从输出结果索引468-472存储的是人眼左边5个关键点,473-477存储的是人眼右边5个关键点。关键点图在网上还有点难找因此放这里,图片必要放大才气开清楚位置数字。
本文选取左眼【130,240,23,159】四个点和嘴巴【62,292,12,15】四个点,通过盘算四个点之间的关系,来判断眼睛和嘴巴是否处于伸开状态。这对于疲劳检测具有肯定的借鉴意义。代码如下:
  1. def findDis(pts1,pts2):
  2.     return ((pts2[0]-pts1[0])**2 + (pts2[1]-pts1[1])**2)**0.5
  3. cap = cv2.VideoCapture(0)
  4. pTime = 0
  5. id_list = [23, 159, 130, 243, 62, 292, 12, 15]
  6. mpDraw = mp.solutions.drawing_utils
  7. mpFaceMesh = mp.solutions.face_mesh
  8. faceMesh = mpFaceMesh.FaceMesh(max_num_faces=2)
  9. drawSpec = mpDraw.DrawingSpec(thickness=1, circle_radius=2)
  10. while True:
  11.     success, img = cap.read()
  12.     imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
  13.     results = faceMesh.process(imgRGB)
  14.     if results.multi_face_landmarks:
  15.         for faceLms in results.multi_face_landmarks:
  16.             mpDraw.draw_landmarks(img, faceLms, mpFaceMesh.FACEMESH_CONTOURS,
  17.                                   drawSpec,drawSpec)
  18.             mp_data = []
  19.             for id,lm in enumerate(faceLms.landmark):
  20.                 ih, iw, ic = img.shape
  21.                 x,y = int(lm.x*iw), int(lm.y*ih)
  22.                 if id in id_list:           #左眼[22, 23, 24, 26, 110, 157, 158, 159, 160, 161, 130, 243]:
  23.                     mp_data.append([x,y])
  24.                     cv2.circle(img,(x,y),2,(255,0,0),-1)
  25.             eye_length_1 = findDis(mp_data[0],mp_data[1])
  26.             eye_length_2 = findDis(mp_data[2],mp_data[3])
  27.             mouth_length_2 = findDis(mp_data[4],mp_data[5])
  28.             mouth_length_1 = findDis(mp_data[6],mp_data[7])
  29. #             print(eye_length_1,eye_length_2)
  30.             if ((mouth_length_1/mouth_length_2)<(98/18)):
  31.                 cv2.putText(img,"mouth close",(400,50),cv2.FONT_HERSHEY_PLAIN, 2,(0,0,255),3)
  32.                     
  33.             else:
  34.                 cv2.putText(img,"mouth open",(400,50),cv2.FONT_HERSHEY_PLAIN, 2,(0,0,255),3)
  35.             if (eye_length_2/eye_length_1)>18:
  36.                 cv2.putText(img,"eye open",(400,100),cv2.FONT_HERSHEY_PLAIN, 2,(0,0,255),3)  
  37.             else:                 
  38.                 cv2.putText(img,"eye close",(400,100),cv2.FONT_HERSHEY_PLAIN, 2,(0,0,255),3)  
  39.     cTime = time.time()
  40.     fps = 1 / (cTime - pTime)
  41.     pTime = cTime
  42.     cv2.putText(img, f'FPS: {int(fps)}', (20, 70), cv2.FONT_HERSHEY_PLAIN,
  43.                 3, (255, 0, 0), 3)
  44.     cv2.imshow("Image", img)
  45.     if cv2.waitKey(1)&0xFF == ord("q"):
  46.         cv2.imwrite("6.jpg",img)
  47.         break
  48. cap.release()
  49. cv2.destroyAllWindows()
复制代码
结果展示:

总结

无论是手势,人体姿态,还是人脸检测,都是对于点位的检测,通过点位坐标实现一系列功能。对于手势点位检测,我们可以实现手语辨认,对于人体姿势点位检测,可以实现人体动作,当下有那些跳绳计数、深蹲计数的App也是这么个原理;对于人脸检测,通过点位坐标检测,可以实现疲劳检测。这里不做多述,有兴趣者可以做各种有趣的事故。

来源:https://blog.csdn.net/qq_43018832/article/details/128015624
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则