我用flow = cv2.calcOpticalFlowFarneback()来计算视频中的光流,它给了我一个形状为(高度,宽度,2)的numpy数组,其中包含每个像素(flow[:,:,0] = Fx和flow[:,:,1] = Fy)的Fx和Fy值.
为了计算散度,我使用了np.像这样的梯度:
def divergence_npgrad(flow):
Fx, Fy = flow[:, :, 0], flow[:, :, 1]
F = [Fx, Fy]
d = len(F)
return np.ufunc.reduce(np.add, [np.gradient(F[i], axis=i) for i in range(d)])
接下来,我想计算旋度.我知道在sympy.physics.vector中有一个旋度函数,但我真的不知道它是如何工作的,或者它如何应用于我的flow.所以我想我可以用np.这个也有梯度.在2D中,我需要计算每个像素的dFy/dx - dFx/dy,所以我会这样:
def curl_npgrad(flow):
Fx, Fy = flow[:, :, 0], flow[:, :, 1]
dFx_dy = np.gradient(Fx, axis=1)
dFy_dx = np.gradient(Fy, axis=0)
curl = np.ufunc.reduce(np.subtract, [dFy_dx, dFx_dy])
return curl
这是一种正确的方式还是我遗漏了什么?
如果我有curl,我想用matplotlib画两幅图.
以下是我试图使用的:
def flow_plot(flow, frame):
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
h, w = flow.shape[:2]
dpi = 72
xinch = w / dpi
yinch = h / dpi
step = 24
y, x = np.mgrid[step / ((h % step) // 2):h:step, step / ((w % step) // 2):w:step].reshape(2, -1).astype(int)
fx, fy = flow[y, x].T
mag = np.sqrt(np.power(fx, 2) + np.power(fy, 2))
fx = fx / mag
fy = fy / mag
curl = curl_npgrad(flow)
curl_map = curl[y, x]
quiver_params = dict(cmap='Oranges', # for magnitude
#cmap='seismic', # for curl
norm=colors.Normalize(vmin=0.0, vmax=1.0), # for magnitude
#norm = colors.CenteredNorm(), # for curl
units='xy',
scale=0.03,
headwidth=3,
headlength=5,
minshaft=1.5,
pivot='middle')
fig = plt.figure(figsize=(xinch, yinch), dpi=dpi)
plt.imshow(frame)
plt.quiver(x, y, fx, fy, mag, **quiver_params)
plt.gca().invert_yaxis()
plt.gca().set_aspect('equal', 'datalim')
plt.axis('off')
fig.tight_layout(pad=0)
fig.canvas.draw()
img = np.frombuffer(fig.canvas.tostring_rgb(), dtype='uint8')
img = img.reshape(fig.canvas.get_width_height()[::-1] + (3,))
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
img = cv2.flip(img, 0)
plt.close(fig)
return img
I'm converting the plot to a cv2 image so i can use it for opencv video writer.
我注意到,如果我没有显示绘图后面的原始帧,我必须反转y轴并在plt.quiver()中使用-fy,如果我想显示后面的帧,我也必须反转y轴,可以使用fy,但之后我必须翻转整个图像.这有什么意义?我搞不懂.
至于卷发,对我来说有点乱.几乎看不出任何 colored颜色 ,随机的红色和蓝色斑点,没有一个红色/蓝色箭头,流体在那里清晰地旋转.就像这样:
对于这种流动来说,计算旋度是一种糟糕的方法吗?我错过了什么?