📄 cannyedgedetector.mht
字号:
From: <Saved by Windows Internet Explorer 7>
Subject:
Date: Sun, 1 Feb 2009 20:32:13 +0530
MIME-Version: 1.0
Content-Type: text/html;
charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://www.mathworks.com/matlabcentral/fx_files/22714/2/CannyEdgeDetector.m
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5579
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Dwindows-1252">
<META content=3D"MSHTML 6.00.6000.16788" name=3DGENERATOR></HEAD>
<BODY><PRE>function varargout =3D CannyEdgeDetector(varargin)
% CannyEdgeDetector Detects edges in the intensity image.
% imo =3D CannyEdgeDetector(imi) takes the intensity image imi as =
input
% and returns a binary image imo with the same size as imi, where =
1's
% are the edge pixels detected by Canny's method (default). The =
default
% value for the thresholds are specified as
% 0.3*max(GradientMagnitudeImage), 0.1*max(GradientMagnitudeImage) =
and
% 1 for high and low thresholds and sigma for Gaussian kernel,
% respectively. There are also some additional features listed as
% below:
% =20
% imo =3D CannyEdgeDetector(imi,method) takes an additional string=20
% 'method' as input which specifies the function to detect the edges =
% whether using Canny's method, or Laplacian of Gaussian. The =
possible=20
% valid entries for method input are 'canny' and 'log'. The default=20
% threshold value for log method is automatically chosen by 'edge'=20
% function, which is present in "Image Processing Toolbox".
% =20
% imo =3D CannyEdgeDetector(imi,sigma) returns the same output as=20
% described at the top, only with the specified sigma value for
% Gaussian kernel in stead of the default value. The default value =
for
% method is 'canny'.
% =20
% imo =3D CannyEdgeDetector(imi,sigma,method) returns the edge =
detected=20
% binary image imo, with the specified sigma value and the specified =
% method, in stead of the defaults.
% =20
% imo =3D CannyEdgeDetector(...,Th) returns the same output as =
described
% above, with an additional input to specify the threshold for 'log'
% method, or the high threshold for 'canny'. In the second case, the
% low threshold is 1/3 of Th by default.
% =20
% imo =3D CannyEdgeDetector(...,Th,Tl) takes an additional input Tl,
% which specifies the low threshold in case of Canny's method. When =
the
% method input is 'log', this usage is invalid and the function will
% return an error message.
% =20
% imo =3D CannyEdgeDetector(...,Th,Tl,feature) In the case of =
Canny's
% method, there are two distinct ways to apply hysteresis =
thresholding
% defined. The first one is a recursive search (namely, depth first
% search), and the second one is to use some morphological =
operations.
% Obviously, the recursive method takes longer to operate. The =
string
% input 'feature' specifies which one to use. Valid options for this
% input are 'dfs' and 'morph'. It is defined as 'dfs' by default. In
% the case of log method, this usage is invalid and will return an
% error message.
%=20
% CannyEdgeDetector(...) usage (without the output arguments) plots =
the
% binary image using imshow, in stead of making any assignments.
% =20
% Author: Halim Can ALBASAN
% =20
% Written for the term project of the course "Robot Vision" (EE701)
% given in Middle East Technical University, Ankara, Turkey; by the=20
% lecturer A. Aydin Alatan.
% =20
% Date: 15/06/2008=20
[imi,sigma,method,Th,Tl,feature] =3D parse_inputs (varargin{:});
switch method
case 'canny'
=20
%% Detection of Gaussian kernel size ( 3 <=3D N <=3D 15 )
G =3D gaussmf (-10:10,[sigma 0]);
ind =3D find (G<=3D.1);
if length(ind)<=3D6
N =3D 15; % Upper boundary
warning('MATLAB:LargeSigma','Sigma too large!')
=20
elseif length(ind)>=3D18
N =3D 3; % Lower boundary
warning('MATLAB:SmallSigma','Sigma too small!')
else
G(ind) =3D [];
N =3D length (G);
end
%% Gaussian kernel and its first derivatives ( horizontal (Gh) and =
vertical
%% (Gv) )
G =3D fspecial ('gaussian', [N N], sigma);
[Gh,Gv] =3D gradient(G);
%% Applying the operators to the image and obtaining the gradient
%% magnitudes and directions
imx =3D conv2(double(imi),Gh);
imx =3D imx =
((N-1)/2+1:size(imx,1)-(N-1)/2,(N-1)/2+1:size(imx,2)-(N-1)/2);
imy =3D conv2(double(imi),Gv);
imy =3D imy =
((N-1)/2+1:size(imy,1)-(N-1)/2,(N-1)/2+1:size(imy,2)-(N-1)/2);
gra_mag =3D sqrt(imx.^2+imy.^2);
gra_dir =3D atan2(imy,imx);
%% Gradient direction discretization
[r c] =3D size (gra_dir);
for i=3D1:r
for j=3D1:c
if ( gra_dir(i,j)<pi/8 && gra_dir(i,j)>=3D0 ) ...
|| ( gra_dir(i,j)<=3D2*pi && =
gra_dir(i,j)>=3D15*pi/8 ) ...
|| ( gra_dir(i,j)<9*pi/8 && =
gra_dir(i,j)>=3D7*pi/8 )
gra_dir(i,j) =3D 0;
elseif ( gra_dir(i,j)>=3Dpi/8 && =
gra_dir(i,j)<3*pi/8 ) ...
|| ( gra_dir(i,j)>=3D9*pi/8 && =
gra_dir(i,j)<11*pi/8 )
gra_dir(i,j) =3D 45;
elseif ( gra_dir(i,j)>=3D3*pi/8 && =
gra_dir(i,j)<5*pi/8 ) ...
|| ( gra_dir(i,j)>=3D11*pi/8 && =
gra_dir(i,j)<13*pi/8)
gra_dir(i,j) =3D 90;
else
gra_dir(i,j) =3D 135;
end
end
end
%% Nonmaxima suppression
gra_mag_s =3D gra_mag;
gra_mag_s(1,:) =3D zeros (1,c);
gra_mag_s(r,:) =3D zeros (1,c);
gra_mag_s(:,1) =3D zeros (r,1);
gra_mag_s(:,c) =3D zeros (r,1); % Suppress boundaries first
for i=3D2:r-1
for j=3D2:c-1
if gra_dir(i,j)=3D=3D0
if ( gra_mag(i,j)<=3Dgra_mag(i,j+1) ) ...
|| ( gra_mag(i,j)<=3Dgra_mag(i,j-1) )
gra_mag_s(i,j) =3D 0;
end
elseif gra_dir(i,j)=3D=3D45
if ( gra_mag(i,j)<=3Dgra_mag(i-1,j+1) ) ...
|| ( gra_mag(i,j)<=3Dgra_mag(i+1,j-1) )
gra_mag_s(i,j) =3D 0;
end
elseif gra_dir(i,j)=3D=3D90
if ( gra_mag(i,j)<=3Dgra_mag(i+1,j) ) ...
|| ( gra_mag(i,j)<=3Dgra_mag(i-1,j) )
gra_mag_s(i,j) =3D 0;
end
else
if ( gra_mag(i,j)<=3Dgra_mag(i+1,j+1) ) ...
|| ( gra_mag(i,j)<=3Dgra_mag(i-1,j-1) )
gra_mag_s(i,j) =3D 0;
end
end
end
end
%% Hysteresis thresholding and forming the output image
if isempty(Th)
Tl =3D .10*max(max(gra_mag_s));
Th =3D .30*max(max(gra_mag_s));
end
h_thr_im =3D gra_mag_s;
h_thr_im(gra_mag_s<Th) =3D 0;
l_thr_im =3D gra_mag_s;
l_thr_im(gra_mag_s<Tl) =3D 0;
switch feature
case 'morph'
=20
h_thr_im =3D logical(h_thr_im);
l_thr_im =3D logical(l_thr_im);
[ii jj] =3D find(h_thr_im);
imo =3D bwselect(l_thr_im , jj , ii , 8);
imo =3D bwmorph(imo , 'thin' , 1);
case 'dfs'
=20
for i=3D2:r-1
for j=3D2:c-1
if h_thr_im (i,j)>0
h_thr_im =3D edge_follow(h_thr_im,l_thr_im,i,j);
end
end
end
imo =3D logical(h_thr_im);
end
=20
case 'log'
=20
imo =3D edge(imi,method,Th,sigma);
end
if nargout<1
imshow(imo)
else
varargout{1} =3D imo;
end
function thr_h =3D edge_follow(thr_h,thr_l,i,j)
=20
x =3D [-1 0 1 -1 1 -1 0 1]; % Relative coordinates =
of 8 neighbors
y =3D [-1 -1 -1 0 0 1 1 1];
=20
=20
for k=3D1:8
if thr_h(i+x(k),j+y(k))=3D=3D0 && =
thr_l(i+x(k),j+y(k))~=3D0
thr_h(i+x(k),j+y(k)) =3D -thr_l(i+x(k),j+y(k));
thr_h =3D edge_follow(thr_h,thr_l,i+x(k),j+y(k));
end
end
end
function [imi,sigma,method,Th,Tl,feature] =3D parse_inputs(varargin)
=20
imi =3D varargin{1};
sigma =3D 1; % defaults
method =3D 'canny';
Th =3D []; % the defaults for the thresholds will =
be=20
Tl =3D []; % specified after the gradient =
magnitude is=20
feature =3D 'dfs'; % calculated.
=20
methods =3D {'canny','log'};
features =3D {'dfs','morph'};
sigma_default =3D false;
=20
if nargin<1
error('Not enough input arguments.')
end
=20
if nargin>=3D2
=20
if ischar(varargin{2})
if length(strmatch(varargin{2},methods))~=3D1
error('Wrong input for edge detection method')
else
method=3Dvarargin{2};
sigma_default =3D true;
end
=20
else
sigma=3Dvarargin{2};
end
end
=20
if nargin>=3D3
=20
if sigma_default
Th =3D varargin{3};
Tl =3D Th/3;
else
if length(strmatch(varargin{3},methods))~=3D1
error('Wrong input for edge detection method')
else
method=3Dvarargin{3};
end
end
end
=20
if nargin>=3D4
=20
if sigma_default
if strcmp(method,'canny')
Tl =3D varargin{4};
else
error('Wrong sequence or number of inputs for "log" =
method')
end
else
Th =3D varargin{4};
end
end
=20
if nargin>=3D5
if strcmp(method,'log')
error('Too many input arguments!')
else
if sigma_default
if ischar(varargin{5})
if length(strmatch(varargin{5},features))~=3D1
error('Wrong input for hysteresis thresholding =
method')
else
feature =3D varargin{5};
end
else
error('Wrong usage of input argument "feature"!')
end
else
Tl =3D varargin{5};
end
end
end
=20
if nargin>=3D6
if sigma_default
error('Too many input arguments!')
else
if ischar(varargin{6})
if length(strmatch(varargin{6},features))~=3D1
error('Wrong input for hysteresis thresholding =
method')
else
feature =3D varargin{5};
end
else
error('Wrong usage of input argument "feature"!')
end
end
end
=20
if nargin>6
error('Too many input arguments')
end
end
end</PRE></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -