result.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. # copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
  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 cv2
  15. import math
  16. import matplotlib.pyplot as plt
  17. import numpy as np
  18. from ...common.result import BaseCVResult
  19. def get_color(idx):
  20. idx = idx * 3
  21. color = ((37 * idx) % 255, (17 * idx) % 255, (29 * idx) % 255)
  22. return color
  23. def draw_keypoints(img, results, visual_thresh=0.1, ids=None):
  24. plt.switch_backend("agg")
  25. skeletons = results["keypoints"]
  26. skeletons = np.array(skeletons)
  27. if len(skeletons) > 0:
  28. kpt_nums = skeletons.shape[1]
  29. if kpt_nums == 17: # plot coco keypoint
  30. EDGES = [
  31. (0, 1),
  32. (0, 2),
  33. (1, 3),
  34. (2, 4),
  35. (3, 5),
  36. (4, 6),
  37. (5, 7),
  38. (6, 8),
  39. (7, 9),
  40. (8, 10),
  41. (5, 11),
  42. (6, 12),
  43. (11, 13),
  44. (12, 14),
  45. (13, 15),
  46. (14, 16),
  47. (11, 12),
  48. ]
  49. else: # plot mpii keypoint
  50. EDGES = [
  51. (0, 1),
  52. (1, 2),
  53. (3, 4),
  54. (4, 5),
  55. (2, 6),
  56. (3, 6),
  57. (6, 7),
  58. (7, 8),
  59. (8, 9),
  60. (10, 11),
  61. (11, 12),
  62. (13, 14),
  63. (14, 15),
  64. (8, 12),
  65. (8, 13),
  66. ]
  67. NUM_EDGES = len(EDGES)
  68. colors = [
  69. [255, 0, 0],
  70. [255, 85, 0],
  71. [255, 170, 0],
  72. [255, 255, 0],
  73. [170, 255, 0],
  74. [85, 255, 0],
  75. [0, 255, 0],
  76. [0, 255, 85],
  77. [0, 255, 170],
  78. [0, 255, 255],
  79. [0, 170, 255],
  80. [0, 85, 255],
  81. [0, 0, 255],
  82. [85, 0, 255],
  83. [170, 0, 255],
  84. [255, 0, 255],
  85. [255, 0, 170],
  86. [255, 0, 85],
  87. ]
  88. plt.figure()
  89. color_set = results["colors"] if "colors" in results else None
  90. if "bbox" in results and ids is None:
  91. bboxs = results["bbox"]
  92. for j, rect in enumerate(bboxs):
  93. xmin, ymin, xmax, ymax = rect
  94. color = (
  95. colors[0] if color_set is None else colors[color_set[j] % len(colors)]
  96. )
  97. cv2.rectangle(img, (xmin, ymin), (xmax, ymax), color, 1)
  98. canvas = img.copy()
  99. for i in range(kpt_nums):
  100. for j in range(len(skeletons)):
  101. if skeletons[j][i, 2] < visual_thresh:
  102. continue
  103. if ids is None:
  104. color = (
  105. colors[i]
  106. if color_set is None
  107. else colors[color_set[j] % len(colors)]
  108. )
  109. else:
  110. color = get_color(ids[j])
  111. cv2.circle(
  112. canvas,
  113. tuple(skeletons[j][i, 0:2].astype("int32")),
  114. 2,
  115. color,
  116. thickness=-1,
  117. )
  118. stickwidth = 1
  119. for i in range(NUM_EDGES):
  120. for j in range(len(skeletons)):
  121. edge = EDGES[i]
  122. if (
  123. skeletons[j][edge[0], 2] < visual_thresh
  124. or skeletons[j][edge[1], 2] < visual_thresh
  125. ):
  126. continue
  127. cur_canvas = canvas.copy()
  128. X = [skeletons[j][edge[0], 1], skeletons[j][edge[1], 1]]
  129. Y = [skeletons[j][edge[0], 0], skeletons[j][edge[1], 0]]
  130. mX = np.mean(X)
  131. mY = np.mean(Y)
  132. length = ((X[0] - X[1]) ** 2 + (Y[0] - Y[1]) ** 2) ** 0.5
  133. angle = math.degrees(math.atan2(X[0] - X[1], Y[0] - Y[1]))
  134. polygon = cv2.ellipse2Poly(
  135. (int(mY), int(mX)), (int(length / 2), stickwidth), int(angle), 0, 360, 1
  136. )
  137. if ids is None:
  138. color = (
  139. colors[i]
  140. if color_set is None
  141. else colors[color_set[j] % len(colors)]
  142. )
  143. else:
  144. color = get_color(ids[j])
  145. cv2.fillConvexPoly(cur_canvas, polygon, color)
  146. canvas = cv2.addWeighted(canvas, 0.4, cur_canvas, 0.6, 0)
  147. plt.close()
  148. return canvas
  149. class KptResult(BaseCVResult):
  150. """Save Result Transform"""
  151. def _to_img(self):
  152. """apply"""
  153. if "kpts" in self: # for single module result
  154. keypoints = [kpt["keypoints"] for kpt in self["kpts"]]
  155. else:
  156. keypoints = [
  157. obj["keypoints"] for obj in self["boxes"]
  158. ] # for top-down pipeline result
  159. image = draw_keypoints(self["input_img"], dict(keypoints=np.stack(keypoints)))
  160. return {"res": image}