diff --git a/modules/cudalegacy/include/opencv2/cudalegacy.hpp b/modules/cudalegacy/include/opencv2/cudalegacy.hpp index 328836c530..f0107499d3 100644 --- a/modules/cudalegacy/include/opencv2/cudalegacy.hpp +++ b/modules/cudalegacy/include/opencv2/cudalegacy.hpp @@ -71,8 +71,9 @@ public: CV_EXPORTS Ptr createImagePyramid(InputArray img, int nLayers = -1, Stream& stream = Stream::Null()); -//////////////////////////////////////////////////// +// // GMG +// /** @brief Background/Foreground Segmentation Algorithm. @@ -125,8 +126,9 @@ public: CV_EXPORTS Ptr createBackgroundSubtractorGMG(int initializationFrames = 120, double decisionThreshold = 0.8); -//////////////////////////////////////////////////// +// // FGD +// /** @brief The class discriminates between foreground and background pixels by building and maintaining a model of the background. @@ -180,6 +182,51 @@ struct CV_EXPORTS FGDParams CV_EXPORTS Ptr createBackgroundSubtractorFGD(const FGDParams& params = FGDParams()); +// +// Optical flow +// + +//! Calculates optical flow for 2 images using block matching algorithm */ +CV_EXPORTS void calcOpticalFlowBM(const GpuMat& prev, const GpuMat& curr, + Size block_size, Size shift_size, Size max_range, bool use_previous, + GpuMat& velx, GpuMat& vely, GpuMat& buf, + Stream& stream = Stream::Null()); + +class CV_EXPORTS FastOpticalFlowBM +{ +public: + void operator ()(const GpuMat& I0, const GpuMat& I1, GpuMat& flowx, GpuMat& flowy, int search_window = 21, int block_window = 7, Stream& s = Stream::Null()); + +private: + GpuMat buffer; + GpuMat extended_I0; + GpuMat extended_I1; +}; + +/** @brief Interpolates frames (images) using provided optical flow (displacement field). + +@param frame0 First frame (32-bit floating point images, single channel). +@param frame1 Second frame. Must have the same type and size as frame0 . +@param fu Forward horizontal displacement. +@param fv Forward vertical displacement. +@param bu Backward horizontal displacement. +@param bv Backward vertical displacement. +@param pos New frame position. +@param newFrame Output image. +@param buf Temporary buffer, will have width x 6\*height size, CV_32FC1 type and contain 6 +GpuMat: occlusion masks for first frame, occlusion masks for second, interpolated forward +horizontal flow, interpolated forward vertical flow, interpolated backward horizontal flow, +interpolated backward vertical flow. +@param stream Stream for the asynchronous version. + */ +CV_EXPORTS void interpolateFrames(const GpuMat& frame0, const GpuMat& frame1, + const GpuMat& fu, const GpuMat& fv, + const GpuMat& bu, const GpuMat& bv, + float pos, GpuMat& newFrame, GpuMat& buf, + Stream& stream = Stream::Null()); + +CV_EXPORTS void createOpticalFlowNeedleMap(const GpuMat& u, const GpuMat& v, GpuMat& vertex, GpuMat& colors); + //! @} }} diff --git a/modules/cudaoptflow/src/bm.cpp b/modules/cudalegacy/src/bm.cpp similarity index 100% rename from modules/cudaoptflow/src/bm.cpp rename to modules/cudalegacy/src/bm.cpp diff --git a/modules/cudaoptflow/src/bm_fast.cpp b/modules/cudalegacy/src/bm_fast.cpp similarity index 100% rename from modules/cudaoptflow/src/bm_fast.cpp rename to modules/cudalegacy/src/bm_fast.cpp diff --git a/modules/cudaoptflow/src/cuda/bm.cu b/modules/cudalegacy/src/cuda/bm.cu similarity index 100% rename from modules/cudaoptflow/src/cuda/bm.cu rename to modules/cudalegacy/src/cuda/bm.cu diff --git a/modules/cudaoptflow/src/cuda/bm_fast.cu b/modules/cudalegacy/src/cuda/bm_fast.cu similarity index 100% rename from modules/cudaoptflow/src/cuda/bm_fast.cu rename to modules/cudalegacy/src/cuda/bm_fast.cu diff --git a/modules/cudaoptflow/src/cuda/needle_map.cu b/modules/cudalegacy/src/cuda/needle_map.cu similarity index 100% rename from modules/cudaoptflow/src/cuda/needle_map.cu rename to modules/cudalegacy/src/cuda/needle_map.cu diff --git a/modules/cudaoptflow/src/interpolate_frames.cpp b/modules/cudalegacy/src/interpolate_frames.cpp similarity index 100% rename from modules/cudaoptflow/src/interpolate_frames.cpp rename to modules/cudalegacy/src/interpolate_frames.cpp diff --git a/modules/cudaoptflow/src/needle_map.cpp b/modules/cudalegacy/src/needle_map.cpp similarity index 100% rename from modules/cudaoptflow/src/needle_map.cpp rename to modules/cudalegacy/src/needle_map.cpp diff --git a/modules/cudaoptflow/include/opencv2/cudaoptflow.hpp b/modules/cudaoptflow/include/opencv2/cudaoptflow.hpp index f65b1447b2..7882a8e622 100644 --- a/modules/cudaoptflow/include/opencv2/cudaoptflow.hpp +++ b/modules/cudaoptflow/include/opencv2/cudaoptflow.hpp @@ -347,47 +347,6 @@ private: GpuMat norm_buf; }; -//! Calculates optical flow for 2 images using block matching algorithm */ -CV_EXPORTS void calcOpticalFlowBM(const GpuMat& prev, const GpuMat& curr, - Size block_size, Size shift_size, Size max_range, bool use_previous, - GpuMat& velx, GpuMat& vely, GpuMat& buf, - Stream& stream = Stream::Null()); - -class CV_EXPORTS FastOpticalFlowBM -{ -public: - void operator ()(const GpuMat& I0, const GpuMat& I1, GpuMat& flowx, GpuMat& flowy, int search_window = 21, int block_window = 7, Stream& s = Stream::Null()); - -private: - GpuMat buffer; - GpuMat extended_I0; - GpuMat extended_I1; -}; - -/** @brief Interpolates frames (images) using provided optical flow (displacement field). - -@param frame0 First frame (32-bit floating point images, single channel). -@param frame1 Second frame. Must have the same type and size as frame0 . -@param fu Forward horizontal displacement. -@param fv Forward vertical displacement. -@param bu Backward horizontal displacement. -@param bv Backward vertical displacement. -@param pos New frame position. -@param newFrame Output image. -@param buf Temporary buffer, will have width x 6\*height size, CV_32FC1 type and contain 6 -GpuMat: occlusion masks for first frame, occlusion masks for second, interpolated forward -horizontal flow, interpolated forward vertical flow, interpolated backward horizontal flow, -interpolated backward vertical flow. -@param stream Stream for the asynchronous version. - */ -CV_EXPORTS void interpolateFrames(const GpuMat& frame0, const GpuMat& frame1, - const GpuMat& fu, const GpuMat& fv, - const GpuMat& bu, const GpuMat& bv, - float pos, GpuMat& newFrame, GpuMat& buf, - Stream& stream = Stream::Null()); - -CV_EXPORTS void createOpticalFlowNeedleMap(const GpuMat& u, const GpuMat& v, GpuMat& vertex, GpuMat& colors); - //! @} }} // namespace cv { namespace cuda { diff --git a/modules/cudaoptflow/perf/perf_optflow.cpp b/modules/cudaoptflow/perf/perf_optflow.cpp index d22eb7e60d..12612b0622 100644 --- a/modules/cudaoptflow/perf/perf_optflow.cpp +++ b/modules/cudaoptflow/perf/perf_optflow.cpp @@ -46,91 +46,10 @@ using namespace std; using namespace testing; using namespace perf; -////////////////////////////////////////////////////// -// InterpolateFrames - typedef pair pair_string; DEF_PARAM_TEST_1(ImagePair, pair_string); -PERF_TEST_P(ImagePair, InterpolateFrames, - Values(make_pair("gpu/opticalflow/frame0.png", "gpu/opticalflow/frame1.png"))) -{ - cv::Mat frame0 = readImage(GetParam().first, cv::IMREAD_GRAYSCALE); - ASSERT_FALSE(frame0.empty()); - - cv::Mat frame1 = readImage(GetParam().second, cv::IMREAD_GRAYSCALE); - ASSERT_FALSE(frame1.empty()); - - frame0.convertTo(frame0, CV_32FC1, 1.0 / 255.0); - frame1.convertTo(frame1, CV_32FC1, 1.0 / 255.0); - - if (PERF_RUN_CUDA()) - { - const cv::cuda::GpuMat d_frame0(frame0); - const cv::cuda::GpuMat d_frame1(frame1); - cv::cuda::GpuMat d_fu, d_fv; - cv::cuda::GpuMat d_bu, d_bv; - - cv::cuda::BroxOpticalFlow d_flow(0.197f /*alpha*/, 50.0f /*gamma*/, 0.8f /*scale_factor*/, - 10 /*inner_iterations*/, 77 /*outer_iterations*/, 10 /*solver_iterations*/); - - d_flow(d_frame0, d_frame1, d_fu, d_fv); - d_flow(d_frame1, d_frame0, d_bu, d_bv); - - cv::cuda::GpuMat newFrame; - cv::cuda::GpuMat d_buf; - - TEST_CYCLE() cv::cuda::interpolateFrames(d_frame0, d_frame1, d_fu, d_fv, d_bu, d_bv, 0.5f, newFrame, d_buf); - - CUDA_SANITY_CHECK(newFrame, 1e-4); - } - else - { - FAIL_NO_CPU(); - } -} - -////////////////////////////////////////////////////// -// CreateOpticalFlowNeedleMap - -PERF_TEST_P(ImagePair, CreateOpticalFlowNeedleMap, - Values(make_pair("gpu/opticalflow/frame0.png", "gpu/opticalflow/frame1.png"))) -{ - cv::Mat frame0 = readImage(GetParam().first, cv::IMREAD_GRAYSCALE); - ASSERT_FALSE(frame0.empty()); - - cv::Mat frame1 = readImage(GetParam().second, cv::IMREAD_GRAYSCALE); - ASSERT_FALSE(frame1.empty()); - - frame0.convertTo(frame0, CV_32FC1, 1.0 / 255.0); - frame1.convertTo(frame1, CV_32FC1, 1.0 / 255.0); - - if (PERF_RUN_CUDA()) - { - const cv::cuda::GpuMat d_frame0(frame0); - const cv::cuda::GpuMat d_frame1(frame1); - cv::cuda::GpuMat u; - cv::cuda::GpuMat v; - - cv::cuda::BroxOpticalFlow d_flow(0.197f /*alpha*/, 50.0f /*gamma*/, 0.8f /*scale_factor*/, - 10 /*inner_iterations*/, 77 /*outer_iterations*/, 10 /*solver_iterations*/); - - d_flow(d_frame0, d_frame1, u, v); - - cv::cuda::GpuMat vertex, colors; - - TEST_CYCLE() cv::cuda::createOpticalFlowNeedleMap(u, v, vertex, colors); - - CUDA_SANITY_CHECK(vertex, 1e-6); - CUDA_SANITY_CHECK(colors); - } - else - { - FAIL_NO_CPU(); - } -} - ////////////////////////////////////////////////////// // BroxOpticalFlow @@ -383,72 +302,3 @@ PERF_TEST_P(ImagePair, OpticalFlowDual_TVL1, CPU_SANITY_CHECK(flow); } } - -////////////////////////////////////////////////////// -// OpticalFlowBM - -PERF_TEST_P(ImagePair, OpticalFlowBM, - Values(make_pair("gpu/opticalflow/frame0.png", "gpu/opticalflow/frame1.png"))) -{ - declare.time(400); - - const cv::Mat frame0 = readImage(GetParam().first, cv::IMREAD_GRAYSCALE); - ASSERT_FALSE(frame0.empty()); - - const cv::Mat frame1 = readImage(GetParam().second, cv::IMREAD_GRAYSCALE); - ASSERT_FALSE(frame1.empty()); - - const cv::Size block_size(16, 16); - const cv::Size shift_size(1, 1); - const cv::Size max_range(16, 16); - - if (PERF_RUN_CUDA()) - { - const cv::cuda::GpuMat d_frame0(frame0); - const cv::cuda::GpuMat d_frame1(frame1); - cv::cuda::GpuMat u, v, buf; - - TEST_CYCLE() cv::cuda::calcOpticalFlowBM(d_frame0, d_frame1, block_size, shift_size, max_range, false, u, v, buf); - - CUDA_SANITY_CHECK(u); - CUDA_SANITY_CHECK(v); - } - else - { - FAIL_NO_CPU(); - } -} - -PERF_TEST_P(ImagePair, DISABLED_FastOpticalFlowBM, - Values(make_pair("gpu/opticalflow/frame0.png", "gpu/opticalflow/frame1.png"))) -{ - declare.time(400); - - const cv::Mat frame0 = readImage(GetParam().first, cv::IMREAD_GRAYSCALE); - ASSERT_FALSE(frame0.empty()); - - const cv::Mat frame1 = readImage(GetParam().second, cv::IMREAD_GRAYSCALE); - ASSERT_FALSE(frame1.empty()); - - const cv::Size block_size(16, 16); - const cv::Size shift_size(1, 1); - const cv::Size max_range(16, 16); - - if (PERF_RUN_CUDA()) - { - const cv::cuda::GpuMat d_frame0(frame0); - const cv::cuda::GpuMat d_frame1(frame1); - cv::cuda::GpuMat u, v; - - cv::cuda::FastOpticalFlowBM fastBM; - - TEST_CYCLE() fastBM(d_frame0, d_frame1, u, v, max_range.width, block_size.width); - - CUDA_SANITY_CHECK(u, 2); - CUDA_SANITY_CHECK(v, 2); - } - else - { - FAIL_NO_CPU(); - } -} diff --git a/modules/cudaoptflow/test/test_optflow.cpp b/modules/cudaoptflow/test/test_optflow.cpp index dce9cc59bc..7a6e68310f 100644 --- a/modules/cudaoptflow/test/test_optflow.cpp +++ b/modules/cudaoptflow/test/test_optflow.cpp @@ -378,122 +378,4 @@ INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, OpticalFlowDual_TVL1, testing::Combine( ALL_DEVICES, testing::Values(Gamma(0.0), Gamma(1.0)))); -////////////////////////////////////////////////////// -// FastOpticalFlowBM - -namespace -{ - void FastOpticalFlowBM_gold(const cv::Mat_& I0, const cv::Mat_& I1, cv::Mat_& velx, cv::Mat_& vely, int search_window, int block_window) - { - velx.create(I0.size()); - vely.create(I0.size()); - - int search_radius = search_window / 2; - int block_radius = block_window / 2; - - for (int y = 0; y < I0.rows; ++y) - { - for (int x = 0; x < I0.cols; ++x) - { - int bestDist = std::numeric_limits::max(); - int bestDx = 0; - int bestDy = 0; - - for (int dy = -search_radius; dy <= search_radius; ++dy) - { - for (int dx = -search_radius; dx <= search_radius; ++dx) - { - int dist = 0; - - for (int by = -block_radius; by <= block_radius; ++by) - { - for (int bx = -block_radius; bx <= block_radius; ++bx) - { - int I0_val = I0(cv::borderInterpolate(y + by, I0.rows, cv::BORDER_DEFAULT), cv::borderInterpolate(x + bx, I0.cols, cv::BORDER_DEFAULT)); - int I1_val = I1(cv::borderInterpolate(y + dy + by, I0.rows, cv::BORDER_DEFAULT), cv::borderInterpolate(x + dx + bx, I0.cols, cv::BORDER_DEFAULT)); - - dist += std::abs(I0_val - I1_val); - } - } - - if (dist < bestDist) - { - bestDist = dist; - bestDx = dx; - bestDy = dy; - } - } - } - - velx(y, x) = (float) bestDx; - vely(y, x) = (float) bestDy; - } - } - } - - double calc_rmse(const cv::Mat_& flow1, const cv::Mat_& flow2) - { - double sum = 0.0; - - for (int y = 0; y < flow1.rows; ++y) - { - for (int x = 0; x < flow1.cols; ++x) - { - double diff = flow1(y, x) - flow2(y, x); - sum += diff * diff; - } - } - - return std::sqrt(sum / flow1.size().area()); - } -} - -struct FastOpticalFlowBM : testing::TestWithParam -{ -}; - -CUDA_TEST_P(FastOpticalFlowBM, Accuracy) -{ - const double MAX_RMSE = 0.6; - - int search_window = 15; - int block_window = 5; - - cv::cuda::DeviceInfo devInfo = GetParam(); - cv::cuda::setDevice(devInfo.deviceID()); - - cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE); - ASSERT_FALSE(frame0.empty()); - - cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE); - ASSERT_FALSE(frame1.empty()); - - cv::Size smallSize(320, 240); - cv::Mat frame0_small; - cv::Mat frame1_small; - - cv::resize(frame0, frame0_small, smallSize); - cv::resize(frame1, frame1_small, smallSize); - - cv::cuda::GpuMat d_flowx; - cv::cuda::GpuMat d_flowy; - cv::cuda::FastOpticalFlowBM fastBM; - - fastBM(loadMat(frame0_small), loadMat(frame1_small), d_flowx, d_flowy, search_window, block_window); - - cv::Mat_ flowx; - cv::Mat_ flowy; - FastOpticalFlowBM_gold(frame0_small, frame1_small, flowx, flowy, search_window, block_window); - - double err; - - err = calc_rmse(flowx, cv::Mat(d_flowx)); - EXPECT_LE(err, MAX_RMSE); - - err = calc_rmse(flowy, cv::Mat(d_flowy)); - EXPECT_LE(err, MAX_RMSE); -} - -INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, FastOpticalFlowBM, ALL_DEVICES); - #endif // HAVE_CUDA