changeset 217:93ec20b95b4a

First revision
author hauberg
date Wed, 27 Dec 2006 19:21:15 +0000
parents 3adc76e1a7c7
children 69bb85145ef5
files inst/fspecial.m
diffstat 1 files changed, 172 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/inst/fspecial.m
@@ -0,0 +1,172 @@
+## Copyright (C) 2005 Søren 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 2 of the License, 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 program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+function [ f ] = fspecial (type, arg1, arg2)
+  if (!ischar(type))
+    error("fspecial: first argument must be a string");
+  endif
+  
+  switch lower(type)
+    case "average"
+      ## Get filtersize
+      if (nargin > 1 && isreal(arg1) && length(arg1(:)) <= 2)
+        fsize = arg1(:);
+      else
+        fsize = 3;
+      endif
+      ## Create the filter
+      f = ones(fsize);
+      ## Normalize the filter to integral 1
+      f = f/sum(f(:));
+
+    case "disk"
+      ## Get the radius
+      if (nargin > 1 && isreal(arg1) && length(arg1(:)) == 1)
+        radius = arg1;
+      else
+        radius = 5;
+      endif
+      ## Create the filter
+      [x,y] = meshgrid(-c2:c2, -r2:r2);
+      r = sqrt(x.^2 + y.^2);
+      f = (r <= radius);
+      ## Normalize the filter to integral 1
+      f = f/sum(f(:));
+
+    case "gaussian"
+      ## Get hsize
+      if (nargin > 1 && isreal(arg1))
+        if (length(arg1(:)) == 1)
+          hsize = [arg1, arg1];
+        elseif (length(arg1(:)) == 2)
+          hsize = arg1;
+        else
+          error("fspecial: second argument must be a scalar or a vector of two scalars");
+        endif
+      else
+        hsize = [3, 3];
+      endif
+      ## Get sigma
+      if (nargin > 2 && isreal(arg2) && length(arg2(:)) == 1)
+        sigma = arg2;
+      else
+        sigma = 0.5;
+      endif
+      h1 = hsize(1)-1; h2 = hsize(2)-1; 
+      [x, y] = meshgrid(0:h2, 0:h1);
+      x = x-h2/2; y = y-h1/2;
+      gauss = exp( -( x.^2 + y.^2 ) / (2*sigma^2) );
+      f = gauss/sum(gauss(:));
+
+    case "laplacian"
+      ## Get alpha
+      if (nargin > 1 && isscalar(arg1))
+        alpha = arg1;
+        if (alpha<0 | alpha>1)
+          error("fspecial: second argument must be between 0 and 1");
+        endif
+      else
+        alpha = 0.2;
+      endif
+      ## Compute filter
+      f = (4/(alpha+1))*[alpha/4, (1-alpha)/4, alpha/4; ...
+                         (1-alpha)/4, -1, (1-alpha)/4;  ...
+                         alpha/4, (1-alpha)/4, alpha/4];
+    case "log"
+      ## Get hsize
+      if (nargin > 1 && isreal(arg1))
+        if (length(arg1(:)) == 1)
+          hsize = [arg1, arg1];
+        elseif (length(arg1(:)) == 2)
+          hsize = arg1;
+        else
+          error("fspecial: second argument must be a scalar or a vector of two scalars");
+        endif
+      else
+        hsize = [5, 5];
+      endif
+      ## Get sigma
+      if (nargin > 2 && isreal(arg2) && length(arg2(:)) == 1)
+        sigma = arg2;
+      else
+        sigma = 0.5;
+      endif
+      ## Compute the filter
+      h1 = hsize(1)-1; h2 = hsize(2)-1; 
+      [x y] = meshgrid(0:h2, 0:h1);
+      x = x-h2/2; y = y = y-h1/2;
+      gauss = exp( -( x.^2 + y.^2 ) / (2*sigma^2) );
+      f = ( (x.^2 + y.^2 - 2*sigma^2).*gauss )/( 2*pi*sigma^6*sum(gauss(:)) );
+
+    case "motion"
+      ## Taken (with some changes) from Peter Kovesis implementation 
+      ## (http://www.csse.uwa.edu.au/~pk/research/matlabfns/OctaveCode/fspecial.m)
+      ## FIXME: The implementation is not quite matlab compatible.
+      if (nargin > 1 && isreal(arg1))
+        len = arg1;
+      else
+        len = 9;
+      endif
+      if (mod(len,2) == 1)
+        sze = [len, len];
+      else
+        sze = [len+1, len+1];
+      end
+      if (nargin > 2 && isreal(arg2))
+        angle = arg2;
+      else
+        angle = 0;
+      endif
+	    
+      ## First generate a horizontal line across the middle
+      f = zeros(sze);
+      f(floor(len/2)+1,1:len) = 1;   
+
+      # Then rotate to specified angle
+      f = imrotate(f, angle, 'bilinear', 'loose');
+      f = f/sum(f(:));
+
+    case "prewitt"
+      ## The filter
+      f = [1 1 1; 0 0 0; -1 -1 -1];
+      
+    case "sobel"
+      ## The filter
+      f = [1 2 1; 0 0 0; -1 -2 -1];
+      
+    case "kirsch"
+      ## The filter
+      f = [3 3 3; 3 0 3; -5 -5 -5];
+    
+    case "unsharp"
+      ## Get alpha
+      if (nargin > 1 && isscalar(arg1))
+        alpha = arg1;
+        if (alpha<0 | alpha>1)
+          error("fspecial: second argument must be between 0 and 1");
+        endif
+      else
+        alpha = 0.2;
+      endif
+      ## Compute filter
+      f = (1/(alpha+1))*[-alpha,  alpha-1, -alpha; ...
+                         alpha-1, alpha+5, alpha-1; ...
+                         -alpha,  alpha-1, -alpha];
+
+    otherwise
+      error("fspecial: filter type '%s' is not supported", type);
+  endswitch
+endfunction