Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CV2 optical flow function is not deterministic

I'm trying to get the amount of motion by calculating the optical flow magnitude between two images (in Python 3.7 and cv2 v4.0). But passing the same images, I see the final value is not deterministic. Sometimes it prints inf and sometimes it prints 7.372749678324908e-05.

What is the problem? Why it's not deterministic?!

def getOpticalMag(prev_image, curr_image):

    prev_image_gray = cv2.cvtColor(prev_image, cv2.COLOR_BGR2GRAY)
    curr_image_gray = cv2.cvtColor(curr_image, cv2.COLOR_BGR2GRAY)

    flow = cv2.calcOpticalFlowFarneback(prev_image_gray, curr_image_gray, flow=None,
                                        pyr_scale=0.5, levels=1, winsize=15,
                                        iterations=2,
                                        poly_n=5, poly_sigma=1.1, flags=0)

    mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1])

    return np.mean(mag)
like image 968
angel_30 Avatar asked Feb 14 '26 15:02

angel_30


1 Answers

I've found out that it's a bug in the underlying IPP (IPPICV) part of OpenCV, which is shipped with the Python version in order to make it work faster, so posted it and it's already milestoned https://github.com/opencv/opencv/issues/19506.

You can write your own converter from cartesian to polar coordinates using numpy like in this feature request https://github.com/numpy/numpy/issues/5228#issue-46746558 (if you use Python version of OpenCV, you have NumPy already)

def cartToPol(x, y):
    ang = numpy.arctan2(y, x)
    mag = numpy.hypot(x, y)
    return mag, ang

Another solution is to compile OpenCV without IPP or use the C++ version of OpenCV: in my Ubuntu 20.04, this bug doesn't exist for the C++ version because I didn't install IPP.

like image 51
Charlie Avatar answered Feb 17 '26 06:02

Charlie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!