/IntensityFeatures/fspecial3.m

https://github.com/nnmm/spineDetection · MATLAB · 171 lines · 151 code · 13 blank · 7 comment · 20 complexity · 4918d6f0d2cb15b3a0e7194aa6f71c9f MD5 · raw file

  1. function h = fspecial3(type,siz,dir)
  2. % Created by Manuel Berning to produce 3D filters
  3. %added:
  4. %dog: difference of gaussians, second gaussian has a width that is 2/3 of
  5. %the first one
  6. %gaussiangradient1/2: filter that applied to an image gives the
  7. %first/second derivative wrt to dir (two direction to be specified for the
  8. %second derivative) of the gaussian-smoothed image
  9. if nargin < 3
  10. dir = [];
  11. end
  12. switch type
  13. case 'cubeAverage'
  14. h = ones(siz,siz,siz)/prod([siz siz siz]);
  15. case 'sphereAverage'
  16. R = siz/2;
  17. R(R==0) = 1;
  18. h = ones(siz,siz,siz);
  19. siz = (siz-1)/2;
  20. [x,y,z] = ndgrid(-siz:siz,-siz:siz,-siz:siz);
  21. I = (x.*x/R^2+y.*y/R^2+z.*z/R^2)>1;
  22. h(I) = 0;
  23. h = h/sum(h(:));
  24. case 'gaussianFWHMhalfSize'
  25. sig = siz/(4*sqrt(2*log(2)));
  26. siz = (siz-1)/2;
  27. [x,y,z] = ndgrid(-siz:siz,-siz:siz,-siz:siz);
  28. h = exp(-(x.*x/2/sig^2 + y.*y/2/sig^2 + z.*z/2/sig^2));
  29. h = h/sum(h(:));
  30. case 'laplacian'
  31. if siz < 3
  32. error('Discrete Laplacian with size per dimension < 3 not defined');
  33. else
  34. siz = siz + [2 2 2];
  35. h = zeros(siz);
  36. h([1 end],:,:) = 1;
  37. h(:,[1 end],:) = 1;
  38. h(:,:,[1 end]) = 1;
  39. h = bwdist(h);
  40. h([1 end],:,:) = [];
  41. h(:,[1 end],:) = [];
  42. h(:,:,[1 end]) = [];
  43. if rem(siz,2) == 0
  44. mid = (siz-2)/2;
  45. h(mid:mid+1, mid:mid+1, mid:mid+1) = 0;
  46. h(mid:mid+1, mid:mid+1, mid:mid+1) = repmat(-sum(h(:)),[2 2 2]);
  47. h = double(h);
  48. else
  49. mid = ceil((siz-2)/2);
  50. h(mid, mid, mid) = 0;
  51. h(mid, mid, mid) = sum(-h(:));
  52. h = double(h);
  53. end
  54. end
  55. case 'log'
  56. if siz < 3
  57. error('Laplacian of Gaussian Filter with size per dimension < 3 not defined');
  58. else
  59. sig = siz/(4*sqrt(2*log(2)));
  60. siz = (siz-1)/2;
  61. [x,y,z] = ndgrid(-siz:siz,-siz:siz,-siz:siz);
  62. h = exp(-(x.*x/2/sig^2 + y.*y/2/sig^2 + z.*z/2/sig^2));
  63. h = h/sum(h(:));
  64. arg = (x.*x/sig^4 + y.*y/sig^4 + z.*z/sig^4 - ...
  65. (1/sig^2 + 1/sig^2 + 1/sig^2));
  66. h = arg.*h;
  67. h = h/sum(h(:));
  68. end
  69. case 'dog'
  70. sig1=siz/(4*sqrt(2*log(2)));
  71. sig2=sig1*0.66;
  72. dsig=sig1-sig2;
  73. siz=(siz-1)/2;
  74. [x,y,z] = ndgrid(-siz:siz,-siz:siz,-siz:siz);
  75. h1 = exp(-(x.*x/2/sig1^2 + y.*y/2/sig1^2 + z.*z/2/sig1^2));
  76. h1 = h1/sum(h1(:));
  77. h2 = exp(-(x.*x/2/sig2^2 + y.*y/2/sig2^2 + z.*z/2/sig2^2));
  78. h2 = h2/sum(h2(:));
  79. h=(sig1-dsig/2)/dsig*(h1-h2);
  80. case 'gradient'
  81. if siz < 3
  82. error('Gradient Filter with size per dimension < 3 not defined');
  83. elseif isempty(dir)
  84. error('Specifiy direction for gradient!');
  85. else
  86. if rem(siz,2) == 0
  87. mid = siz/2-0.5;
  88. a= (-mid:mid)';
  89. else
  90. mid = floor(siz/2);
  91. a = (-mid:mid)';
  92. end
  93. b = ones(1,siz,1);
  94. switch dir
  95. case 1
  96. h = repmat(a * b, [1 1 siz]);
  97. case 2
  98. h = repmat(reshape(a * b, 1, siz, siz), [siz 1 1]);
  99. case 3
  100. h = repmat(reshape((a * b)', 1, siz, siz), [siz 1 1]);
  101. otherwise
  102. error('Only implemented for 3 axis aligned dimensions.')
  103. end
  104. end
  105. case 'gaussgradient1'
  106. if isempty(dir)
  107. error('Specify direction for gradient!');
  108. else
  109. sig = siz/(4*sqrt(2*log(2)));
  110. siz = (siz-1)/2;
  111. [x,y,z] = ndgrid(-siz:siz,-siz:siz,-siz:siz);
  112. h = exp(-(x.*x/2/sig^2 + y.*y/2/sig^2 + z.*z/2/sig^2));
  113. h = h/sum(h(:));
  114. switch dir
  115. case 1
  116. h=-x.*h/sig^2;
  117. case 2
  118. h=-y.*h/sig^2;
  119. case 3
  120. h=-z.*h/sig^2;
  121. otherwise
  122. error('Only implemented for 3 axis aligned dimensions.')
  123. end
  124. end
  125. case 'gaussgradient2'
  126. if isempty(dir)
  127. error('Specify direction of the gradient!');
  128. else
  129. sig = siz/(4*sqrt(2*log(2)));
  130. siz = (siz-1)/2;
  131. [x,y,z] = ndgrid(-siz:siz,-siz:siz,-siz:siz);
  132. h = exp(-(x.*x/2/sig^2 + y.*y/2/sig^2 + z.*z/2/sig^2));
  133. h = h/sum(h(:));
  134. switch dir
  135. case 11
  136. h=h.*(x.^2-sig^2)/sig^4;
  137. case 22
  138. h=h.*(y.^2-sig^2)/sig^4;
  139. case 33
  140. h=h.*(z.^2-sig^2)/sig^4;
  141. case 12
  142. h=h.*(x.*y)/sig^4;
  143. case 13
  144. h=h.*(x.*z)/sig^4;
  145. case 23
  146. h=h.*(y.*z)/sig^4;
  147. otherwise
  148. error('For a second derivative two directions have to be specified.')
  149. end
  150. end
  151. otherwise
  152. error('Unknown filter type.')
  153. end