📄 cannyedge.txt
字号:
function [eout,thresh] = edge(varargin)
[a,method,thresh,sigma,H,kx,ky] = parse_inputs(varargin{:});
% Transform to a double precision intensity image if necessary
if ~isa(a, 'double')
a = im2double(a);
end
m = size(a,1);
n = size(a,2);
rr = 2:m-1; cc=2:n-1;
% The output edge map:
e = repmat(false, m, n);
if strcmp(method,'canny')
% Magic numbers
GaussianDieOff = .0001;
PercentOfPixelsNotEdges = .7; % Used for selecting thresholds
ThresholdRatio = .4; % Low thresh is this fraction of the high.
% Design the filters - a gaussian and its derivative
pw = 1:30; % possible widths
ssq = sigma*sigma;
width = max(find(exp(-(pw.*pw)/(2*sigma*sigma))>GaussianDieOff));
if isempty(width)
width = 1; % the user entered a really small sigma
end
t = (-width:width);
gau = exp(-(t.*t)/(2*ssq))/(2*pi*ssq); % the gaussian 1D filter
% Find the directional derivative of 2D Gaussian (along X-axis)
% Since the result is symmetric along X, we can get the derivative along
% Y-axis simply by transposing the result for X direction.
[x,y]=meshgrid(-width:width,-width:width);
dgau2D=-x.*exp(-(x.*x+y.*y)/(2*ssq))/(pi*ssq);
% Convolve the filters with the image in each direction
% The canny edge detector first requires convolution with
% 2D gaussian, and then with the derivitave of a gaussian.
% Since gaussian filter is separable, for smoothing, we can use
% two 1D convolutions in order to achieve the effect of convolving
% with 2D Gaussian. We convolve along rows and then columns.
%smooth the image out
aSmooth=imfilter(a,gau,'conv','replicate'); % run the filter accross rows
aSmooth=imfilter(aSmooth,gau','conv','replicate'); % and then accross columns
%apply directional derivatives
ax = imfilter(aSmooth, dgau2D, 'conv','replicate');
ay = imfilter(aSmooth, dgau2D', 'conv','replicate');
mag = sqrt((ax.*ax) + (ay.*ay));
magmax = max(mag(:));
if magmax>0
mag = mag / magmax; % normalize
end
% Select the thresholds
if isempty(thresh)
[counts,x]=imhist(mag, 64);
highThresh = min(find(cumsum(counts) > PercentOfPixelsNotEdges*m*n)) / 64;
lowThresh = ThresholdRatio*highThresh;
thresh = [lowThresh highThresh];
elseif length(thresh)==1
highThresh = thresh;
if thresh>=1
eid = sprintf('Images:%s:thresholdMustBeLessThanOne', mfilename);
msg = 'The threshold must be less than 1.';
error(eid,'%s',msg);
end
lowThresh = ThresholdRatio*thresh;
thresh = [lowThresh highThresh];
elseif length(thresh)==2
lowThresh = thresh(1);
highThresh = thresh(2);
if (lowThresh >= highThresh) | (highThresh >= 1)
eid = sprintf('Images:%s:thresholdOutOfRange', mfilename);
msg = 'Thresh must be [low high], where low < high < 1.';
error(eid,'%s',msg);
end
end
% The next step is to do the non-maximum supression.
% We will accrue indices which specify ON pixels in strong edgemap
% The array e will become the weak edge map.
idxStrong = [];
for dir = 1:4
idxLocalMax = cannyFindLocalMaxima(dir,ax,ay,mag);
idxWeak = idxLocalMax(mag(idxLocalMax) > lowThresh);
e(idxWeak)=1;
idxStrong = [idxStrong; idxWeak(mag(idxWeak) > highThresh)];
end
rstrong = rem(idxStrong-1, m)+1;
cstrong = floor((idxStrong-1)/m)+1;
e = bwselect(e, cstrong, rstrong, 8);
e = bwmorph(e, 'thin', 1); % Thin double (or triple) pixel wide contours
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -