1

I want to do the filter2d() of openCV in freqency domain.

I have read several posts but still it has not become clear to me, how can I get the filtering effect in frequency domain. I have found few posts which tell to convert an image into the frequency domain (i mean, to calculate it's DFT).

I think that I need to do the following steps:

  1. Take an image
  2. Make a filter kernel

    Mat kernel = (Mat_<double>(3,3) <<  1.36, 0.062,  -0.921,
                -0.644198,  1.10, -0.17,
                -0.072951, -1.81485,  2.806);
    
  3. Calculate the DFT of given image
  4. Calculate the DFT of filter kernel
  5. Multiply dft(given image) with dft(filter kernel)
  6. Calculate the inverse-dft of the above multiplication.

I have found the posts which tell about calculating teh DFT of a grayscale image.

Problem: I don't know how do i perform the multipliaction of step-3 and step-4 on GPU because the documentiona says that the two matrices should be of same size.

skm
  • 5,015
  • 8
  • 43
  • 104
  • i doubt, that you need 4), and 5) is [filter2D](http://docs.opencv.org/ref/master/d4/d86/group__imgproc__filter.html#ga27c049795ce870216ddfb366086b5a04) – berak Jun 24 '15 at 13:51
  • @berak: I meant, the multiplication of step-3 and step-4. I think that we need to multiply the DFT of the image with the DFT of the filter to get the required results. Calculating only the DFT of the given image would not do anything. – skm Jun 24 '15 at 13:54
  • afaik, when using filter2D, openCV automatically decides whether to compute DFT (frequency domain) or whether to use image convolution (spatial domain), depending on image size and filter size. – Micka Jun 24 '15 at 14:27
  • from docs: http://docs.opencv.org/modules/imgproc/doc/filtering.html#filter2d `The function uses the DFT-based algorithm in case of sufficiently large kernels (~``11 x 11`` or larger) and the direct algorithm (that uses the engine retrieved by createLinearFilter() ) for small kernels.` – Micka Jun 24 '15 at 14:28
  • @Micka: my kernel is just 3x3 but my image is very big (20 megapixel). So, I think that opencv is not using DFT method because of the small kernel size. Moreover, I debugged the code and found that the opencv took itself to `createLinearfilter()` – skm Jun 24 '15 at 14:51
  • no idea whether DFT of large image is more efficient. BUT you can have a look at filter2D source code and check how openCV computes DFT and sequence domain filtering in case of big filters. Just use that part of the code within your code ;) – Micka Jun 24 '15 at 15:00
  • @Micka: As I mentioned, I have already found the code to compute DFT of an image. The problem is, I don't know how can i multiply the DFT of two images (given image and filter image). – skm Jun 24 '15 at 15:06
  • should all be somewhere within the filter2D code of openCV – Micka Jun 24 '15 at 15:08
  • @anonymous: What is interesting to you about this question? Is it the GPU aspect? I ask because there are a lot of questions on here asking help with convolution through the FFT. For example here: https://stackoverflow.com/q/51200852/7328782 — that answer answers this one as well, with code, except for the GPU aspect. – Cris Luengo Jul 07 '18 at 14:16
  • There's absolutely no need to use DFT, if your filter is just 3x3. It would be much slower this way. Just do the 3x3 convolution in the spatial domain. – geza Jul 09 '18 at 19:12

1 Answers1

2

You do element-wise multiplication of DFT response of both filter and the image. Before you compute FFT, you have to pad the kernel with zeros to make it the same dimension as that of the image. This is why the FFT option is only computationally efficient if the size of the filter is too large or at least comparable to the dimension of the image.

To have a reasonable estimate along the border of the final matrix, you may have to also pad the image by half of the dimension of the filter.

Ajay
  • 360
  • 1
  • 11
  • Do you think that it would be beneficial for me in terms of computational time because my filter size is 3x3 but the image size is really large. – skm Jun 25 '15 at 09:15
  • No, it won't be. It's the relative size that matters. So long as your filter is small, the cost of computing FFT and then inverting it will take away any advantage of just having to do element-wise operation in the frequency domain. In my experience, if your filter size exceeds 15x15, you should start to consider the frequency route. Besides, opencv does the switch for you too if you use cvFilter2D, so may not have to think about it at all. – Ajay Jun 25 '15 at 15:31