AiwassD 2024-03-13 23:38 采纳率: 50%
浏览 33
已结题

PYSKL工具的Vis3DPose出现报错,如何解决?

正在学习使用pytorch基于骨骼关键点的数据进行动作识别,想要把3D的骨骼点可视化,PYSKL工具的Vis3DPose出现报错:

ax.lines = []
AttributeError: can't set attribute

Vis3DPose的代码如下:

import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
from matplotlib.animation import FuncAnimation

def Vis3DPose(item, layout='nturgb+d', fps=12, angle=(30, 45), fig_size=(8, 8), with_grid=False):
    kp = item['keypoint'].copy()
    colors = ('#3498db', '#000000', '#e74c3c')  # l, m, r

    assert layout == 'nturgb+d'
    if layout == 'nturgb+d':
        num_joint = 25
        kinematic_tree = [
            [1, 2, 21, 3, 4],
            [21, 9, 10, 11, 12, 25], [12, 24],
            [21, 5, 6, 7, 8, 23], [8, 22],
            [1, 17, 18, 19, 20],
            [1, 13, 14, 15, 16]
        ]
        kinematic_tree = [[x - 1 for x in lst] for lst in kinematic_tree]
        colors = ['black', 'blue', 'blue', 'red', 'red', 'darkblue', 'darkred']

    assert len(kp.shape) == 4 and kp.shape[3] == 3 and kp.shape[2] == num_joint
    x, y, z = kp[..., 0], kp[..., 1], kp[..., 2]
    min_x, max_x = min(x[x != 0]), max(x[x != 0])
    min_y, max_y = min(y[y != 0]), max(y[y != 0])
    min_z, max_z = min(z[z != 0]), max(z[z != 0])

    max_axis = max(max_x - min_x, max_y - min_y, max_z - min_z)
    mid_x, mid_y, mid_z = (min_x + max_x) / 2, (min_y + max_y) / 2, (min_z + max_z) / 2

    min_x, max_x = mid_x - max_axis / 2, mid_x + max_axis / 2
    min_y, max_y = mid_y - max_axis / 2, mid_y + max_axis / 2
    min_z, max_z = mid_z - max_axis / 2, mid_z + max_axis / 2

    fig = plt.figure(figsize=fig_size)
    #plt.show()
    ax = p3.Axes3D(fig)
    ax.set_xlim3d([min_x, max_x])
    ax.set_ylim3d([min_y, max_y])
    ax.set_zlim3d([min_z, max_z])
    ax.view_init(*angle)
    fig.suptitle(item.get('frame_dir', 'demo'), fontsize=20)
    save_path = item.get('frame_dir', 'tmp').split('/')[-1] + '.mp4'

    def update(t):
        ax.lines = []
        ax.view_init(*angle)
        for i, (chain, color) in enumerate(zip(kinematic_tree, colors)):
            linewidth = 2.0
            for j in range(kp.shape[0]):
                ax.plot3D(kp[j, t, chain, 0], kp[j, t, chain, 1], kp[j, t, chain, 2], linewidth=linewidth, color=color)
        if not with_grid:
            plt.axis('off')
            ax.set_xticklabels([])
            ax.set_yticklabels([])
            ax.set_zticklabels([])
    ani = FuncAnimation(fig, update, frames=kp.shape[1], interval=0, repeat=False)
    ani.save(save_path, fps=fps)
    plt.close()
    video = mpy.VideoFileClip(save_path)
    return video

使用Vis3DPose的代码如下:

import glob
from pyskl.smp import *
from pyskl.utils.visualize import Vis3DPose, Vis2DPose
from mmcv import load, dump
from pyskl.datasets.pipelines import PreNormalize3D
download_file('http://download.openmmlab.com/mmaction/pyskl/demo/annotations/ntu60_samples_hrnet.pkl', 'ntu60_2d.pkl')
download_file('http://download.openmmlab.com/mmaction/pyskl/demo/annotations/ntu60_samples_3danno.pkl', 'ntu60_3d.pkl')
annotations = load('ntu60_3d.pkl')
index = 0
anno = annotations[index]
anno = PreNormalize3D()(anno)
vid = Vis3DPose(anno, layout='nturgb+d', fps=12, angle=(30, 45), fig_size=(8, 8), with_grid=False)
vid.ipython_display()

查了matplotlib的官方文档,没找到原因……
环境如下:

python==3.8

  • addict 2.4.0
    anyio 4.3.0
    argon2-cffi 23.1.0
    argon2-cffi-bindings 21.2.0
    arrow 1.3.0
    asttokens 2.4.1
    async-lru 2.0.4
    attrs 23.2.0
    Babel 2.14.0
    backcall 0.2.0
    beautifulsoup4 4.12.3
    bleach 6.1.0
    certifi 2024.2.2
    cffi 1.16.0
    chardet 4.0.0
    charset-normalizer 3.3.2
    chumpy 0.70
    colorama 0.4.6
    comm 0.2.1
    contourpy 1.1.1
    cycler 0.12.1
    Cython 3.0.9
    d2l 1.0.3
    debugpy 1.8.1
    decorator 4.4.2
    decord 0.6.0
    defusedxml 0.7.1
    exceptiongroup 1.2.0
    executing 2.0.1
    fastjsonschema 2.19.1
    ffmpeg 1.4
    filelock 3.13.1
    fonttools 4.49.0
    fqdn 1.5.1
    fsspec 2024.2.0
    fvcore 0.1.5.post20221221
    h11 0.14.0
    httpcore 1.0.4
    httpx 0.27.0
    idna 2.10
    imageio 2.34.0
    imageio-ffmpeg 0.4.9
    importlib_metadata 7.0.2
    importlib_resources 6.1.3
    iopath 0.1.10
    ipykernel 6.29.3
    ipython 8.12.3
    ipywidgets 8.1.2
    isoduration 20.11.0
    jedi 0.19.1
    Jinja2 3.1.3
    json-tricks 3.17.3
    json5 0.9.22
    jsonpointer 2.4
    jsonschema 4.21.1
    jsonschema-specifications 2023.12.1
    jupyter 1.0.0
    jupyter_client 8.6.0
    jupyter-console 6.6.3
    jupyter_core 5.7.1
    jupyter-events 0.9.0
    jupyter-lsp 2.2.4
    jupyter_server 2.13.0
    jupyter_server_terminals 0.5.2
    jupyterlab 4.1.4
    jupyterlab_pygments 0.3.0
    jupyterlab_server 2.25.3
    jupyterlab_widgets 3.0.10
    kiwisolver 1.4.5
    MarkupSafe 2.1.5
    matplotlib 3.7.2
    matplotlib-inline 0.1.6
    mistune 3.0.2
    mmcv-full 1.5.0
    mmdet 2.23.0
    mmpose 0.24.0
    moviepy 1.0.3
    mpmath 1.3.0
    munkres 1.1.4
    nbclient 0.9.0
    nbconvert 7.16.2
    nbformat 5.9.2
    nest-asyncio 1.6.0
    networkx 3.1
    notebook 7.1.1
    notebook_shim 0.2.4
    numpy 1.23.5
    opencv-contrib-python 4.9.0.80
    opencv-python 4.9.0.80
    overrides 7.7.0
    packaging 24.0
    pandas 2.0.3
    pandocfilters 1.5.1
    parso 0.8.3
    pickleshare 0.7.5
    pillow 10.2.0
    pip 23.3.1
    pkgutil_resolve_name 1.3.10
    platformdirs 4.2.0
    portalocker 2.8.2
    proglog 0.1.10
    prometheus_client 0.20.0
    prompt-toolkit 3.0.43
    psutil 5.9.8
    pure-eval 0.2.2
    pycocotools 2.0.7
    pycparser 2.21
    Pygments 2.17.2
    pymemcache 4.0.0
    pyparsing 3.0.9
    pyskl 0.1.0 d:\learn\PYSKL\pyskl_main
    python-dateutil 2.9.0.post0
    python-json-logger 2.0.7
    pytz 2024.1
    pywin32 306
    pywinpty 2.0.13
    PyYAML 6.0.1
    pyzmq 25.1.2
    qtconsole 5.5.1
    QtPy 2.4.1
    referencing 0.33.0
    regex 2023.12.25
    requests 2.31.0
    rfc3339-validator 0.1.4
    rfc3986-validator 0.1.1
    rpds-py 0.18.0
    scipy 1.10.1
    Send2Trash 1.8.2
    setuptools 68.2.2
    six 1.16.0
    sniffio 1.3.1
    soupsieve 2.5
    stack-data 0.6.3
    sympy 1.12
    tabulate 0.9.0
    termcolor 2.4.0
    terminado 0.18.0
    terminaltables 3.1.10
    tinycss2 1.2.1
    tomli 2.0.1
    torch 2.2.1
    torchvision 0.17.1
    tornado 6.4
    tqdm 4.66.2
    traitlets 5.14.1
    types-python-dateutil 2.8.19.20240311
    typing_extensions 4.10.0
    tzdata 2024.1
    uri-template 1.3.0
    urllib3 2.2.1
    wcwidth 0.2.13
    webcolors 1.13
    webencodings 0.5.1
    websocket-client 1.7.0
    wheel 0.41.2
    widgetsnbextension 4.0.10
    xtcocotools 1.14.3
    yacs 0.1.8
    yapf 0.40.2
    zipp 3.17.0

配置过程基本是按照PYSKL的官网说明进行的,不知如何修改才能正常可视化3d骨骼

  • 写回答

22条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-03-13 23:39
    关注
    获得0.60元问题酬金

    引自免费微信小程序:皆我百晓生

    在上述代码中,问题出在尝试直接通过 ax.lines = [] 清空3D坐标系中的线条。在matplotlib的3D axes (mpl_toolkits.mplot3d.axes3d.Axes3D) 中,无法直接通过这种方式清空已经绘制的线条。

    要解决这个问题,你可以采用以下方法来清除上一帧的线条:

    def update(t):
        # 清除上一帧的所有线条
        for line in ax.lines:
            line.remove()
    
        ax.view_init(*angle)
        for i, (chain, color) in enumerate(zip(kinematic_tree, colors)):
            linewidth = 2.0
            for j in range(kp.shape[0]):
                new_line = ax.plot3D(kp[j, t, chain, 0], kp[j, t, chain, 1], kp[j, t, chain, 2], linewidth=linewidth, color=color)[0]
                # 将新绘制的线条保存以便于后续清除
                ax.lines.append(new_line)
    
        if not with_grid:
            plt.axis('off')
            ax.set_xticklabels([])
            ax.set_yticklabels([])
            ax.set_zticklabels([])
    

    这样,在每次更新动画帧时都会先移除之前绘制的所有线条,然后再绘制当前帧的骨骼点连线,从而实现3D骨骼点的动态可视化。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 3月21日
  • 创建了问题 3月13日