fast_gauss.m 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. function Y = fast_gauss( X, sigma, do_norm )
  2. % Low-pass filter image using the Gaussian filter
  3. %
  4. % Y = blur_gaussian( X, sigma, do_norm )
  5. %
  6. % do_norm - normalize the results or not, 'true' by default
  7. %
  8. % Use FFT or spatial domain, whichever is faster
  9. %ksize2 = min(max(3, ceil(((sigma-0.8)/0.3 + 1)*2)), max(size(X))*2);
  10. if( ~exist( 'do_norm', 'var' ) )
  11. do_norm = true;
  12. end
  13. if( do_norm )
  14. norm_f = 1;
  15. else
  16. norm_f = sigma*sqrt(2*pi);
  17. end
  18. if( sigma >= 4.3 ) % Experimentally found threshold when FFT is faster
  19. ks = [size(X,1) size(X,2)]*2;
  20. NF = pi;
  21. % xx = [linspace( 0, NF, ks(2)/2 ) linspace(-NF, 0, ks(2)/2) ];
  22. % yy = [linspace( 0, NF, ks(1)/2 ) linspace(-NF, 0, ks(1)/2) ];
  23. xx = [linspace( 0, NF, ks(2)/2 ) linspace(-NF, -NF/(ks(2)/2), ks(2)/2) ];
  24. yy = [linspace( 0, NF, ks(1)/2 ) linspace(-NF, -NF/(ks(1)/2), ks(1)/2) ];
  25. [XX YY] = meshgrid( xx, yy );
  26. K = exp( -0.5*(XX.^2 + YY.^2)*sigma^2 ) * norm_f;
  27. Y = zeros( size(X) );
  28. for cc=1:size(X,3)
  29. Y(:,:,cc) = fast_conv_fft( X(:,:,cc), K, 'replicate' );
  30. end
  31. else
  32. ksize = round(sigma*5);
  33. h = fspecial( 'gaussian', ksize, sigma ) * norm_f;
  34. Y = imfilter( X, h, 'replicate' );
  35. end
  36. end
  37. function Y = fast_conv_fft( X, fH, pad_value )
  38. % Convolve with a large support kernel in the Fourier domain.
  39. %
  40. % Y = fast_conv_fft( X, fH, pad_value )
  41. %
  42. % X - image to be convolved (in spatial domain)
  43. % fH - filter to convolve with in the Fourier domain, idealy 2x size of X
  44. % pad_value - value to use for padding when expanding X to the size of fH
  45. %
  46. % (C) Rafal Mantiuk <mantiuk@gmail.com>
  47. % This is an experimental code for internal use. Do not redistribute.
  48. pad_size = (size(fH)-size(X));
  49. %mX = mean( X(:) );
  50. fX = fft2( padarray( X, pad_size, pad_value, 'post' ) );
  51. Yl = real(ifft2( fX.*fH, size(fX,1), size(fX,2), 'symmetric' ));
  52. Y = Yl(1:size(X,1),1:size(X,2));
  53. end