0

我正在对实时馈送执行图像稳定,以便在稳定的图像上运行一些视觉算法(强调“实时”)。目前,这个使用 CPU 实现的 LK 金字塔版本的过程几乎不够快,即使在预先构建金字塔时也是如此(参考图像和“以前的”特征只计算一次),但它需要缩放到处理分辨率约为四倍的图像,这使得它在当前实现中太慢了。我想我可能会尝试通过合并 GPU 来加快速度,因为 OpenCV 已经为支持 CUDA 的设备实现了相同的 LK 方法,即 cv::gpu::PyrLKOpticalFlow 类。我将 ::sparse 调用与一组先前的功能一起使用。

我的主要问题是窗口大小似乎有限制,而我的窗口太大了。该限制作为断言出现在 pyrlk.cpp 文件中:

CV_Assert(patch.x > 0 && patch.x < 6 && patch.y > 0 && patch.y < 6);

补丁尺寸在上面确定的地方:

void calcPatchSize(cv::Size winSize, dim3& block, dim3& patch)
{
    if (winSize.width > 32 && winSize.width > 2 * winSize.height)
    {
        block.x = deviceSupports(FEATURE_SET_COMPUTE_12) ? 32 : 16;
        block.y = 8;
    }
    else
    {
        block.x = 16;
        block.y = deviceSupports(FEATURE_SET_COMPUTE_12) ? 16 : 8;
    }

    patch.x = (winSize.width  + block.x - 1) / block.x;
    patch.y = (winSize.height + block.y - 1) / block.y;

    block.z = patch.z = 1;
}

我的问题是我需要一个大约 80x80 像素的窗口大小,这是 A.为什么我要使用 GPU 加速和 B.为什么这在 OpenCV 中似乎不起作用。:) 此外,随着更大分辨率的图像,此窗口大小将需要增长。

我不熟悉实际实现 GPU 加速,所以我想知道是否有人可以解释为什么 OpenCV 中存在这种限制,它是否是硬件或 OpenCV 实现所施加的真正限制,以及是否有办法解决它。这似乎是一个硬件限制,这似乎很奇怪,因为这些是您想要使用 GPU 的情况。我可以通过较小的搜索窗口获得合理的速度,但稳定性对于应用程序来说还不够好。

我需要这么大的搜索窗口大小,因为我正在计算第一(参考)帧的运动。运动是循环的,加上一些小的随机漂移,所以这种方法效果很好,但是当匹配特征可能在 30-40 像素之外(在原始分辨率下)时,需要更多的空间来搜索循环的峰值。

这是在 Linux 上使用 OpenCV 版本 2.4.10,从源代码构建以支持 CUDA。

(这是来自http://answers.opencv.org/question/54579/window-size-limit-in-gpu-accelerated-lk-pyramid/的(稍作修改)重新发布,但似乎没有那里有很多活动,所以希望 SO 提供更好的讨论环境!)

4

1 回答 1

3

补丁大小作为模板参数传递给 CUDA 内核。

请参阅https://github.com/jet47/opencv/blob/master/modules/cudaoptflow/src/cuda/pyrlk.cu#L493处的调用代码:

static const func_t funcs[5][5] =
{
    {sparse_caller<1, 1, 1>, sparse_caller<1, 2, 1>, sparse_caller<1, 3, 1>, sparse_caller<1, 4, 1>, sparse_caller<1, 5, 1>},
    {sparse_caller<1, 1, 2>, sparse_caller<1, 2, 2>, sparse_caller<1, 3, 2>, sparse_caller<1, 4, 2>, sparse_caller<1, 5, 2>},
    {sparse_caller<1, 1, 3>, sparse_caller<1, 2, 3>, sparse_caller<1, 3, 3>, sparse_caller<1, 4, 3>, sparse_caller<1, 5, 3>},
    {sparse_caller<1, 1, 4>, sparse_caller<1, 2, 4>, sparse_caller<1, 3, 4>, sparse_caller<1, 4, 4>, sparse_caller<1, 5, 4>},
    {sparse_caller<1, 1, 5>, sparse_caller<1, 2, 5>, sparse_caller<1, 3, 5>, sparse_caller<1, 4, 5>, sparse_caller<1, 5, 5>}
};

其中sparse_caller声明为:

template <int cn, int PATCH_X, int PATCH_Y>
void sparse_caller(int rows, int cols, const float2* prevPts, float2* nextPts, 
                   uchar* status, float* err, int ptcount,
                   int level, dim3 block, cudaStream_t stream)

对补丁大小的限制是为了减少模板实例化的数量。您可以通过修改此代码并添加更多实例来根据需要增加此限制。

于 2015-02-08T10:21:57.690 回答