【问题标题】:Dense optical flow with masking带掩蔽的密集光流
【发布时间】:2019-11-14 14:55:25
【问题描述】:

我需要计算从头顶摄像头记录的两个连续帧之间车辆的密集光流。我正在使用对象检测器进行车辆检测,并使用 Farneback 算法在 Python 中进行光流估计。目前,计算整个图像的光流。但是,我需要在检测到的车辆周围创建一个遮罩,并仅在选定区域周围计算密集光流。这将有助于显着加快光流估计。我也可以使用任何其他形式的密集光流估计,但不能使用稀疏光流(例如 Lucas-Kanade 方法)。一种选择是提取车辆区域并单独输入每个车辆区域以进行光流估计,但我正在寻找更好的解决方案。

flow = cv2.calcOpticalFlowFarneback(prvs,next, None, 0.5, 3, 15, 3, 5, 1.2, 0)

对于没有任何光流计算的非车辆遮蔽区域,预期的光流结果将为零。

【问题讨论】:

    标签: python opencv opticalflow


    【解决方案1】:

    对于某些光流用例来说,这可能是一种健康的加速方法。

    为了确保我们在同一页面上,光流不会直接用作跟踪汽车的主要信息来源。这由另一个模块处理......可能是一些基于深度学习的对象检测器。这个物体检测器可能在计算方面很密集(除非你有一些特殊的硬件,比如专用的 GPU 或 VPU)。

    密集流可以是一个很好的补充,以获得关于汽车及其周围发生的事情的低延迟信息,并且可以用作引导后一个检测器的一部分(在连续的检测器中提供先验帧,如卡尔曼滤波器跟踪设置)。

    有了这个假设,您可以轻松优化您提到的光流计算。我建议您在这里跳过密集掩码的概念,只需使用检测器中的边界框即可。这将是您对流量计算感兴趣的区域。如果您在检测所在的帧 t 中,并且想要使用来自 2 帧 t 和 t-1 的光流,则对两个帧使用相同的边界框。这将为您提供 2 个 ROI,并将它们馈送到您的密集光流模块。

    每个光流算法都有其低级操作的支持区域,并且它们都不能很好地处理图像边界。因此,请确保为边界框提供足够的额外空间(只要它们可以容纳在原始视频帧中)。

    为了清楚起见,如果您有用于汽车检测的边界框为 bbox(x,y,w,h),则您需要一个良好的边距 m,以便用于密集流的边界框为 bbox(xm/2,ym /2,w+m,h+m)。边距是您想要根据您的光流方法(及其参数)设置的东西。

    编辑:这里给你的代码,你去。请注意,我根本没有测试过这个:

    // This is c++, since we are talking optimizations
    // I am uncertain of they python wrappers, but below I am fairly certain
    // will not make any deep copies outside of the flow module.
    // Assume you have INew and IOld, the two frames of the video:
    // assume your bounding box from your detector is a cv::Rect b
    float m = 4.0; // 4 pixels as an example margin...
    Rect boxFlow(b.x - m/2, b.y - m/2, b.width + m, b.height + m);
    Mat roiNew(INew (boxFlow));
    Mat roiOld(IOld (boxFlow));
    Mat uflow;
    calcOpticalFlowFarneback(roiOld, roiNew, uflow, 0.5, 3, 15, 3, 5, 1.2, 0);
    

    但是,根据您的设置,这最终可能不会显着加快速度。对于上面的代码,我不知道flow模块内部是如何处理内存的,而在你的python版本中,我更不确定它会如何处理。

    考虑在流线型密集光流方法中(您使用相同大小的数据吞吐量),您的管道中的内存缓冲区大小相同。您提到的方法的幼稚实现需要动态分配内存,因为边界框的大小和数量会随着时间而变化。

    【讨论】:

      【解决方案2】:

      不幸的是,按照您的计划通过屏蔽或仅提供检测器的边界框来加速运动估计并不是一个好主意。如果您使用密集光流方法,则需要提供整个图像并计算整个图像的流场。 如果您通过移除来覆盖图像,您将引入人工边缘,这会混淆该方法。 另一方面,单独输入每个车辆区域,您将失去密集流方法计算较大(快速)运动的能力。 farneback 等方法使用图像金字塔来处理大运动,即它们基于缩小输入图像。如果区域小于这限制了计算大运动的能力。 减少运行时间的一种可能性是应用稀疏方法,例如(Lucas Kanade 或 RLOF)并将 SparseToDense 插值(例如 OpenCV 中的 EdgeAwareInterpolation)应用到您的车辆区域并获得该区域的密集运动场。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多