-
Notifications
You must be signed in to change notification settings - Fork 0
/
fspecial3.m
109 lines (95 loc) · 3.28 KB
/
fspecial3.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
function h = fspecial3(type,siz)
%FSPECIAL3 Create predefined 3-D filters.
% H = FSPECIAL3(TYPE,SIZE) creates a 3-dimensional filter H of the
% specified type and size. Possible values for TYPE are:
%
% 'average' averaging filter
% 'ellipsoid' ellipsoidal averaging filter
% 'gaussian' Gaussian lowpass filter
% 'laplacian' Laplacian operator
% 'log' Laplacian of Gaussian filter
%
% The default SIZE is [5 5 5]. If SIZE is a scalar then H is a 3D cubic
% filter of dimension SIZE^3.
%
% H = FSPECIAL3('average',SIZE) returns an averaging filter H of size
% SIZE. SIZE can be a 3-element vector specifying the dimensions in
% H or a scalar, in which case H is a cubic matrix.
%
% H = FSPECIAL3('ellipsoid',SIZE) returns an ellipsoidal averaging filter.
%
% H = FSPECIAL3('gaussian',SIZE) returns a centered Gaussian lowpass
% filter of size SIZE with standard deviations defined as SIZE/2/2.354 so
% that FWHM equals half filter size (http://en.wikipedia.org/wiki/FWHM).
%
% H = FSPECIAL3('laplacian') returns a 3-by-3-by-3 filter approximating
% the shape of the three-dimensional Laplacian operator. REMARK: the
% shape of the Laplacian cannot be adjusted. An infinite number of 3D
% Laplacian could be defined. If you know any simple formulation allowing
% one to control the shape, please contact me.
%
% H = FSPECIAL3('log',SIZE) returns a rotationally symmetric Laplacian of
% Gaussian filter of size SIZE with standard deviation defined as
% SIZE/2/2.354.
%
%
% Class Support
% -------------
% H is of class double.
%
% Example
% -------
% I = single(rand(80,40,20));
% h = fspecial3('gaussian',[9 5 3]);
% Inew = imfilter(I,h);
%
% See also IMFILTER, FSPECIAL.
%
% -- Damien Garcia -- 2007/08
type = lower(type);
if nargin==1
siz = 5;
end
if numel(siz)==1
siz = round(repmat(siz,1,3));
elseif numel(siz)~=3
error('Number of elements in SIZ must be 1 or 3')
else
siz = round(siz(:)');
end
switch type
case 'average'
h = ones(siz)/prod(siz);
case 'gaussian'
sig = siz/2/2.354;
siz = (siz-1)/2;
[x,y,z] = ndgrid(-siz(1):siz(1),-siz(2):siz(2),-siz(3):siz(3));
h = exp(-(x.*x/2/sig(1)^2 + y.*y/2/sig(2)^2 + z.*z/2/sig(3)^2));
h = h/sum(h(:));
case 'ellipsoid'
R = siz/2;
h = ones(siz);
siz = (siz-1)/2;
[x,y,z] = ndgrid(-siz(1):siz(1),-siz(2):siz(2),-siz(3):siz(3));
I = (x.*x/R(1)^2+y.*y/R(2)^2+z.*z/R(3)^2)>1;
h(I) = 0;
h = convn(h,ones(2,2,2),'same');
h = h/sum(h(:));
case 'laplacian'
h = zeros(3,3,3);
h(:,:,1) = [0 3 0;3 10 3;0 3 0];
h(:,:,3) = h(:,:,1);
h(:,:,2) = [3 10 3;10 -96 10;3 10 3];
case 'log'
sig = siz/2/2.354;
siz = (siz-1)/2;
[x,y,z] = ndgrid(-siz(1):siz(1),-siz(2):siz(2),-siz(3):siz(3));
h = exp(-(x.*x/2/sig(1)^2 + y.*y/2/sig(2)^2 + z.*z/2/sig(3)^2));
h = h/sum(h(:));
arg = (x.*x/sig(1)^4 + y.*y/sig(2)^4 + z.*z/sig(3)^4 - ...
(1/sig(1)^2 + 1/sig(2)^2 + 1/sig(3)^2));
h = arg.*h;
h = h-sum(h(:))/prod(2*siz+1);
otherwise
error('Unknown filter type.')
end