1## Copyright (C) 2013 Brandon Miles <brandon.miles7@gmail.com> 2## 3## This program is free software; you can redistribute it and/or modify it 4## under the terms of the GNU General Public License as published by 5## the Free Software Foundation; either version 3 of the License, or 6## (at your option) any later version. 7## 8## This program is distributed in the hope that it will be useful, 9## but WITHOUT ANY WARRANTY; without even the implied warranty of 10## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11## GNU 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## -*- texinfo -*- 17## @deftypefn {Function File} {[@var{gradMag}, @var{gradDir}] =} imgradient (@var{img}) 18## @deftypefnx {Function File} {[@var{gradMag}, @var{gradDir}] =} imgradient (@var{img}, @var{method}) 19## @deftypefnx {Function File} {[@var{gradMag}, @var{gradDir}] =} imgradient (@var{gx}, @var{gy}) 20## Compute the gradient magnitude and direction in degrees for an image. 21## 22## These are computed from the @var{gx} and @var{xy} gradients using 23## @code{imgradientxy}. The first input @var{img} is a gray scale image to 24## compute the edges on. The second input @var{method} controls the method 25## used to calculate the gradients. Alternatively the first input @var{gx} 26## can be the x gradient and the second input @var{gy} can be the y gradient. 27## 28## The first output @var{gradMag} returns the magnitude of the gradient. 29## The second output @var{gradDir} returns the direction in degrees. 30## 31## The @var{method} input argument must be a string specifying one of the 32## methods supported by @code{imgradientxy}. 33## 34## @seealso{edge, imgradientxy} 35## @end deftypefn 36 37function [gradMag, gradDir] = imgradient (img, method = "sobel") 38 39 if (nargin < 1 || nargin > 2) 40 print_usage (); 41 elseif (ndims (img) != 2) 42 error("imgradient: IMG must be a 2 dimensional matrix"); 43 endif 44 45 if (ischar (method)) 46 [gradX, gradY] = imgradientxy (img, method); 47 else 48 ## we already got gX and gY, just confirm it's good data 49 if (! size_equal (img, method)) 50 error("imgradient: GX and GY must be of equal size") 51 endif 52 gradX = img; 53 gradY = method; 54 endif 55 56 gradMag = sqrt (gradX.^2 + gradY.^2); 57 58 if (nargout > 1) 59 ## Why imgradient invert vertical when computing the angle 60 ## Use atan2(-gy,gx)*pi/180. See http://stackoverflow.com/questions/18549015 61 gradDir = atan2d (-gradY, gradX); 62 endif 63 64endfunction 65 66%!test 67%! A = [0 1 0 68%! 1 1 1 69%! 0 1 0]; 70%! 71%! [gMag, gDir] = imgradient (A); 72%! assert (gMag,[sqrt(18) 4 sqrt(18); 4 0 4; sqrt(18),4,sqrt(18)]); 73%! assert (gDir,[-45 -90 -135; -0 -0 -180; 45 90 135]); 74%! 75%! ## the following just test if passing gx and gy separately gets 76%! ## us the same as the image and method though imgradient 77%! [gxSobel, gySobel] = imgradientxy (A, "Sobel"); 78%! [gxPrewitt, gyPrewitt] = imgradientxy (A, "Prewitt"); 79%! [gxCd, gyCd] = imgradientxy (A, "CentralDifference"); 80%! [gxId, gyId] = imgradientxy (A, "IntermediateDifference"); 81%! 82%! assert (imgradient (A), 83%! imgradient (gxSobel, gySobel)); 84%! assert (imgradient (A, "Sobel"), 85%! imgradient (gxSobel, gySobel)); 86%! assert (imgradient (A, "Prewitt"), 87%! imgradient(gxPrewitt, gyPrewitt)); 88%! assert (imgradient (A, "CentralDifference"), 89%! imgradient (gxCd, gyCd)); 90%! assert (imgradient (A, "IntermediateDifference"), 91%! imgradient (gxId, gyId)); 92 93