diff --git a/modules/gpu/include/opencv2/gpu/gpu.hpp b/modules/gpu/include/opencv2/gpu/gpu.hpp index 949acba690..db5aa43763 100644 --- a/modules/gpu/include/opencv2/gpu/gpu.hpp +++ b/modules/gpu/include/opencv2/gpu/gpu.hpp @@ -395,7 +395,7 @@ CV_EXPORTS void GaussianBlur(const GpuMat& src, GpuMat& dst, Size ksize, GpuMat& //! applies Laplacian operator to the image //! supports only ksize = 1 and ksize = 3 -CV_EXPORTS void Laplacian(const GpuMat& src, GpuMat& dst, int ddepth, int ksize = 1, double scale = 1, Stream& stream = Stream::Null()); +CV_EXPORTS void Laplacian(const GpuMat& src, GpuMat& dst, int ddepth, int ksize = 1, double scale = 1, int borderType = BORDER_DEFAULT, Stream& stream = Stream::Null()); ////////////////////////////// Arithmetics /////////////////////////////////// @@ -1094,8 +1094,8 @@ public: bool use_local_init_data_cost; private: - GpuMat messages_buffers; - + GpuMat messages_buffers; + GpuMat temp; GpuMat out; }; diff --git a/modules/gpu/src/filtering.cpp b/modules/gpu/src/filtering.cpp index 2349857ee7..ebf990001a 100644 --- a/modules/gpu/src/filtering.cpp +++ b/modules/gpu/src/filtering.cpp @@ -87,7 +87,7 @@ void cv::gpu::Scharr(const GpuMat&, GpuMat&, int, int, int, double, int, int) { void cv::gpu::Scharr(const GpuMat&, GpuMat&, int, int, int, GpuMat&, double, int, int, Stream&) { throw_nogpu(); } void cv::gpu::GaussianBlur(const GpuMat&, GpuMat&, Size, double, double, int, int) { throw_nogpu(); } void cv::gpu::GaussianBlur(const GpuMat&, GpuMat&, Size, GpuMat&, double, double, int, int, Stream&) { throw_nogpu(); } -void cv::gpu::Laplacian(const GpuMat&, GpuMat&, int, int, double, Stream&) { throw_nogpu(); } +void cv::gpu::Laplacian(const GpuMat&, GpuMat&, int, int, double, int, Stream&) { throw_nogpu(); } #else @@ -664,8 +664,8 @@ namespace cv { namespace gpu { namespace device namespace imgproc { template - void filter2D_gpu(DevMem2Db srcWhole, int ofsX, int ofsY, DevMem2Db dst, - int kWidth, int kHeight, int anchorX, int anchorY, const float* kernel, + void filter2D_gpu(DevMem2Db srcWhole, int ofsX, int ofsY, DevMem2Db dst, + int kWidth, int kHeight, int anchorX, int anchorY, const float* kernel, int borderMode, const float* borderValue, cudaStream_t stream); } }}} @@ -708,14 +708,14 @@ namespace nppFilter2D_t func; }; - typedef void (*gpuFilter2D_t)(DevMem2Db srcWhole, int ofsX, int ofsY, DevMem2Db dst, - int kWidth, int kHeight, int anchorX, int anchorY, const float* kernel, + typedef void (*gpuFilter2D_t)(DevMem2Db srcWhole, int ofsX, int ofsY, DevMem2Db dst, + int kWidth, int kHeight, int anchorX, int anchorY, const float* kernel, int borderMode, const float* borderValue, cudaStream_t stream); struct GpuFilter2D : public BaseFilter_GPU { GpuFilter2D(Size ksize_, Point anchor_, gpuFilter2D_t func_, const GpuMat& kernel_, int brd_type_) : - BaseFilter_GPU(ksize_, anchor_), func(func_), kernel(kernel_), brd_type(brd_type_) + BaseFilter_GPU(ksize_, anchor_), func(func_), kernel(kernel_), brd_type(brd_type_) { } @@ -1193,7 +1193,7 @@ void cv::gpu::Scharr(const GpuMat& src, GpuMat& dst, int ddepth, int dx, int dy, sepFilter2D(src, dst, ddepth, kx, ky, buf, Point(-1,-1), rowBorderType, columnBorderType, stream); } -void cv::gpu::Laplacian(const GpuMat& src, GpuMat& dst, int ddepth, int ksize, double scale, Stream& stream) +void cv::gpu::Laplacian(const GpuMat& src, GpuMat& dst, int ddepth, int ksize, double scale, int borderType, Stream& stream) { CV_Assert(ksize == 1 || ksize == 3); @@ -1206,7 +1206,7 @@ void cv::gpu::Laplacian(const GpuMat& src, GpuMat& dst, int ddepth, int ksize, d if (scale != 1) kernel *= scale; - filter2D(src, dst, ddepth, kernel, Point(-1,-1), stream); + filter2D(src, dst, ddepth, kernel, Point(-1,-1), borderType, stream); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/gpu/test/test_filters.cpp b/modules/gpu/test/test_filters.cpp index 6f7b8d9113..99c463b84a 100644 --- a/modules/gpu/test/test_filters.cpp +++ b/modules/gpu/test/test_filters.cpp @@ -334,10 +334,7 @@ TEST_P(Laplacian, Accuracy) cv::Mat dst_gold; cv::Laplacian(src, dst_gold, -1, ksize.width); - if (type == CV_32FC1) - EXPECT_MAT_NEAR(dst_gold, dst, 0.0); - else - EXPECT_MAT_NEAR(getInnerROI(dst_gold, cv::Size(3, 3)), getInnerROI(dst, cv::Size(3, 3)), 0.0); + EXPECT_MAT_NEAR(dst_gold, dst, 0.0); } INSTANTIATE_TEST_CASE_P(GPU_Filter, Laplacian, testing::Combine( diff --git a/samples/gpu/performance/tests.cpp b/samples/gpu/performance/tests.cpp index a49ba2a778..e025d7dd12 100644 --- a/samples/gpu/performance/tests.cpp +++ b/samples/gpu/performance/tests.cpp @@ -273,7 +273,7 @@ TEST(SURF) SURF surf; vector keypoints; - vector descriptors; + Mat descriptors; surf(src, Mat(), keypoints, descriptors); @@ -899,7 +899,6 @@ TEST(solvePnPRansac) } } - TEST(GaussianBlur) { for (int size = 1000; size <= 4000; size += 1000) @@ -928,6 +927,39 @@ TEST(GaussianBlur) } } +TEST(filter2D) +{ + for (int size = 512; size <= 2048; size *= 2) + { + Mat src; + gen(src, size, size, CV_8UC4, 0, 256); + + for (int ksize = 3; ksize <= 16; ksize += 2) + { + SUBTEST << "ksize = " << ksize << ", " << size << 'x' << size << ", 8UC4"; + + Mat kernel; + gen(kernel, ksize, ksize, CV_32FC1, 0.0, 1.0); + + Mat dst; + cv::filter2D(src, dst, -1, kernel); + + CPU_ON; + cv::filter2D(src, dst, -1, kernel); + CPU_OFF; + + gpu::GpuMat d_src(src); + gpu::GpuMat d_dst; + + gpu::filter2D(d_src, d_dst, -1, kernel); + + GPU_ON; + gpu::filter2D(d_src, d_dst, -1, kernel); + GPU_OFF; + } + } +} + TEST(pyrDown) { for (int size = 4000; size >= 1000; size -= 1000)