CV2光流功能不确定

问题描述

我正在尝试通过计算两个图像之间的光通量来获得运动量(在Python 3.7和cv2 v4.0中)。但是通过传递相同的图像,我看到最终值不是确定性的。有时会打印inf,有时会打印7.372749678324908e-05

出什么问题了?为什么它不是确定性的?!

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)

解决方法

我发现它是 OpenCV 的底层 IPP (IPPICV) 部分中的一个错误,它与 Python 版本一起提供以使其工作更快,因此将其发布并已成为里程碑 https://github.com/opencv/opencv/issues/19506

您可以使用 numpy 编写自己的从笛卡尔坐标到极坐标的转换器,就像在此功能请求 https://github.com/numpy/numpy/issues/5228#issue-46746558 中一样(如果您使用 Python 版本的 OpenCV,则您已经拥有 NumPy)

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

另一种解决方案是在没有 IPP 的情况下编译 OpenCV 或使用 OpenCV 的 C++ 版本:在我的 Ubuntu 20.04 中,C++ 版本不存在此错误,因为我没有安装 IPP。