Mediapipe显示身体关键点仅。

huangapple go评论93阅读模式
英文:

Mediapipe Display Body Landmarks Only

问题

我已经安装了Python (3.7.0)在Windows 11上使用Mediapipe (0.9.0.1)。
我已成功地让Mediapipe为图像、视频和网络摄像头流生成了关键点(用于面部和身体)。

现在,我想让Mediapipe 绘制身体特定的关键点(即排除面部关键点)。

我了解我可以使用OpenCV(或Czone)来实现这个目标,但我希望使用Mediapipe(即使用Mediapipe库中的draw_landmarks函数)来实现我的目标。

我尝试的特定代码部分(但出现了错误)如下:

  1. #初始化一个列表来存储检测到的关键点。
  2. landmarks = []
  3. #遍历Mediapipe检测到的关键点。
  4. for landmark in results.pose_landmarks.landmark:
  5. #将Mediapipe关键点添加到列表中。
  6. landmarks.append((int(landmark.x * width), int(landmark.y * height),
  7. (landmark.z * width)))
  8. #为特定的关键点创建索引列表
  9. body_landmark_indices = [11,12,13,14,15,16,23,24,25,26,27,28,29,30,31,32]
  10. landmark_list_body = []
  11. #创建一个仅包含所需关键点的列表
  12. for index in body_landmark_indices:
  13. landmark_list_body.append(landmarks[index - 1])
  14. mp_drawing.draw_landmarks(
  15. image=output_image,
  16. landmark_list=landmark_list_body,
  17. connections=mp_pose.POSE_CONNECTIONS,
  18. landmark_drawing_spec=landmark_drawing_spec,
  19. connection_drawing_spec=connection_drawing_spec)`
  20. 执行上述代码时,我收到错误信息`'list' object has no attribute 'pose_landmarks'`。
  21. 我已经用`landmark_list=landmark_list_body`替换了`landmark_list=landmark_list_body.pose_landmarks`,但仍然出现错误。
  22. 我现在非常疲倦并且没有更多的想法。是否有无需斗篷的英雄可以帮助?
  23. 谢谢。
  24. <details>
  25. <summary>英文:</summary>
  26. I have installed Mediapipe (0.9.0.1) using Python (3.7.0) on windows 11.
  27. I have been able to successfully get Mediapipe to generate landmarks (for face and body); for an image, video, and webcam stream.
  28. I would like to now get Mediapipe to **only** draw body specific landmarks (i.e. exclude facial landmarks).
  29. I understand that I may use OpenCV (or Czone) to accomplish this goal, however, I am looking to achieve my objective using Mediapipe (i.e. using the `draw_landmarks` function in the MediaPipe library).
  30. The specific bit of code I am trying (but with errors) is the following:

#Initialize a list to store the detected landmarks.
landmarks = []

  1. # Iterate over the Mediapipe detected landmarks.
  2. for landmark in results.pose_landmarks.landmark:
  3. # Append the Mediapipe landmark into the list.
  4. landmarks.append((int(landmark.x * width), int(landmark.y * height),
  5. (landmark.z * width)))
  6. #create index list for specific landmarks
  7. body_landmark_indices = [11,12,13,14,15,16,23,24,25,26,27,28,29,30,31,32]
  8. landmark_list_body = []
  9. #Create a list which only has the required landmarks
  10. for index in body_landmark_indices:
  11. landmark_list_body.append(landmarks[index - 1])
  12. mp_drawing.draw_landmarks(
  13. image=output_image,
  14. landmark_list=landmark_list_body.pose_landmarks,
  15. connections=mp_pose.POSE_CONNECTIONS,
  16. landmark_drawing_spec=landmark_drawing_spec,
  17. connection_drawing_spec=connection_drawing_spec)`

Executing the above I get the error `'list' object has no attribute 'pose_landmarks'

  1. I have replaced `landmark_list=landmark_list_body.pose_landmarks,` with `landmark_list=landmark_list_body` but with errors.
  2. I am now very tiered and out of ideas. Is there a capeless hero out there?
  3. Thanks.
  4. </details>
  5. # 答案1
  6. **得分**: 5
  7. 你可以尝试以下方法:
  8. ```python
  9. import cv2
  10. import mediapipe as mp
  11. import numpy as np
  12. from mediapipe.python.solutions.pose import PoseLandmark
  13. from mediapipe.python.solutions.drawing_utils import DrawingSpec
  14. mp_drawing = mp.solutions.drawing_utils
  15. mp_drawing_styles = mp.solutions.drawing_styles
  16. mp_pose = mp.solutions.pose
  17. custom_style = mp_drawing_styles.get_default_pose_landmarks_style()
  18. custom_connections = list(mp_pose.POSE_CONNECTIONS)
  19. # 要从绘图中排除的关键点列表
  20. excluded_landmarks = [
  21. PoseLandmark.LEFT_EYE,
  22. PoseLandmark.RIGHT_EYE,
  23. PoseLandmark.LEFT_EYE_INNER,
  24. PoseLandmark.RIGHT_EYE_INNER,
  25. PoseLandmark.LEFT_EAR,
  26. PoseLandmark.RIGHT_EAR,
  27. PoseLandmark.LEFT_EYE_OUTER,
  28. PoseLandmark.RIGHT_EYE_OUTER,
  29. PoseLandmark.NOSE,
  30. PoseLandmark.MOUTH_LEFT,
  31. PoseLandmark.MOUTH_RIGHT ]
  32. for landmark in excluded_landmarks:
  33. # 改变被排除关键点的绘制方式
  34. custom_style[landmark] = DrawingSpec(color=(255,255,0), thickness=None)
  35. # 删除包含这些关键点的所有连接
  36. custom_connections = [connection_tuple for connection_tuple in custom_connections
  37. if landmark.value not in connection_tuple]
  38. IMAGE_FILES = ["test.jpg"]
  39. BG_COLOR = (192, 192, 192)
  40. with mp_pose.Pose(
  41. static_image_mode=True,
  42. model_complexity=2,
  43. enable_segmentation=True,
  44. min_detection_confidence=0.5) as pose:
  45. for idx, file in enumerate(IMAGE_FILES):
  46. image = cv2.imread(file)
  47. image_height, image_width, _ = image.shape
  48. results = pose.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
  49. annotated_image = image.copy()
  50. mp_drawing.draw_landmarks(
  51. annotated_image,
  52. results.pose_landmarks,
  53. connections = custom_connections, # 传递修改后的连接列表
  54. landmark_drawing_spec=custom_style) # 和绘制样式
  55. cv2.imshow('landmarks', annotated_image)
  56. cv2.waitKey(0)

它修改了DrawingSpecPOSE_CONNECTIONS来“隐藏”一部分关键点。但是,由于在Mediapipe中实现draw_landmarks()函数的方式,还需要在drawing_utils.py中添加一个条件(位于site-packages/mediapipe/python/solutions):

  1. if drawing_spec.thickness == None: continue

在第188行之前添加这行代码(查看MediaPipe GitHub 仓库# White circle border)。结果应该是这样的:

  1. ...
  2. drawing_spec = landmark_drawing_spec[idx] if isinstance(
  3. landmark_drawing_spec, Mapping) else landmark_drawing_spec
  4. if drawing_spec.thickness == None: continue
  5. # White circle border
  6. circle_border_radius = max(drawing_spec.circle_radius + 1,
  7. int(drawing_spec.circle_radius * 1.2))
  8. ...

这个改变是为了完全消除绘制在关键点周围的白色边框,而不考虑它们的绘制规范。

希望对你有所帮助。

英文:

You can try the following approach:

  1. import cv2
  2. import mediapipe as mp
  3. import numpy as np
  4. from mediapipe.python.solutions.pose import PoseLandmark
  5. from mediapipe.python.solutions.drawing_utils import DrawingSpec
  6. mp_drawing = mp.solutions.drawing_utils
  7. mp_drawing_styles = mp.solutions.drawing_styles
  8. mp_pose = mp.solutions.pose
  9. custom_style = mp_drawing_styles.get_default_pose_landmarks_style()
  10. custom_connections = list(mp_pose.POSE_CONNECTIONS)
  11. # list of landmarks to exclude from the drawing
  12. excluded_landmarks = [
  13. PoseLandmark.LEFT_EYE,
  14. PoseLandmark.RIGHT_EYE,
  15. PoseLandmark.LEFT_EYE_INNER,
  16. PoseLandmark.RIGHT_EYE_INNER,
  17. PoseLandmark.LEFT_EAR,
  18. PoseLandmark.RIGHT_EAR,
  19. PoseLandmark.LEFT_EYE_OUTER,
  20. PoseLandmark.RIGHT_EYE_OUTER,
  21. PoseLandmark.NOSE,
  22. PoseLandmark.MOUTH_LEFT,
  23. PoseLandmark.MOUTH_RIGHT ]
  24. for landmark in excluded_landmarks:
  25. # we change the way the excluded landmarks are drawn
  26. custom_style[landmark] = DrawingSpec(color=(255,255,0), thickness=None)
  27. # we remove all connections which contain these landmarks
  28. custom_connections = [connection_tuple for connection_tuple in custom_connections
  29. if landmark.value not in connection_tuple]
  30. IMAGE_FILES = [&quot;test.jpg&quot;]
  31. BG_COLOR = (192, 192, 192)
  32. with mp_pose.Pose(
  33. static_image_mode=True,
  34. model_complexity=2,
  35. enable_segmentation=True,
  36. min_detection_confidence=0.5) as pose:
  37. for idx, file in enumerate(IMAGE_FILES):
  38. image = cv2.imread(file)
  39. image_height, image_width, _ = image.shape
  40. results = pose.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
  41. annotated_image = image.copy()
  42. mp_drawing.draw_landmarks(
  43. annotated_image,
  44. results.pose_landmarks,
  45. connections = custom_connections, # passing the modified connections list
  46. landmark_drawing_spec=custom_style) # and drawing style
  47. cv2.imshow(&#39;landmarks&#39;, annotated_image)
  48. cv2.waitKey(0)

It modifies the DrawingSpec and POSE_CONNECTIONS to "hide" a subset of landmarks.
However, due to the way the draw_landmarks() function is implemented in Mediapipe, it is also required to add a condition in drawing_utils.py (located in site-packages/mediapipe/python/solutions):

  1. if drawing_spec.thickness == None: continue

Add it before Line 188 (see MediaPipe GitHub repo, # White circle border). The result should look like this:

  1. ...
  2. drawing_spec = landmark_drawing_spec[idx] if isinstance(
  3. landmark_drawing_spec, Mapping) else landmark_drawing_spec
  4. if drawing_spec.thickness == None: continue
  5. # White circle border
  6. circle_border_radius = max(drawing_spec.circle_radius + 1,
  7. int(drawing_spec.circle_radius * 1.2))
  8. ...

This change is required in order to completely eliminate the white border that is drawn around landmarks regardless of their drawing specification.

Hope it helps.

huangapple
  • 本文由 发表于 2023年2月7日 02:50:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75365431.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定