下面的代码代表与n行文本文件读取相对应的图形绘制。每行包含4列,前三列是(x,y,z)点的坐标,而第四列是此绘图不必要的二进制变量。
每读取20行,就会读取一个骨架,该骨架是一组20个(x,y,z)点或关节,每个关节由每行的前三列组成。
文本文件包含860行,并且860/20 = 43,即要创建20个(x,y,z)关节骨架的关节数量。然后,该文本文件由43个骨骼组成,生成一个动作。因此,文本文件代表运动。
我在构建以逻辑方式将每个(x,y,z)点与其他点连接起来的边线时遇到了问题,因此点的绘制看起来像是骨架。一个循环,这样,每读取20行,就会生成一个骨架,并在按键事件发生后,假设向右箭头键,则会读取下20行并生成另一个骨架。
我是Python和Matplotlib的初学者。我在下面发布了Matploblit生成的没有边缘的骨架的图片,另一幅与我需要用边缘实现的结果相似的图片。
文本文件内容的示例:
1.3200000e+002 8.0000000e+001 6.8100000e+002 1.0000000e+000
1.6900000e+002 8.1000000e+001 6.6500000e+002 1.0000000e+000
1.4800000e+002 7.5000000e+001 6.5000000e+002 0.0000000e+000
1.5100000e+002 9.8000000e+001 6.9800000e+002 0.0000000e+000
1.3200000e+002 1.2000000e+002 6.7400000e+002 1.0000000e+000
1.6100000e+002 1.2200000e+002 6.6200000e+002 8.1730800e-001
此外,在绘制骨骼时,仅采用两个坐标(x,y)来生成2D骨骼,因此将忽略第三个坐标。并且,绘图已经在循环中,但是按键事件部分尚未实现,当关闭当前画布时,将绘制下一个骨架。
此外,您可能会注意到绘图正在生成前一个骨骼与下一个骨骼的重叠,我也张贴了重叠的图片,这是第一个骨骼之后生成的42个骨骼之一。
第一个绘制的无关节骨骼: https://i.stack.imgur.com/FNFTL.png
接下来的42个无关节绘制的骨骼中的一个出现了OVERLAP问题: https://i.stack.imgur.com/D8FQt.png
所需结果的一种方法: https://i.stack.imgur.com/PkWUc.png
from pylab import *
from matplotlib import gridspec
import numpy as np
import sys
import math
import matplotlib.pyplot as plt
movement = np.loadtxt("file01.txt")
number_of_postures = int(len(movement)/20)
listing = []
for i in range(number_of_postures):
listing.append(movement[(i*20):((i+1)*20),:3])
matrixCoord = np.array(listing)
num_plots = number_of_postures
z = 0
for m in range(num_plots):
gs = gridspec.GridSpec(1, 2, width_ratios=[3, 1]) # create figure at start of loop
z += 20
skeleton = movement[:z,:2]
x = skeleton[:,0]
y = -skeleton[:,1]
plt.subplot(gs[1])
plt.scatter(x,y, s=40)
plt.title('Skeleton')
plt.show()
答案 0 :(得分:1)
仅首先直接回答您的问题:
绘制关节之间的线:
首先创建“骨骼列表”,该列表包含构建骨骼线的所有关节对。可以从您张贴的带有枚举关节的图片中获得:
bone_list = [[1, 3], [2, 3], [3, 4], [4, 7], [5, 7], [6, 7], [1, 8], [2, 9], [8, 10], [9, 11], [10, 12], [11, 13], [5, 14], [6, 15], [14, 16], [15, 17], [16, 18], [17, 19], [3, 20]]
由于枚举从1
开始,而python索引从0
开始,请将列表转换为numpy数组,以轻松地将所有值减1:
bone_list = np.array(bone_list) - 1
准备好这一步后,您就可以在运动循环中画线,并为每条线(在plt.scatter(x, y, s=40)
之后)添加一个额外的循环:
for bone in bone_list:
plt.plot([x[bone[0]], x[bone[1]]], [y[bone[0]], y[bone[1]]], 'r')
,关于您的重叠问题:
这只是因为
skeleton = movement[:z, :2]
您总是从零开始切片,即在第一个循环(绘制一个骨骼)中为[0:20,:2],在第二个循环(绘制两个骨骼)中为[0:40,:2],依此类推。
更改为
skeleton = movement[z-20:z, :2] # or [z:z+20, :2] and do z+=20 afterwards
但是,如果我可以在您的脚本中添加一些常规提示:
进口太多(至少对于您发布的部分而言)
有重命名的变量已经存在
有未使用的变量
您不会在循环中使用迭代变量m
gridspec
用于在不均匀分布的网格中创建子图-您需要吗?
请记住,您想要的脚本可能如下所示:
import matplotlib.pyplot as plt
import numpy as np
movement = np.loadtxt("file01.txt")
bone_list = [[1, 3], [2, 3], [3, 4], [4, 7], [5, 7], [6, 7], [1, 8], [2, 9], [8, 10], [9, 11], [10, 12], [11, 13], [5, 14], [6, 15], [14, 16], [15, 17], [16, 18], [17, 19], [3, 20]]
bone_list = np.array(bone_list) - 1
number_of_postures = int(len(movement)/20)
for i in range(number_of_postures):
fig, ax = plt.subplots(1, figsize=(3, 8))
plt.title('Skeleton')
plt.xlim(100, 180)
plt.ylim(-250, 0)
skeleton = movement[i*20:(i+1)*20]
x = skeleton[:, 0]
y = -skeleton[:, 1]
sc = ax.scatter(x, y, s=40)
for bone in bone_list:
ax.plot([x[bone[0]], x[bone[1]]], [y[bone[0]], y[bone[1]]], 'r')