Skip to content Skip to sidebar Skip to footer

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 as prev and type CV_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?"