Switch to side-by-side view

--- a
+++ b/functions/functions_Kovesi/derivative5.m
@@ -0,0 +1,112 @@
+% DERIVATIVE5 - 5-Tap 1st and 2nd discrete derivatives
+%
+% This function computes 1st and 2nd derivatives of an image using the 5-tap
+% coefficients given by Farid and Simoncelli.  The results are significantly
+% more accurate than MATLAB's GRADIENT function on edges that are at angles
+% other than vertical or horizontal. This in turn improves gradient orientation
+% estimation enormously.  If you are after extreme accuracy try using DERIVATIVE7.
+%
+% Usage:  [gx, gy, gxx, gyy, gxy] = derivative5(im, derivative specifiers)
+%
+% Arguments:
+%                       im - Image to compute derivatives from.
+%    derivative specifiers - A comma separated list of character strings
+%                            that can be any of 'x', 'y', 'xx', 'yy' or 'xy'
+%                            These can be in any order, the order of the
+%                            computed output arguments will match the order
+%                            of the derivative specifier strings.
+% Returns:
+%  Function returns requested derivatives which can be:
+%     gx, gy   - 1st derivative in x and y
+%     gxx, gyy - 2nd derivative in x and y
+%     gxy      - 1st derivative in y of 1st derivative in x
+%
+%  Examples:
+%    Just compute 1st derivatives in x and y
+%    [gx, gy] = derivative5(im, 'x', 'y');  
+%                                           
+%    Compute 2nd derivative in x, 1st derivative in y and 2nd derivative in y
+%    [gxx, gy, gyy] = derivative5(im, 'xx', 'y', 'yy')
+%
+% See also: DERIVATIVE7
+
+% Reference: Hany Farid and Eero Simoncelli "Differentiation of Discrete
+% Multi-Dimensional Signals" IEEE Trans. Image Processing. 13(4): 496-508 (2004)
+
+% Copyright (c) 2010 Peter Kovesi
+% Centre for Exploration Targeting
+% The University of Western Australia
+% peterkovesi.com
+% 
+% Permission is hereby granted, free of charge, to any person obtaining a copy
+% of this software and associated documentation files (the "Software"), to deal
+% in the Software without restriction, subject to the following conditions:
+% 
+% The above copyright notice and this permission notice shall be included in 
+% all copies or substantial portions of the Software.
+%
+% The Software is provided "as is", without warranty of any kind.
+%
+% April 2010
+
+function varargout = derivative5(im, varargin)
+
+    varargin = varargin(:);
+    varargout = cell(size(varargin));
+    
+    % Check if we are just computing 1st derivatives.  If so use the
+    % interpolant and derivative filters optimized for 1st derivatives, else
+    % use 2nd derivative filters and interpolant coefficients.
+    % Detection is done by seeing if any of the derivative specifier
+    % arguments is longer than 1 char, this implies 2nd derivative needed.
+    secondDeriv = false;    
+    for n = 1:length(varargin)
+        if length(varargin{n}) > 1
+            secondDeriv = true;
+            break
+        end
+    end
+    
+    if ~secondDeriv
+        % 5 tap 1st derivative cofficients.  These are optimal if you are just
+        % seeking the 1st deriavtives
+        p = [0.037659  0.249153  0.426375  0.249153  0.037659];
+        d1 =[0.109604  0.276691  0.000000 -0.276691 -0.109604];
+    else         
+        % 5-tap 2nd derivative coefficients. The associated 1st derivative
+        % coefficients are not quite as optimal as the ones above but are
+        % consistent with the 2nd derivative interpolator p and thus are
+        % appropriate to use if you are after both 1st and 2nd derivatives.
+        p  = [0.030320  0.249724  0.439911  0.249724  0.030320];
+        d1 = [0.104550  0.292315  0.000000 -0.292315 -0.104550];
+        d2 = [0.232905  0.002668 -0.471147  0.002668  0.232905];
+    end
+
+    % Compute derivatives.  Note that in the 1st call below MATLAB's conv2
+    % function performs a 1D convolution down the columns using p then a 1D
+    % convolution along the rows using d1. etc etc.
+    gx = false;
+    
+    for n = 1:length(varargin)
+      if strcmpi('x', varargin{n})
+          varargout{n} = conv2(p, d1, im, 'same');    
+          gx = true;   % Record that gx is available for gxy if needed
+          gxn = n;
+      elseif strcmpi('y', varargin{n})
+          varargout{n} = conv2(d1, p, im, 'same');
+      elseif strcmpi('xx', varargin{n})
+          varargout{n} = conv2(p, d2, im, 'same');    
+      elseif strcmpi('yy', varargin{n})
+          varargout{n} = conv2(d2, p, im, 'same');
+      elseif strcmpi('xy', varargin{n}) || strcmpi('yx', varargin{n})
+          if gx
+              varargout{n} = conv2(d1, p, varargout{gxn}, 'same');
+          else
+              gx = conv2(p, d1, im, 'same');    
+              varargout{n} = conv2(d1, p, gx, 'same');
+          end
+      else
+          error('''%s'' is an unrecognized derivative option',varargin{n});
+      end
+    end
+