# How do I can create a Gaussian filter in CUDA that is larger than 32 and double type?

The following code gives an error:

OpenCV(3.4.1) Error: Assertion failed (rowFilter_ != 0) in anonymous-namespace'::SeparableLinearFilter::SeparableLinearFilter, file c:\opencv\3.4.1\opencv-3.4.1\modules\cudafilters\src\filtering.cpp, line 413

filter3 = cv::cuda::createGaussianFilter(CV_64FC1, CV_64FC1, cv::Size(1501, 1501), 250);


and the below code gives an error:

OpenCV(3.4.1) Error: Assertion failed (rowKernel_.cols > 0 && rowKernel_.cols <= 32) in anonymous-namespace'::SeparableLinearFilter::SeparableLinearFilter, file c:\opencv\3.4.1\opencv-3.4.1\modules\cudafilters\src\filtering.cpp, line 404

filter1 = cv::cuda::createGaussianFilter(CV_8UC1, CV_8UC1, cv::Size(33, 33), 15);

edit retag close merge delete

Sort by » oldest newest most voted

I've already replied to a similar question here

Basically the size can be maximum 32 due to CUDA architecture (I suppose), but you can overcome running multiple time the filter. Here it is well explained how to achieve that, and also in the wikipidea page it is written that:

Applying multiple, successive Gaussian blurs to an image has the same effect as applying a single, larger Gaussian blur, whose radius is the square root of the sum of the squares of the blur radii that were actually applied. For example, applying successive Gaussian blurs with radii of 6 and 8 gives the same results as applying a single Gaussian blur of radius 10, since sqrt(6^2 + 8^2) = 10. Because of this relationship, processing time cannot be saved by simulating a Gaussian blur with successive, smaller blurs — the time required will be at least as great as performing the single large blur.

As you can see it increase the time needed for the execution, unfortunately.

more

Thank you. So, if want to apply the filter size larger than 32 x 32 and want high efficiency, I have to write my own custom kernel for that? Now, I am using the cv::cuda::Convolution::convolution()for that. I don't know it has the same results or not.

( 2019-05-18 23:02:28 -0500 )edit

You can generate you kernel defining the own choice sigma and apply to the whole image. There is an online calculator, if you know prior the size and the sigma I suppose it could help you in speed up the process. You can find it here.

Try this:

cv::Mat kernel = (cv::Mat(33,33,CV_64F) << /*here the value that you got from the website*/);
cv::Mat result;
cv::Ptr<cuda::Convolution> conv= cuda::createConvolution(Size(33, 33));
conv->convolve(img, kernel, result);


Instead of feed the kernel matrix by hand is possible to create a function to compute it. I found a code in the past but I'm not able to find it again, I'm sorry. By the way, hope it helped.

( 2019-05-19 11:12:18 -0500 )edit

I have generated the Gaussian kernels (using function) by myself and I add padding to image by using copyMakeBorder and convolve with the generated kernels. But the result is different and get unintended results. New question. I asked the new question in this link. And one more thing, is that cuda::Convolution only accept double type?

( 2019-05-20 06:46:01 -0500 )edit

Ok, I'll check the new question the next days since I'm a little bit busy till wednesday. Regarding the type, check the documentation according to your OpenCV version. For mine, it says:

image   Source image. Only CV_32FC1 images are supported for now.
templ   Template image. The size is not greater than the image size. The type is the same as image.
`

So, only float are accepted in the CUDA implementation (CV_32FC1). My fault, you need to change the code I supplied before to use float instead of double.

( 2019-05-20 08:08:50 -0500 )edit

@HYPEREGO Thank you for your time. It was the same as mine.

( 2019-05-20 19:40:49 -0500 )edit

Official site

GitHub

Wiki

Documentation

## Stats

Seen: 338 times

Last updated: May 17 '19