Ask Your Question

# How to calculate Optical Flow magnitude?

I'm trying to see how big different two given video frames are. My goal is to calculate a single value showing how fast objects inside those frames are moving.

I can calculate Optical Flow matrix below, both the HSV and magnitude matrices. But I don't know how to calculate a average total movement magnitude. How can I calculate it from those matrices?

def optical_flow(one, two):
one_g = cv2.cvtColor(one, cv2.COLOR_RGB2GRAY)
two_g = cv2.cvtColor(two, cv2.COLOR_RGB2GRAY)
hsv = np.zeros((120, 320, 3))
# set saturation
hsv[:,:,1] = cv2.cvtColor(two, cv2.COLOR_RGB2HSV)[:,:,1]
# obtain dense optical flow paramters
flow = cv2.calcOpticalFlowFarneback(one_g, two_g, flow=None,
pyr_scale=0.5, levels=1, winsize=15,
iterations=2,
poly_n=5, poly_sigma=1.1, flags=0)
# convert from cartesian to polar
mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])
# hue corresponds to direction
hsv[:,:,0] = ang * (180/ np.pi / 2)
# value corresponds to magnitude
hsv[:,:,2] = cv2.normalize(mag,None,0,255,cv2.NORM_MINMAX)
# convert HSV to int32's
hsv = np.asarray(hsv, dtype= np.float32)
rgb_flow = cv2.cvtColor(hsv,cv2.COLOR_HSV2RGB)
return rgb_flow


The rgb_flow is a 3D array looks like this:

[[[0 0 0]
[0 0 0]
[0 0 0]
...
[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]
...
[0 0 0]
[0 0 0]
[0 0 0]]

...

[[0 0 0]
[0 0 0]
[0 0 0]
...
[0 0 0]
[0 0 0]
[0 0 0]]]


And the mag matrix is 2D array like this:

[[3.2825139e-03 3.9561605e-03 4.8938910e-03 ... 3.7310597e-02
3.2986153e-02 2.5520157e-02]
[4.9569397e-03 6.3276174e-03 7.7017904e-03 ... 3.9564677e-02
3.2582227e-02 2.6329078e-02]
...

[6.9548332e-06 8.3683852e-05 6.0906638e-03 ... 8.3484064e-04
6.4721738e-04 2.9505073e-04]]

edit retag close merge delete

## Comments

1

Yes, I did that. And then I average this over the whole shot frames. But the results are mehhh...Sometimes a more fast-moving scenes have less values than a more static ones.

if you think of it, it's the mean motion of a whole image, including all non-moving pixels (probably the majority)

so, the mean of the magnitude of the flow does not deliver, what you want, but what do you want ?

how fast objects inside those frames are moving.

can you explain ? what do you need it for ? do you need movement directions ? why the optflow ?

I'm trying to see how big different two given video frames are.

maybe much simpler measures like psnr would do better ?

1

No, my final aim is differentiate fast scenes with slow scenes. Fast camera or fast objects inside, both are OK. Like, a car racing vs a person just standing and talking.

## 1 answer

Sort by » oldest newest most voted

magnitudes are always positive. the noise in a static scene can produce noticeable flow vectors... albeit in random directions... which don't affect magnitudes.

you should sum up all the flow vectors instead. that will give you average motion and direction. the average will represent camera motion or full scene motion. it will only imperfectly track one object moving across the view.

if you want to ignore static parts of the image and only react to moving parts, make a mask for the static parts (magnitudes less than some threshold) and, for the summing/averaging, select only flow vectors that aren't in that mask.

more

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2019-08-15 12:21:09 -0500

Seen: 754 times

Last updated: Nov 19 '20