GRDMASK - Mask-based directional derivatives of an image.

Contents

Description

Apply classical gradient operators using local difference masks.

Syntax

  [Gx,Gy] = GRDMASK(I);
  [Gx,Gy] = GRDMASK(I, method, map, axis);

Inputs

I : input 2D image with size (X,Y,C), with C>1 for multispectral image.

method : (optional) parameter defining the original (3,3) gradient mask used for estimating the directional derivatives [GW02]; classical masks include: * 'sob' or 'sobel' for Sobel masks in i- and j-directions (see option axis below), * 'kir' or 'kirsch' for Kirsch mask, * 'prew' or 'prewitt' for Prewitt mask, * 'iso' or 'isotropic' for Frei-Chen's isotropic mask, * 'opt' or 'optimal' for Ando's optimal mask, * 'ori' or 'orientation' for optimized orientation invariant filter, * 'circ' or 'circular' for Davies' circular mask, * 'rob' or 'robinson' for Robinson mask,

finite difference schemes are also implemented as:

but are not very accurate when further used for the detection of edges that are at angles other than vertical or horizontal [Fleck92], therefore improvements have been proposed in [FS04] and are here implemented through the call to P.Kovesi's functions [KOVESI] as:

    default: |method='sob'|.

map : (optional) logical map (with size (X,Y)) defining the pixels of the input image domain where the gradient is to be computed; set to false where no gradient needs to be output; in this case, the function GRDMASKMAP_BASE is called; default: map=[], ie. considered to be true everywhere and the function GRDMASK_BASE is called.

axis : (optional) string indicating the direction/orientation of the output directional derivatives, it is either 'ij' or 'xy'; default: axis='ij' (right-handed coordinate system), ie. the vector orthogonal to the (real) gradient is output: gx is in that case the vertical derivative, and gy, the horizontal derivative.

Outputs

Gx, Gy : directional derivatives in vertical and horizontal directions resp. in the case axis='ij', the opposite in the case axis='xy'.

References

[Fleck92] M.M. Fleck: "Some defects in finite-difference edge finders", IEEE Trans. Pattern Analysis and Machine Intelligence, 14(3):337-345, 1992. http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=120328&tag=1

[GW02] R.C. Gonzales and R.E. Woods: "Digital Image Processing", Prentice Hall, 2002.

[FS04] H. Farid and E. Simoncelli: "Differentiation of discrete multi- dimensional signals", IEEE Trans. Image Processing, 13(4):496-508, 2004. http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1284386

[KOVESI] P.D. Kovesi: "MATLAB and Octave Functions for Computer Vision and Image Processing", The University of Western Australia, available at http://www.csse.uwa.edu.au/~pk/research/matlabfns/.

Acknowledgments

Options 'derivative5' and 'derivative7' call the resp. functions of P.Kovesi's toolboox available at: http://www.csse.uwa.edu.au/~pk/Research/MatlabFns/.

See also

Ressembles: GRDSMOOTH, GRADIENT. Requires: GRDMASK_BASE, GRDMASKMAP_BASE.

Function implementation

function [Gx,Gy] = grdmask(I, varargin)

parsing parameters

error(nargchk(1, 12, nargin, 'struct'));
error(nargoutchk(1, 2, nargout, 'struct'));

if ~isnumeric(I)
    error('grdmask:inputerror','a matrix is required in input');
end

p = createParser('GRDMASK');
p.addOptional('method', 'sobel', @(x)ischar(x) && ...
    any(strcmpi(x,{'matlab','diff','difference', 'backward','back', 'forward','for',...
    'prewitt','prew', 'kirsch','kir', 'robinson','rob', 'circular','circ',...
    'optimal','opt', 'ori','orientation', 'isotropic','iso', 'sobel','sob', ...
    'roberts', 'derivative5','tap5', 'derivative7','tap7'})));
p.addOptional('map',[],@(x)isnumeric(x) || islogical(x));
p.addOptional('axis','ij',@(x)ischar(x) && any(strcmpi(x,{'ij','xy'})));

% parse and validate all input arguments
p.parse(varargin{:});
p = getvarParser(p);

check parameters

if any(strcmpi(p.method,{'derivative5','tap5', 'derivative7','tap7'}))
    error('grdmask:methoderror', ...
        'Kovesi''s library required with tap coefficients');

elseif ~isempty(p.map) && ~isequal(size(p.map),size(I(:,:,1)))
    error('grdmask:inputerror', ...
        'input map must be same size as the input image domain');
end

main computation

[X,Y,C] = size(I);

if isempty(p.map) || all(p.map(:))
    [Gx,Gy] = grdmask_base(I, p.method, p.axis);
else
    [Gx,Gy] = grdmaskmap_base(I, p.map, p.method, p.axis);
end

display

if p.disp
    figure,
    subplot(1,2,1), imagesc(rescale(Gx,0,1)), axis image off,
    title(['gx - axis ''' p.axis '''']); if C==1,  colormap gray;  end
    subplot(1,2,2), imagesc(rescale(Gy,0,1)), axis image off,
    title(['gy - axis ''' p.axis '''']); if C==1,  colormap gray;  end
    figure,
    imagesc(rescale(I,0,1)), axis image off;    hold on;
    if C==1,  colormap gray;  end
    [X,Y] = meshgrid(3:10:X-2,3:10:Y-2);
    if strcmpi(p.axis,'ij')
        quiver(X, Y, max(Gy(X(1,:),Y(:,1),:),[],3), max(Gx(X(1,:),Y(:,1),:),[],3));
    else
        quiver(X, Y, Gx(X(1,:),Y(:,1)), -Gy(X(1,:),Y(:,1)));
    end
    hold off; title('gradient field')
end
end % end of grdmask