openpose重绘json里的骨骼信息

环境

  • windows 10 64 bit

  • opencv 4.5.3

需求

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

解决步骤

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

c93cb0998b4c926f1aa74ce7f27cbe17.png

openpose json

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

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

486c9ba2ce4685887b838ae968995325.png

openpose json

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

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

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

04764210f28b9aa0467afa2b4318dfd5.png

openpose json

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

2f2004135b280345750163b22b02eeb7.png

openpose json

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

import argparse
import json
import os

import cv2
import numpy as np

# 骨骼关键点连接对
pose_pairs = [
    [0, 1], [0, 15], [0, 16],
    [15, 17],
    [16, 18],
    [1, 2], [1, 5], [1, 8],
    [2, 3],
    [3, 4],
    [5, 6],
    [6, 7],
    [8, 9], [8, 12],
    [9, 10],
    [10, 11],
    [11, 22], [11, 24],
    [22, 23],
    [12, 13],
    [13, 14],
    [14, 21], [14, 19],
    [19, 20]
]

# 手部关键点连接对
hand_pairs = [
    [0, 1], [0, 5], [0, 9], [0, 13], [0, 17],
    [1, 2],
    [2, 3],
    [3, 4],
    [5, 6], [6, 7], [7, 8],
    [9, 10], [10, 11], [11, 12],
    [13, 14], [14, 15], [15, 16],
    [17, 18], [18, 19], [19, 20]
]

# 绘制用的颜色
pose_colors = [
    (255., 0., 85.), (255., 0., 0.), (255., 85., 0.), (255., 170., 0.),
    (255., 255., 0.), (170., 255., 0.), (85., 255., 0.), (0., 255., 0.),
    (255., 0., 0.), (0., 255., 85.), (0., 255., 170.), (0., 255., 255.),
    (0., 170., 255.), (0., 85., 255.), (0., 0., 255.), (255., 0., 170.),
    (170., 0., 255.), (255., 0., 255.), (85., 0., 255.), (0., 0., 255.),
    (0., 0., 255.), (0., 0., 255.), (0., 255.,
                                     255.), (0., 255., 255.), (0., 255., 255.)
]

hand_colors = [
    (100., 100., 100.),
    (100, 0, 0),
    (150, 0, 0),
    (200, 0, 0), (255, 0, 0), (100, 100, 0), (150,
                                              150, 0), (200, 200, 0), (255, 255, 0),
    (0, 100, 50), (0, 150, 75), (0, 200, 100), (0,
                                                255, 125), (0, 50, 100), (0, 75, 150),
    (0, 100, 200), (0, 125, 255), (100, 0, 100), (150, 0, 150),
    (200, 0, 200), (255, 0, 255)
]


def handle_json(jsonfile):

    print('hand json {}'.format(jsonfile))

    with open(jsonfile, 'r') as f:
        data = json.load(f)

    # 纯黑色背景
    img = cv2.imread('black.jpg')

    for d in data['people']:
        kpt = np.array(d['pose_keypoints_2d']).reshape((25, 3))
        for p in pose_pairs:
            pt1 = tuple(list(map(int, kpt[p[0], 0:2])))
            c1 = kpt[p[0], 2]
            pt2 = tuple(list(map(int, kpt[p[1], 0:2])))
            c2 = kpt[p[1], 2]

            print('== {}, {}, {}, {} =='.format(pt1, c1, pt2, c2))

            if c1 == 0.0 or c2 == 0.0:
                continue

            color = tuple(list(map(int, pose_colors[p[0]])))
            img = cv2.line(img, pt1, pt2, color, thickness=4)
            img = cv2.circle(img, pt1, 4, color, thickness=-
                             1, lineType=8, shift=0)
            img = cv2.circle(img, pt2, 4, color, thickness=-
                             1, lineType=8, shift=0)

        kpt_left_hand = np.array(d['hand_left_keypoints_2d']).reshape((21, 3))
        for q in hand_pairs:
            pt1 = tuple(list(map(int, kpt_left_hand[q[0], 0:2])))
            c1 = kpt_left_hand[p[0], 2]
            pt2 = tuple(list(map(int, kpt_left_hand[q[1], 0:2])))
            c2 = kpt_left_hand[q[1], 2]

            # print('** {}, {}, {}, {} **'.format(pt1, c1, pt2, c2))

            if c1 == 0.0 or c2 == 0.0:
                continue

            color = tuple(list(map(int, hand_colors[q[0]])))
            img = cv2.line(img, pt1, pt2, color, thickness=4)

        kpt_right_hand = np.array(
            d['hand_right_keypoints_2d']).reshape((21, 3))
        for k in hand_pairs:
            pt1 = tuple(list(map(int, kpt_right_hand[k[0], 0:2])))
            c1 = kpt_right_hand[k[0], 2]
            pt2 = tuple(list(map(int, kpt_right_hand[k[1], 0:2])))
            c2 = kpt_right_hand[k[1], 2]

            print('** {}, {}, {}, {} **'.format(pt1, c1, pt2, c2))

            if c1 == 0.0 or c2 == 0.0:
                continue

            color = tuple(list(map(int, hand_colors[q[0]])))
            img = cv2.line(img, pt1, pt2, color, thickness=4)

    if not os.path.exists('results'):
        os.makedirs('results')

    # 保存图片
    cv2.imwrite('results/{}.jpg'.format(jsonfile.split("\\")[-1][0:-5]), img)


if __name__ == '__main__':

    parser = argparse.ArgumentParser()
    parser.add_argument('--directory', type=str,
                        default='.', help='keypoints json directory')
    opt = parser.parse_args()

    for jsonfile in os.listdir(opt.directory):
        if jsonfile.endswith('.json'):
            handle_json(os.path.join(opt.directory, jsonfile))

最后执行代码

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

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

db07f67614f608f9348cc0e58e10b7ff.png

openpose json

参考资料

  • https://xugaoxiang.com/2021/05/29/build-openpose-for-windows-python-api/

  • https://xugaoxiang.com/2021/05/30/openpose-angle/

  • https://xugaoxiang.com/2020/10/26/openpose-build/

知识星球

新开的知识星球,目标每日更新。分享各种学习资源、实战项目、付费项目、私活分享、资源对接、行业资讯等,欢迎扫码加入,一起学习,一起进步。

6d05f0e7daebce9fa07886475e322fb0.png

【资源说明】 基于Openpose的轻量化版本的骨骼点生成器python源码+项目使用说明+模型.zip (1) 环境配置 torch>=0.4.1 torchvision>=0.2.1 pycocotools==2.0.0 opencv-python>=3.4.0.14 numpy>=1.14.0 本项目采用了训练好的模型参数: 参数下载链接: https://download.01.org/opencv/openvino_training_extensions/models/human_pose_estimation/checkpoint_iter_370000.pth 若想要把.pth权重文件转化成onnx格式的权重文件,请在终端运行onnx.py文件 python onnx.py .pth权重文件地址 (2) 运行项目 把测试视频文件放入video文件夹中,终端运行命令: python main.py 即可 如若使用其他文件夹的视频文件,终端执行命令:python main.py --video 视频数据路径 若想使用默认摄像头进行实时动作捕捉,终端执行命令:python main.py --video=0 (3) 添加了计算“人体18个骨骼点”之间的向量角功能 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迷途小书童的Note

请博主喝矿泉书!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值