You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python基于手部关键点数组值绘制各关键点频谱图

实现结论

完全可以基于Python实现手部关键点数组的多频谱整合展示,用常规科学计算栈就可以完成,不需要特殊定制工具。

依赖安装

先装好需要的库,执行以下命令即可:
pip install numpy matplotlib scipy
各库作用:

  • numpy:做快速傅里叶变换,计算频谱核心数据
  • matplotlib:完成多子图/单图多曲线的频谱渲染、布局调整
  • scipy:可选,用来做关键点序列的去噪、加窗预处理,解决关键点抖动带来的频谱杂波问题
分步实现指引

1. 数据格式整理

先把你从姿态模型拿到的关键点数组规整成标准结构:

  • 最终数组形状建议为 (总采样帧数, 关键点总数, 坐标维度数),坐标维度一般是2(平面x/y坐标)或3(空间x/y/z坐标)
  • 单独提取每个关键点对应维度的一维时序序列即可用于频谱计算,比如要分析所有关键点x方向的运动频谱,就取所有帧对应关键点的x值组成长度等于总帧数的一维数组。
  • 可选预处理:如果关键点序列存在检测抖动、跳变,先用滑动平均做平滑;计算频谱前给序列加汉明窗,减少傅里叶变换的频谱泄漏问题。

2. 单关键点频谱计算

对每个关键点的一维时序序列,用快速傅里叶变换得到频率和对应振幅值,可直接复用以下工具函数:
注意不要直接使用全量FFT结果绘图,负频率部分是算法产生的共轭对称冗余数据,仅保留正频率段即可

import numpy as np

def get_spectrum(time_seq, sample_fps):
    """
    time_seq: 单个关键点的单维度时序数组
    sample_fps: 提取关键点时的源视频帧率,即采样频率
    返回: 频率轴数组、对应振幅数组
    """
    seq_len = len(time_seq)
    # 加汉明窗抑制频谱泄漏
    window = np.hamming(seq_len)
    fft_res = np.fft.fft(time_seq * window)
    # 截取正频率部分
    freq_axis = np.fft.fftfreq(seq_len, d=1/sample_fps)[:seq_len//2]
    amplitude = 2.0 / seq_len * np.abs(fft_res[:seq_len//2])
    return freq_axis, amplitude

3. 多频谱整合展示

根据需要的效果选对应布局即可:

网格分图布局(单关键点单独小图展示)

按手部关键点的排布逻辑做网格子图,每个子图画对应关键点的频谱,示例代码如下(以常规21个手部关键点为例,排7行3列网格):

import matplotlib.pyplot as plt

# 配置参数
SAMPLE_FPS = 30 # 替换成你自己的视频帧率
KEYPOINT_NUM = 21 # 替换成你自己的关键点总数
# 这里替换成你自己规整好的关键点数组
# kp_seq形状: (总帧数, KEYPOINT_NUM, 坐标维度)
kp_seq = np.load("your_hand_keypoints.npy") 

# 建7行3列的子图网格,共享xy轴刻度避免重复标注
fig, axes = plt.subplots(nrows=7, ncols=3, figsize=(12, 16), sharex=True, sharey=True)
axes = axes.flatten()

for kp_id in range(KEYPOINT_NUM):
    # 示例取x维度序列,要分析y/z维度就改最后一维的索引
    single_seq = kp_seq[:, kp_id, 0]
    freq, amp = get_spectrum(single_seq, SAMPLE_FPS)
    current_ax = axes[kp_id]
    current_ax.plot(freq, amp, linewidth=0.8)
    current_ax.set_title(f"关键点 {kp_id}", fontsize=9)
    current_ax.grid(alpha=0.3)

# 加整图公共标签
fig.supxlabel("频率 (Hz)")
fig.supylabel("振幅")
plt.tight_layout()
plt.show()

单轴堆叠布局(所有频谱同图展示)

不需要建多子图,在同一个坐标轴上循环绘制所有关键点的频谱曲线,用不同颜色区分、加图例即可,核心逻辑:

fig, ax = plt.subplots(figsize=(12, 6))
for kp_id in range(KEYPOINT_NUM):
    single_seq = kp_seq[:, kp_id, 0]
    freq, amp = get_spectrum(single_seq, SAMPLE_FPS)
    ax.plot(freq, amp, label=f"关键点{kp_id}", linewidth=1)
ax.set_xlabel("频率 (Hz)")
ax.set_ylabel("振幅")
ax.legend(ncol=3, fontsize=8)
ax.grid(alpha=0.3)
plt.tight_layout()
plt.show()
效果优化技巧
  • 按手部生理分组给曲线配色:比如拇指、食指、中指、无名指、小指、掌根组分别用不同色系,辨识度更高
  • 如果不同关键点的振幅差异过大,可对每个关键点的振幅做0-1归一化,避免大振幅曲线压缩小振幅曲线的展示空间
  • 如果需要动态实时展示频谱,可接入matplotlib.animation.FuncAnimation,每次取固定长度的滑动窗口序列计算频谱更新图表即可

内容的提问来源于stack exchange,提问作者blake banker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 22:33:01