欢迎访问我的网站,希望内容对您有用,感兴趣的可以加入我们的社群。

openpose重绘json里的骨骼信息

算法 迷途小书童 3年前 (2021-12-17) 4415次浏览 0个评论

环境

  • windows 10 64 bit
  • opencv 4.5.3

需求

这是来自一位网友的需求,他已经拿到了团队内其它成员通过 openpose 处理后的 json 数据(这部分内容前文 windows编译openpose及在python中调用 已经讲过),现在要将 json 里描述的骨骼信息描绘出来,也就是画出骨骼图。

解决步骤

要实现这个目标,首先要把 json 文件中的数据结构弄清楚。下图是拿到的 json

openpose json

由于是 2d 的识别,所有 json 中只有字段 pose_keypoints_2dhand_left_keypoints_2dhand_right_keypoints_2d 有数据。其它情况,处理也是类似的

这里分2块来处理,身体部分与左右手的部分,前者的关键点如下图,共25个关键点

openpose json

取到每一个点的位置,然后将需要连接的点进行连接,比如关键点0就需要和关键点1、15、16进行连接

  1. pose_pairs = [
  2. [0, 1], [0, 15], [0, 16],
  3. [15, 17],
  4. [16, 18],
  5. [1, 2], [1, 5], [1, 8],
  6. [2, 3],
  7. [3, 4],
  8. [5, 6],
  9. [6, 7],
  10. [8, 9], [8, 12],
  11. [9, 10],
  12. [10, 11],
  13. [11, 22], [11, 24],
  14. [22, 23],
  15. [12, 13],
  16. [13, 14],
  17. [14, 21], [14, 19],
  18. [19, 20]
  19. ]

至于左右手的关键点也是一样,其分布如下

openpose json

至于各个关键点的坐标,再回过头去看 json 文件,在字段 pose_keypoints_2d 中,每3个数值代表一个关键点,分别对应的是 xy 和置信度,取到这些信息后就可以在图上标示出来了

openpose json

最后看一下完整的程序代码

  1. import argparse
  2. import json
  3. import os
  4. import cv2
  5. import numpy as np
  6. # 骨骼关键点连接对
  7. pose_pairs = [
  8. [0, 1], [0, 15], [0, 16],
  9. [15, 17],
  10. [16, 18],
  11. [1, 2], [1, 5], [1, 8],
  12. [2, 3],
  13. [3, 4],
  14. [5, 6],
  15. [6, 7],
  16. [8, 9], [8, 12],
  17. [9, 10],
  18. [10, 11],
  19. [11, 22], [11, 24],
  20. [22, 23],
  21. [12, 13],
  22. [13, 14],
  23. [14, 21], [14, 19],
  24. [19, 20]
  25. ]
  26. # 手部关键点连接对
  27. hand_pairs = [
  28. [0, 1], [0, 5], [0, 9], [0, 13], [0, 17],
  29. [1, 2],
  30. [2, 3],
  31. [3, 4],
  32. [5, 6], [6, 7], [7, 8],
  33. [9, 10], [10, 11], [11, 12],
  34. [13, 14], [14, 15], [15, 16],
  35. [17, 18], [18, 19], [19, 20]
  36. ]
  37. # 绘制用的颜色
  38. pose_colors = [
  39. (255., 0., 85.), (255., 0., 0.), (255., 85., 0.), (255., 170., 0.),
  40. (255., 255., 0.), (170., 255., 0.), (85., 255., 0.), (0., 255., 0.),
  41. (255., 0., 0.), (0., 255., 85.), (0., 255., 170.), (0., 255., 255.),
  42. (0., 170., 255.), (0., 85., 255.), (0., 0., 255.), (255., 0., 170.),
  43. (170., 0., 255.), (255., 0., 255.), (85., 0., 255.), (0., 0., 255.),
  44. (0., 0., 255.), (0., 0., 255.), (0., 255.,
  45. 255.), (0., 255., 255.), (0., 255., 255.)
  46. ]
  47. hand_colors = [
  48. (100., 100., 100.),
  49. (100, 0, 0),
  50. (150, 0, 0),
  51. (200, 0, 0), (255, 0, 0), (100, 100, 0), (150,
  52. 150, 0), (200, 200, 0), (255, 255, 0),
  53. (0, 100, 50), (0, 150, 75), (0, 200, 100), (0,
  54. 255, 125), (0, 50, 100), (0, 75, 150),
  55. (0, 100, 200), (0, 125, 255), (100, 0, 100), (150, 0, 150),
  56. (200, 0, 200), (255, 0, 255)
  57. ]
  58. def handle_json(jsonfile):
  59. print('hand json {}'.format(jsonfile))
  60. with open(jsonfile, 'r') as f:
  61. data = json.load(f)
  62. # 纯黑色背景
  63. img = cv2.imread('black.jpg')
  64. for d in data['people']:
  65. kpt = np.array(d['pose_keypoints_2d']).reshape((25, 3))
  66. for p in pose_pairs:
  67. pt1 = tuple(list(map(int, kpt[p[0], 0:2])))
  68. c1 = kpt[p[0], 2]
  69. pt2 = tuple(list(map(int, kpt[p[1], 0:2])))
  70. c2 = kpt[p[1], 2]
  71. print('== {}, {}, {}, {} =='.format(pt1, c1, pt2, c2))
  72. if c1 == 0.0 or c2 == 0.0:
  73. continue
  74. color = tuple(list(map(int, pose_colors[p[0]])))
  75. img = cv2.line(img, pt1, pt2, color, thickness=4)
  76. img = cv2.circle(img, pt1, 4, color, thickness=-
  77. 1, lineType=8, shift=0)
  78. img = cv2.circle(img, pt2, 4, color, thickness=-
  79. 1, lineType=8, shift=0)
  80. kpt_left_hand = np.array(d['hand_left_keypoints_2d']).reshape((21, 3))
  81. for q in hand_pairs:
  82. pt1 = tuple(list(map(int, kpt_left_hand[q[0], 0:2])))
  83. c1 = kpt_left_hand[p[0], 2]
  84. pt2 = tuple(list(map(int, kpt_left_hand[q[1], 0:2])))
  85. c2 = kpt_left_hand[q[1], 2]
  86. # print('** {}, {}, {}, {} **'.format(pt1, c1, pt2, c2))
  87. if c1 == 0.0 or c2 == 0.0:
  88. continue
  89. color = tuple(list(map(int, hand_colors[q[0]])))
  90. img = cv2.line(img, pt1, pt2, color, thickness=4)
  91. kpt_right_hand = np.array(
  92. d['hand_right_keypoints_2d']).reshape((21, 3))
  93. for k in hand_pairs:
  94. pt1 = tuple(list(map(int, kpt_right_hand[k[0], 0:2])))
  95. c1 = kpt_right_hand[k[0], 2]
  96. pt2 = tuple(list(map(int, kpt_right_hand[k[1], 0:2])))
  97. c2 = kpt_right_hand[k[1], 2]
  98. print('** {}, {}, {}, {} **'.format(pt1, c1, pt2, c2))
  99. if c1 == 0.0 or c2 == 0.0:
  100. continue
  101. color = tuple(list(map(int, hand_colors[q[0]])))
  102. img = cv2.line(img, pt1, pt2, color, thickness=4)
  103. if not os.path.exists('results'):
  104. os.makedirs('results')
  105. # 保存图片
  106. cv2.imwrite('results/{}.jpg'.format(jsonfile.split("\\")[-1][0:-5]), img)
  107. if __name__ == '__main__':
  108. parser = argparse.ArgumentParser()
  109. parser.add_argument('--directory', type=str,
  110. default='.', help='keypoints json directory')
  111. opt = parser.parse_args()
  112. for jsonfile in os.listdir(opt.directory):
  113. if jsonfile.endswith('.json'):
  114. handle_json(os.path.join(opt.directory, jsonfile))

最后执行代码

  1. # jsons是存放json文件的目录
  2. python.exe main.py --directory jsons

在结果文件夹 results 就会生成对应的图像了

openpose json

参考资料

喜欢 (1)

您必须 登录 才能发表评论!