Кому-нибудь удалось заставить работать алгоритм плотного оптического потока Brox в OpenCV?
Вот некоторый код:
{
// 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
работает отлично…
Weird.
Полное исключение:
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
Требуется OpenGL, но также может быть проблема с вашим параметром масштаба (50.0f). Это кажется слишком большим. Как я понимаю, это должно быть меньше 1. Если это большое число, алгоритм быстро заполняет память GPU. Кроме того, может не иметь смысла использовать расширяющуюся (перевернутую?) Пирамиду изображений. Не совсем уверен, хотя.
После экспериментов с другими версиями OpenCV и следуя информации, содержащейся здесь: http://stuartjames.info/Journal/opencv-brox-optical-flow-sample-possible-fix.aspx
Похоже, мне нужно перекомпилировать OpenCV с OpenGL.
Кажется, что вы можете проверить, имеет ли ваша установка OpenCV OpenGL, выполнив команду: cv::gpu::setGlDevice(0);
Если это не получится со странным исключением, как, например, выше, вам нужно перекомпилировать.
OpenGL необходим, поскольку новые алгоритмы оптического потока в OpenCV отображают данные в текстуры OpenGL, чтобы (я полагаю) ускорить операции или, возможно, просто сделать код проще.
Итак, после всего этого, решение состоит в том, чтобы перекомпилировать OpenCV с OpenGL. Это может быть достигнуто путем отметки 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
//...
}