我正在尝试使用Opencv的密集光流功能的输出来绘制运动矢量的箭头图,但是却无法找到函数实际输出的内容。这是代码:
import cv2
import numpy as np
cap = cv2.VideoCapture('GOPR1745.avi')
ret, frame1 = cap.read()
prvs = cv2.cvtColor(frame1,cv2.COLOR_BGR2GRAY)
hsv = np.zeros_like(frame1)
hsv[...,1] = 255
count=0
while(1):
ret, frame2 = cap.read()
next = cv2.cvtColor(frame2,cv2.COLOR_BGR2GRAY)
flow = cv2.calcOpticalFlowFarneback(prvs,next,None, 0.5, 3, 15, 3, 10, 1.2, 0)
mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1])
hsv[...,0] = ang*180/np.pi/2
hsv[...,2] = cv2.normalize(mag,None,0,255,cv2.NORM_MINMAX)
rgb = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR)
if count==10:
count=0
print "flow",flow
cv2.imshow('frame2',rgb)
count=count+1
k = cv2.waitKey(30) & 0xff
if k == 27:
break
elif k == ord('s'):
prvs = next
cap.release()
cv2.destroyAllWindows()
这实际上与OpenCv教程中关于密集光流的代码相同。我从print函数收到以下输出:
flow [[[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
...,
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]]
...,
[[ -3.54891084e-14 -1.38642463e-14]
[ -2.58058853e-14 -1.54020863e-14]
[ -5.56561768e-14 -1.88019359e-14]
...,
[ -7.59403916e-15 1.16633225e-13]
[ 7.22156371e-14 -1.61951507e-13]
[ -4.30715618e-15 -4.39530987e-14]]
[[ -3.54891084e-14 -1.38642463e-14]
[ -2.58058853e-14 -1.54020863e-14]
[ -5.56561768e-14 -1.88019359e-14]
...,
[ -7.59403916e-15 1.16633225e-13]
[ 7.22156371e-14 -1.61951507e-13]
[ -4.30715618e-15 -4.39530987e-14]]
我想知道这些值到底是什么?原始的X,Y坐标?最终的X,Y坐标?距离感动了?
我计划尝试使用以下页面中的代码找到初始和最终坐标以制作箭袋图: https://www.getdatajoy.com/examples/python-plots/vector-fields 这是因为在python中没有我知道的函数可以为你绘制光流图。
提前谢谢!
答案 0 :(得分:10)
你快到了。让我们首先看一下它所说的calcOpticalFlowFarneback Documentation:
flow
- 计算出的流量图像与prev
具有相同的尺寸并输入CV_32FC2
。
所以你实际获得的是一个与输入框架大小相同的矩阵
flow
矩阵中的每个元素都是一个点,表示prev
帧中该像素的位移。这意味着你得到一个带有x和y值的点(以像素为单位),它给出了最后一帧的delta x和delta y。
答案 1 :(得分:0)
我要劫持这个,因为它是同一个主题。
如果单位是@shravya 所述的像素,为什么此代码不显示等于 1 的最大流量?
我真的不明白单位
import numpy as np
import cv2
import seaborn as sns
# Generating img
img = np.zeros(shape=(3,50,50)) # 3 time frames, 50x50
center0 = np.array((10,10))
center1 = np.array((30,30))
for each_time, each_x, each_y in itertools.product(range(img.shape[0]), range(img.shape[1]), range(img.shape[2])):
img[each_time, each_x, each_y] = img[each_time, each_x, each_y] + 1000 * 1/( 0.1* ((center0[0]+each_time*displacement_x - each_x)**2 + 1*(center0[1]+each_time*displacement_y - each_y)**2)**0.5 + 1)
img[each_time, each_x, each_y] = img[each_time, each_x, each_y] + 1000 * 1/( 0.1* ((center1[0]+each_time*displacement_x - each_x)**2 + 1*(center1[1]+each_time*displacement_y - each_y)**2)**0.5 + 1)
img = (img - img.min())/(img.max()-img.min()) # Normalizing
## Ploting
fig, axs = plt.subplots(ncols=3, squeeze=True, figsize=(20,5))
for i in range(3):
im = sns.heatmap(img[i,:,:], ax = axs[i], vmin=0, vmax=np.max(img))
fig.suptitle('Image')
def calc_flow(img):
## Optical flow
img = img.astype(np.int16)
prev = np.zeros(img[0, :, :].shape).astype(np.int16)
flows = np.zeros(shape=(img.shape[0], img.shape[1], img.shape[2], 2))
for i, each_frame in enumerate(img):
if i > img.shape[0]:
break
next_ = each_frame
flow = cv2.calcOpticalFlowFarneback(prev, next_, None,
pyr_scale = 0.5,
levels = 3,
winsize = 12,
iterations = 5,
poly_n = 5,
poly_sigma = 1.2,
flags = 0)
flows[i, :, :, 0] = flow[..., 0]
flows[i, :, :, 1] = flow[..., 1]
prev = next_
return flows
flow = calc_flow(img)
fig, axs = plt.subplots(ncols=3, nrows=2, squeeze=True, figsize=(20,10))
for i in range(3):
im = sns.heatmap(flow[i,:,:, 0] ,ax = axs[0,i], vmin=0, vmax = np.max(flow))
im = sns.heatmap(flow[i,:,:, 1] ,ax = axs[1,i], vmin=0, vmax = np.max(flow))
fig.suptitle('Flow x and y plots')
mag_img, pha_img = cv2.cartToPolar(flow[..., 0], flow[..., 1])
fig, axs = plt.subplots(ncols=3, nrows=2, squeeze=True, figsize=(20,10))
for i in range(3):
im = sns.heatmap(mag_img[i,:,:], ax=axs[0,i], vmin=0, vmax = np.max(mag_img))
im = sns.heatmap(pha_img[i,:,:], ax=axs[1,i], vmin=0, vmax = np.max(pha_img))
fig.suptitle('Magnitude and phase plots')
## Output
print(flow.max()) # This should be equal to displacement!
print(np.abs(flow).min()) # this should be zero
print(mag_img.max()) # This should be equal to displacement!
print(mag_img.min()) # this should be zero