]> Creatis software - CreaPhase.git/blobdiff - octave_packages/image-1.0.15/imfilter.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / image-1.0.15 / imfilter.m
diff --git a/octave_packages/image-1.0.15/imfilter.m b/octave_packages/image-1.0.15/imfilter.m
new file mode 100644 (file)
index 0000000..bd4ca49
--- /dev/null
@@ -0,0 +1,129 @@
+## Copyright (C) 2007  Soren Hauberg
+## 
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3, or (at your option)
+## any later version.
+## 
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details. 
+## 
+## You should have received a copy of the GNU General Public License
+## along with this file.  If not, see <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} @var{J} = imfilter(@var{I}, @var{f})
+## @deftypefnx{Function File} @var{J} = imfilter(@var{I}, @var{f}, @var{options}, ...)
+## Computes the linear filtering of the image @var{I} and the filter @var{f}.
+## The computation is performed using double precision floating point numbers,
+## but the class of the input image is preserved as the following example shows.
+## @example
+## I = 255*ones(100, 100, "uint8");
+## f = fspecial("average", 3);
+## J = imfilter(I, f);
+## class(J)
+## @result{} ans = uint8
+## @end example
+##
+## The function also accepts a number of optional arguments that control the
+## details of the filtering. The following options is currently accepted
+## @table @samp
+## @item S
+## If a scalar input argument is given, the image is padded with this scalar
+## as part of the filtering. The default value is 0.
+## @item "symmetric"
+## The image is padded symmetrically. 
+## @item "replicate"
+## The image is padded using the border of the image.
+## @item "circular"
+## The image is padded by circular repeating of the image elements.
+## @item "same"
+## The size of the output image is the same as the input image. This is the default
+## behaviour.
+## @item "full"
+## Returns the full filtering result.
+## @item "corr"
+## The filtering is performed using correlation. This is the default behaviour.
+## @item "conv"
+## The filtering is performed using convolution.
+## @end table
+## @seealso{conv2, filter2, fspecial, padarray}
+## @end deftypefn
+
+function retval = imfilter(im, f, varargin)
+  ## Check number of input arguments
+  if (nargin < 2)
+    print_usage();
+  endif
+  
+  ## Check image
+  if (!ismatrix(im))
+    error("imfilter: first input argument must be an image");
+  endif
+  [imrows, imcols, imchannels, tmp] = size(im);
+  if (tmp != 1 || (imchannels != 1 && imchannels != 3))
+    error("imfilter: first input argument must be an image");
+  endif
+  C = class(im);
+  
+  ## Check filter (XXX: matlab support 3D filter, but I have no idea what they do with them)
+  if (!ismatrix(f))
+    error("imfilter: second input argument must be a matrix");
+  endif
+  [frows, fcols, tmp] = size(f);
+  if (tmp != 1)
+    error("imfilter: second argument must be a 2-dimensional matrix");
+  endif
+  
+  ## Parse options
+  res_size = "same";
+  res_size_options = {"same", "full"};
+  pad = 0;
+  pad_options = {"symmetric", "replicate", "circular"};
+  ftype = "corr";
+  ftype_options = {"corr", "conv"};
+  for i = 1:length(varargin)
+    v = varargin{i};
+    if (any(strcmpi(v, pad_options)) || isscalar(v))
+      pad = v;
+    elseif (any(strcmpi(v, res_size_options)))
+      res_size = v;
+    elseif (any(strcmpi(v, ftype_options)))
+      ftype = v;
+    else
+      warning("imfilter: cannot handle input argument number %d", i+2);
+    endif
+  endfor
+  
+  ## Pad the image
+  im = padarray(im, floor([frows/2, fcols/2]), pad);
+  if (mod(frows,2) == 0)
+    im = im(1:end-1, :, :);
+  endif
+  if (mod(fcols,2) == 0)
+    im = im(:, 1:end-1, :);
+  endif
+  
+  ## Do the filtering
+  if (strcmpi(res_size, "same"))
+    res_size = "valid";
+  else # res_size == "full"
+    res_size = "same";
+  endif
+  if (strcmpi(ftype, "corr"))
+    for i = imchannels:-1:1
+      retval(:,:,i) = filter2(f, im(:,:,i), res_size);
+    endfor
+  else
+    for i = imchannels:-1:1
+      retval(:,:,i) = conv2(im(:,:,i), f, res_size);
+    endfor
+  endif
+  
+  ## Change the class of the output to the class of the input
+  ## (the filtering functions returns doubles)
+  retval = cast(retval, C);
+  
+endfunction