What Is Output From Opencv's Dense Optical Flow (farneback) Function? How Can This Be Used To Build An Optical Flow Map In Python?
I am trying to use the output of Opencv's dense optical flow function to draw a quiver plot of the motion vectors but have not been able to find what the function actually outputs.
Solution 1:
You were almost there. Lets first take a look at the calcOpticalFlowFarneback Documentation it says there:
flow
– computed flow image that has the same size asprev
and typeCV_32FC2
.
So what you are actually getting is a matrix that has the same size as your input frame.
Each element in that flow
matrix is a point that represents the displacement of that pixel from the prev
frame. Meaning that you get a point with x and y values (in pixel units) that gives you the delta x and delta y from the last frame.
Solution 2:
I'm going to hijack this because it is the same topic.
If units are pixels as stated by @shravya, why this code does not show maximum flow equal to one?
I really dont get the units
Code
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 inrange(3):
im = sns.heatmap(img[i,:,:], ax = axs[i], vmin=0, vmax=np.max(img))
fig.suptitle('Image')
defcalc_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 inenumerate(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 inrange(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 inrange(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')
## Outputprint(flow.max()) # This should be equal to displacement!print(np.abs(flow).min()) # this should be zeroprint(mag_img.max()) # This should be equal to displacement!print(mag_img.min()) # this should be zero
Post a Comment for "What Is Output From Opencv's Dense Optical Flow (farneback) Function? How Can This Be Used To Build An Optical Flow Map In Python?"