我目前正在开发一种行为系统,它将利用移动条,旋转条,交替场,甚至是小型随机移动物体。最初所有这些都是在matlab中编写的,效果很好。但是由于与最终将使用代码的硬件不兼容,该项目已经转移到python。
我已经开始使用python中的matplotlib模块对系统进行编程,但效果很好。我利用matplotlib中的动画功能来生成快速移动物体的一致且流畅的运动。然而,当我深入研究使用matplotlib编程时,我注意到了一些问题。特别值得注意的是,物体的流体运动并不像以前认为的那样流畅。
由于我将使用opencv作为行为系统的另一部分,我想知道opencv是否比matplotlib有任何特别的优势,特别是在绘制速率和动画方面。
我将在下面详细介绍。
以下是构建动画的脚本的一部分,注意这个版本崩溃了,我还没弄清楚原因。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.animation as animation
import time
fig = plt.figure()
ax = fig.add_subplot(111)
fig.patch.set_facecolor([0,0,0])
fig.tight_layout()
plt.xlim(-100, 100)
plt.ylim(-100, 100)
plt.axis('off')
# List of variables
width = 1
bars = 20
spacing = 20
step = .01
direction = -1
RB = [] # Establish RB as a Python list
for a in range(bars):
RB.append(patches.Rectangle((a*spacing-200,-100), width, 200,
color=[1,0,0], alpha=0.50))
def init():
for a in range(bars):
ax.add_patch(RB[a])
return RB
def animate(i):
for i in range(bars):
temp = np.array(RB[i].get_xy())
if temp[0] > 200:
temp[0] = -199
elif temp[0] < -200:
temp[0] = 199
else:
temp[0] = temp[0] + step*direction;
RB[i].set_xy(temp)
return RB
t = time.time()
plt.show()
while t < timewidow
anim = animation.FuncAnimation(fig, animate,
init_func=init,
frames=30,
interval=1,
blit=True)
fig.clf()
有效的代码就在这里。它只是每个单独的对象不会彼此同步移动。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.animation as animation
import time
fig = plt.figure()
ax = fig.add_subplot(111)
fig.patch.set_facecolor([0,0,0])
fig.tight_layout()
plt.xlim(-100, 100)
plt.ylim(-100, 100)
plt.axis('off')
# List of variables
width = 1
bars = 20
spacing = 20
step = .01
direction = -1
RB = [] # Establish RB as a Python list
for a in range(bars):
RB.append(patches.Rectangle((a*spacing-200,-100), width, 200,
color=[1,0,0], alpha=0.50))
def init():
for a in range(bars):
ax.add_patch(RB[a])
return RB
def animate(i):
for i in range(bars):
temp = np.array(RB[i].get_xy())
if temp[0] > 200:
temp[0] = -199
elif temp[0] < -200:
temp[0] = 199
else:
temp[0] = temp[0] + step*direction;
RB[i].set_xy(temp)
return RB
anim = animation.FuncAnimation(fig, animate,
init_func=init,
frames=30,
interval=1,
blit=True)
plt.show()
答案 0 :(得分:3)
在while循环中做一个动画似乎很奇怪。因此,走的路绝对是第二个代码版本。
动画似乎不同步的原因实际上与重绘或类似的时间无关。它更像是插值的效果。矩形的宽度和位置需要舍入到屏幕像素。根据时间步长,矩形位置因此可以偏离一个像素;另外,条的宽度可以偏离2个像素(每侧加/减1)。这会导致不受欢迎的动画。
要解决此问题,您需要以像素为单位进行思考。确保轴范围是整数并等于屏幕上的像素数。然后使条形宽度为一个像素的倍数。使用interval
参数FuncAnimation
来控制动画的速度,而不是步骤。使用恰好一个像素作为步长。
一个完整的例子:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.animation as animation
fig = plt.figure(figsize=(5,3), dpi=100) #figure is 500 pixels wide
ax = fig.add_subplot(111)
fig.patch.set_facecolor([0,0,0])
fig.subplots_adjust(left=.04, right=1-.04) #axes is now 460 pixels wide
plt.xlim(-230, 230) # distribute 460 pixels over x range
plt.ylim(-100, 100)
plt.axis('off')
# List of variables
width = 4
spacing = 20
bars = int(460/spacing) # make sure bars fit into range
direction = -1
RB = [] # Establish RB as a Python list
for a in range(bars):
RB.append(patches.Rectangle((a*spacing-230,-100), width, 200,
color=[1,0,0], alpha=0.50))
def init():
for a in range(bars):
ax.add_patch(RB[a])
return RB
def animate(i):
for j in range(bars):
temp = np.array(RB[j].get_xy())
if temp[0] >= 230: #### use >= instead of > to mimic exactly one step
temp[0] = -229
elif temp[0] <= -230:
temp[0] = 229
else:
temp[0] = temp[0] + direction # each step should be one pixel
RB[j].set_xy(temp)
return RB
anim = animation.FuncAnimation(fig, animate,
init_func=init,
frames=20,
interval=10, # control speed with thie interval
blit=True)
plt.show()