visualizer.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. # Copyright (c) 2024 PaddlePaddle Authors. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import numpy as np
  15. from PIL import ImageDraw
  16. from ......utils.deps import function_requires_deps, is_dep_available
  17. if is_dep_available("pycocotools"):
  18. from pycocotools.coco import COCO
  19. @function_requires_deps("pycocotools")
  20. def draw_keypoint(image, coco_info: "COCO", img_id):
  21. """
  22. Draw keypoints on image for the COCO human keypoint dataset with 17 keypoints.
  23. Args:
  24. image: PIL.Image object
  25. coco_info: COCO object (from pycocotools.coco)
  26. img_id: Image ID
  27. Returns:
  28. image: PIL.Image object with keypoints and skeleton drawn
  29. """
  30. # Initialize the drawing context
  31. image = image.convert("RGB")
  32. draw = ImageDraw.Draw(image)
  33. image_size = image.size
  34. width = int(max(image_size) * 0.005) # Line thickness for drawing
  35. # Define the skeleton connections based on COCO keypoint indexes
  36. skeleton = [
  37. [15, 13],
  38. [13, 11],
  39. [16, 14],
  40. [14, 12],
  41. [11, 12],
  42. [5, 11],
  43. [6, 12],
  44. [5, 6],
  45. [5, 7],
  46. [6, 8],
  47. [7, 9],
  48. [8, 10],
  49. [1, 2],
  50. [0, 1],
  51. [0, 2],
  52. [1, 3],
  53. [2, 4],
  54. [3, 5],
  55. [4, 6],
  56. ]
  57. # Define colors for each keypoint (you can customize these colors)
  58. keypoint_colors = [
  59. (255, 0, 0), # Nose
  60. (255, 85, 0), # Left Eye
  61. (255, 170, 0), # Right Eye
  62. (255, 255, 0), # Left Ear
  63. (170, 255, 0), # Right Ear
  64. (85, 255, 0), # Left Shoulder
  65. (0, 255, 0), # Right Shoulder
  66. (0, 255, 85), # Left Elbow
  67. (0, 255, 170), # Right Elbow
  68. (0, 255, 255), # Left Wrist
  69. (0, 170, 255), # Right Wrist
  70. (0, 85, 255), # Left Hip
  71. (0, 0, 255), # Right Hip
  72. (85, 0, 255), # Left Knee
  73. (170, 0, 255), # Right Knee
  74. (255, 0, 255), # Left Ankle
  75. (255, 0, 170), # Right Ankle
  76. ]
  77. # Get annotations for the image
  78. annotations = coco_info.loadAnns(coco_info.getAnnIds(imgIds=img_id))
  79. # Loop over each person annotation
  80. for ann in annotations:
  81. keypoints = ann.get("keypoints", [])
  82. if not keypoints:
  83. continue # Skip if no keypoints are present
  84. # Reshape keypoints into (num_keypoints, 3)
  85. keypoints = np.array(keypoints).reshape(-1, 3)
  86. # Draw keypoints
  87. for idx, (x, y, v) in enumerate(keypoints):
  88. if v == 2: # v=2 means the keypoint is labeled and visible
  89. radius = max(1, int(width / 2))
  90. x, y = float(x), float(y)
  91. color = keypoint_colors[idx % len(keypoint_colors)]
  92. draw.ellipse(
  93. (x - radius, y - radius, x + radius, y + radius), fill=color
  94. )
  95. # Draw skeleton by connecting keypoints
  96. for sk in skeleton:
  97. kp1_idx, kp2_idx = sk[0], sk[1]
  98. x1, y1, v1 = keypoints[kp1_idx]
  99. x2, y2, v2 = keypoints[kp2_idx]
  100. if v1 == 2 and v2 == 2:
  101. # Both keypoints are visible
  102. x1, y1 = float(x1), float(y1)
  103. x2, y2 = float(x2), float(y2)
  104. draw.line(
  105. (x1, y1, x2, y2),
  106. fill=(0, 255, 0), # Line color (you can customize)
  107. width=width,
  108. )
  109. return image