2

有没有人设法让 OpenCV 中的 Brox 密集光流算法工作?

这是一些代码:

{
    // Load images
    cv::Mat PreviousFrameGrayFloat; // Has an image in format CV_32FC1
    cv::Mat CurrentFrameGrayFloat;  // Has an image in format CV_32FC1

    // Upload images to GPU
    cv::gpu::GpuMat PreviousFrameGPU(PreviousFrameGrayFloat);
    cv::gpu::GpuMat CurrentFrameGPU(CurrentFrameGrayFloat);

    // Prepare receiving variables
    cv::gpu::GpuMat FlowXGPU;
    cv::gpu::GpuMat FlowYGPU;

    // Create optical flow object
    cv::gpu::BroxOpticalFlow OpticalFlowGPU = cv::gpu::BroxOpticalFlow(0.197f, 0.8f, 50.0f, 10, 77, 10);

    // Perform optical flow
    OpticalFlowGPU(PreviousFrameGPU, CurrentFrameGPU, FlowXGPU, FlowYGPU); // EXCEPTION
    // Exception in opencv_core244d!cv::GlBuffer::unbind

    // Download flow from GPU
    cv::Mat FlowX;
    cv::Mat FlowY;
    FlowXGPU.download(FlowX);
    FlowYGPU.download(FlowY);
}

如上所述,我遇到了一个异常,当我尝试使用该cv::gpu::BroxOpticalFlow对象时,我遇到了同样的问题,cv::gpu::PyrLKOpticalFlow但只有密集版本而不是稀疏版本,并且cv::gpu::FarnebackOpticalFlow工作正常......

奇怪的。

整个例外是:

Exception at 0x7c812fd3, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) in opencv_core244d!cv::GlBuffer::unbind

我正在使用带有调试库的调试版本,使用 OpenCV 2.4.4,但是代码也在 OpenCV 2.4.3 中引发异常。

当我使用 OpenCV 2.4.3 时,我得到了这个异常:

Exception at 0x7c812fd3, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) in opencv_core243d!cv::SparseMat::erase
4

2 回答 2

1

需要 OpenGL,但您的比例参数 (50.0f) 也可能存在问题。它似乎太大了。据我了解,这应该小于1。如果是一个很大的数字,算法会很快填满GPU内存。另外,使用扩展(倒置?)图像金字塔可能没有意义。虽然不完全确定。

于 2013-04-17T01:06:39.273 回答
0

在尝试了其他版本的 OpenCV 并遵循此处包含的信息后:http: //stuartjames.info/Journal/opencv-brox-optical-flow-sample-possible-fix.aspx

看起来我需要用 OpenGL 重新编译 OpenCV。

您似乎可以通过运行以下命令来测试您安装的 OpenCV 是否具有 OpenGL:cv::gpu::setGlDevice(0);如果失败并出现上述异常异常,则需要重新编译。

OpenGL 是必需的,因为 OpenCV 中较新的光流算法将数据映射到 OpenGL 纹理以(我假设)加速操作,或者可能只是使代码更简单。

所以,在这一切之后,解决方案是用 OpenGL 重新编译 OpenCV。这可以通过WITH_OPENGL在使用 CMake 配置构建时勾选该框来实现。

如果您想使用视频阅读器的 GPU 版本,请确保您也勾选WITH_NVCUVID了这包含在 CUDA 中,但除非您要求,否则不包含在内...

- 编辑 -

保罗发表评论后,我从问题中更正了代码中的比例因子。

这是我正在测试的完整代码,用于nkint

{
    // Load images
    cv::Mat PreviousFrameGray = cv::imread("Input1.png", 0);
    cv::Mat CurrentFrameGray  = cv::imread("Input2.png", 0);

    cv::Mat PreviousFrameGrayFloat; // Has an image in format CV_32FC1
    cv::Mat CurrentFrameGrayFloat;  // Has an image in format CV_32FC1

    PreviousFrameGray.convertTo(PreviousFrameGrayFloat, CV_32FC1, 1.0/255.0);
    CurrentFrameGray.convertTo(CurrentFrameGrayFloat, CV_32FC1, 1.0/255.0);

    // Upload images to GPU
    cv::gpu::GpuMat PreviousFrameGPU(PreviousFrameGrayFloat);
    cv::gpu::GpuMat CurrentFrameGPU(CurrentFrameGrayFloat);

    // Prepare receiving variables
    cv::gpu::GpuMat FlowXGPU;
    cv::gpu::GpuMat FlowYGPU;

    // Create optical flow object
    cv::gpu::BroxOpticalFlow OpticalFlowGPU = cv::gpu::BroxOpticalFlow(0.197f, 50.0f, 0.8f, 10, 77, 10);

    // Perform optical flow
    OpticalFlowGPU(PreviousFrameGPU, CurrentFrameGPU, FlowXGPU, FlowYGPU);

    // Download flow from GPU
    cv::Mat FlowX;
    cv::Mat FlowY;
    FlowXGPU.download(FlowX);
    FlowYGPU.download(FlowY);

    // Use FlowX and FlowY in further processing
    //...
}
于 2013-03-15T10:57:19.077 回答