]> Creatis software - CreaPhase.git/blob - octave_packages/image-1.0.15/ordfiltn.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / image-1.0.15 / ordfiltn.m
1 ## Copyright (C) 2008 Soren Hauberg
2 ##
3 ## This program is free software; you can redistribute it and/or
4 ## modify it under the terms of the GNU General Public License
5 ## as published by the Free Software Foundation; either version 3
6 ## of the License, or (at your option) any later version.
7 ##
8 ## This program is distributed in the hope that it will be useful, but
9 ## WITHOUT ANY WARRANTY; without even the implied warranty of
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 ## General Public License for more details.
12 ##
13 ## You should have received a copy of the GNU General Public License
14 ## along with this program; If not, see <http://www.gnu.org/licenses/>.
15 ##
16 ## This function is based on 'ordfilt2' by Teemu Ikonen which is released under
17 ## GPLv2 or later.
18
19 ## -*- texinfo -*-
20 ## @deftypefn {Function File} {} ordfiltn(@var{A}, @var{nth}, @var{domain}, [@var{S}, @var{padding}])
21 ## Two dimensional ordered filtering.
22 ##
23 ## Ordered filter replaces an element of @var{A} with the @var{nth} 
24 ## element of the sorted set of neighbours defined by the logical 
25 ## (boolean) matrix @var{domain}.
26 ## Neighbour elements are selected to the sort if the corresponding 
27 ## element in the @var{domain} matrix is true.
28 ## 
29 ## The optional variable @var{S} is a matrix of size(@var{domain}). 
30 ## Values of @var{S} corresponding to nonzero values of domain are 
31 ## added to values obtained from @var{A} when doing the sorting.
32 ##
33 ## Optional variable @var{padding} determines how the matrix @var{A} 
34 ## is padded from the edges. See @code{padarray} for details.
35 ## 
36 ## @seealso{ordfilt2, padarray}
37 ## @end deftypefn
38
39
40 ## Author: Teemu Ikonen <tpikonen@pcu.helsinki.fi>
41 ## Created: 5.5.2000
42 ## Keywords: image processing filtering
43
44 function retval = ordfiltn(A, nth, domain, varargin)
45   ## Check input
46   if (nargin < 3)
47     error("ordfiltn: not enough input arguments");
48   endif
49   if (!ismatrix(A))
50     error("ordfiltn: first input must be an array");
51   endif
52   if (!isscalar(nth) || nth <= 0 || nth != round(nth))
53     error("ordfiltn: second input argument must be a positive integer");
54   endif
55   if (!ismatrix(domain) && !isscalar(domain))
56     error("ordfiltn: third input argument must be an array or a scalar");
57   endif
58   if (isscalar(domain) && (domain <= 0 || domain != round(domain)))
59     error("ordfiltn: third input argument must be a positive integer, when it is a scalar");
60   endif
61   if (isscalar(domain))
62     domain = ones(repmat(domain, 1, ndims(A)), "logical");
63   endif
64   
65   if (ndims(A) != ndims(domain))
66     error("ordfiltn: first and second argument must have same dimensionality");
67   endif
68   if (any(size(A) < size(domain)))
69     error("ordfiltn: domain array cannot be larger than the data array");
70   endif    
71
72   ## Parse varargin
73   S = zeros(size(domain));
74   padding = 0;
75   for i=1:length(varargin)
76     a = varargin{:};
77     if (ischar(a) || isscalar(a))
78       padding = a;
79     elseif (ismatrix(a) && size_equal(a, domain))
80       S = a;
81     endif
82   endfor
83
84   ## Make sure 'domain' is logical. The C++ code assumes this.
85   domain = logical(domain);
86
87   ## Pad array
88   pad = floor(size(domain)/2);
89   A = padarray(A, pad, padding);
90   even = ( round(size(domain)/2) == size(domain)/2 );
91   idx = cell(1, ndims(A));
92   for k = 1:ndims(A)
93     idx{k} = (even(k)+1):size(A,k);
94   endfor
95   A = A(idx{:});
96   
97   ## Perform the filtering
98   retval = __spatial_filtering__ (A, domain, "ordered", S, nth);
99 endfunction