我正在实时馈送上执行图像稳定,以便在稳定的图像上运行一些视觉算法(强调"实时")。目前,这个使用CPU实现的LK金字塔版本的过程几乎不够快,即使在预先构建金字塔时也是如此(参考图像和"以前"的特征只计算过一次),但它需要缩放以处理分辨率约为四倍的图像,这使得它在当前实现中太慢了。我想我可能会尝试通过合并GPU来加快速度,因为OpenCV已经为具有CUDA功能的设备实现了相同的LK方法,即cv::GPU::PyrLKOpticalFlow类。我使用的是:稀疏调用,它具有一组以前的功能。
我的主要问题是窗户的尺寸似乎有限制,而我的窗户太大了。限制作为断言出现在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能提供一个更好的讨论环境!)
补丁大小作为模板参数传递给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)
对补丁大小进行限制是为了减少模板实例化的数量。您可以根据需要通过修改此代码和添加更多实例化来增加此限制。