Has anyone managed to get the Brox dense optical flow algorithm in OpenCV working?
Here is some code:
{
// 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);
}
I get an exception, as commented above, when I try and use the cv::gpu::BroxOpticalFlow
object, I have the same problem with cv::gpu::PyrLKOpticalFlow
but only the dense version not the sparse one, and cv::gpu::FarnebackOpticalFlow
works fine...
Weird.
Entire exception is:
Exception at 0x7c812fd3, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) in opencv_core244d!cv::GlBuffer::unbind
I'm using a debug build with debug libraries, using OpenCV 2.4.4 however the code also raises an exception in OpenCV 2.4.3.
When I use OpenCV 2.4.3 I get this exception:
Exception at 0x7c812fd3, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) in opencv_core243d!cv::SparseMat::erase
OpenGL is required, but there may also be a problem with your scale parameter (50.0f). It seems too large. As I understand, this should be less than 1. If it is a large number, the algorithm fills up GPU memory quickly. Plus, it may not make sense to use an expanding (upside-down?) image pyramid. Not perfectly sure though.
After experimenting with other versions of OpenCV and following the information contained here: http://stuartjames.info/Journal/opencv-brox-optical-flow-sample-possible-fix.aspx
It looks like I need to recompile OpenCV with OpenGL.
It seems that you can test whether your install of OpenCV has OpenGL by running the command: cv::gpu::setGlDevice(0);
if this fails with a weird exception like the one above then you need to recompile.
OpenGL is required as the newer optical flow algorithms in OpenCV map data to OpenGL textures to (I assume) speed up operations, or maybe to just make the code simpler.
So, after all this, the solution is to recompile OpenCV with OpenGL. This can be achieved by ticking the WITH_OPENGL
box when using CMake to configure the build.
If you want to use the GPU version of the video reader make sure you also tick WITH_NVCUVID
this is included with CUDA but not included unless you request it...
-- EDIT --
After the comments from paul I've corrected the scale factor in my code from the question.
Here is the complete code I'm testing, for 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
//...
}
User contributions licensed under CC BY-SA 3.0