?? boundaries.m
字號:
function B = boundaries(BW, conn, dir)
%BOUNDARIES Trace object boundaries.
% B = BOUNDARIES(BW) traces the exterior boundaries of objects in
% the binary image BW. B is a P-by-1 cell array, where P is the
% number of objects in the image. Each cell contains a Q-by-2
% matrix, each row of which contains the row and column coordinates
% of a boundary pixel. Q is the number of boundary pixels for the
% corresponding object. Object boundaries are traced in the
% clockwise direction.
%
% B = BOUNDARIES(BW, CONN) specifies the connectivity to use when
% tracing boundaries. CONN may be either 8 or 4. The default
% value for CONN is 8.
%
% B = BOUNDARIES(BW, CONN, DIR) specifies the direction used for
% tracing boundaries. DIR should be either 'cw' (trace boundaries
% clockwise) or 'ccw' (trace boundaries counterclockwise). If DIR
% is omitted BOUNDARIES traces in the clockwise direction.
% Copyright 2002-2004 R. C. Gonzalez, R. E. Woods, & S. L. Eddins
% Digital Image Processing Using MATLAB, Prentice-Hall, 2004
% $Revision: 1.6 $ $Date: 2003/11/21 14:22:07 $
if nargin < 3
dir = 'cw';
end
if nargin < 2
conn = 8;
end
L = bwlabel(BW, conn);
% The number of objects is the maximum value of L. Initialize the
% cell array B so that each cell initially contains a 0-by-2 matrix.
numObjects = max(L(:));
if numObjects > 0
B = {zeros(0, 2)};
B = repmat(B, numObjects, 1);
else
B = {};
end
% Pad label matrix with zeros. This lets us write the
% boundary-following loop without worrying about going off the edge
% of the image.
Lp = padarray(L, [1 1], 0, 'both');
% Compute the linear indexing offsets to take us from a pixel to its
% neighbors.
M = size(Lp, 1);
if conn == 8
% Order is N NE E SE S SW W NW.
offsets = [-1, M - 1, M, M + 1, 1, -M + 1, -M, -M-1];
else
% Order is N E S W.
offsets = [-1, M, 1, -M];
end
% next_search_direction_lut is a lookup table. Given the direction
% from pixel k to pixel k+1, what is the direction to start with when
% examining the neighborhood of pixel k+1?
if conn == 8
next_search_direction_lut = [8 8 2 2 4 4 6 6];
else
next_search_direction_lut = [4 1 2 3];
end
% next_direction_lut is a lookup table. Given that we just looked at
% neighbor in a given direction, which neighbor do we look at next?
if conn == 8
next_direction_lut = [2 3 4 5 6 7 8 1];
else
next_direction_lut = [2 3 4 1];
end
% Values used for marking the starting and boundary pixels.
START = -1;
BOUNDARY = -2;
% Initialize scratch space in which to record the boundary pixels as
% well as follow the boundary.
scratch = zeros(100, 1);
% Find candidate starting locations for boundaries.
[rr, cc] = find((Lp(2:end-1, :) > 0) & (Lp(1:end-2, :) == 0));
rr = rr + 1;
for k = 1:length(rr)
r = rr(k);
c = cc(k);
if (Lp(r,c) > 0) & (Lp(r - 1, c) == 0) & isempty(B{Lp(r, c)})
% We've found the start of the next boundary. Compute its
% linear offset, record which boundary it is, mark it, and
% initialize the counter for the number of boundary pixels.
idx = (c-1)*size(Lp, 1) + r;
which = Lp(idx);
scratch(1) = idx;
Lp(idx) = START;
numPixels = 1;
currentPixel = idx;
initial_departure_direction = [];
done = 0;
next_search_direction = 2;
while ~done
% Find the next boundary pixel.
direction = next_search_direction;
found_next_pixel = 0;
for k = 1:length(offsets)
neighbor = currentPixel + offsets(direction);
if Lp(neighbor) ~= 0
% Found the next boundary pixel.
if (Lp(currentPixel) == START) & ...
isempty(initial_departure_direction)
% We are making the initial departure from
% the starting pixel.
initial_departure_direction = direction;
elseif (Lp(currentPixel) == START) & ...
(initial_departure_direction == direction)
% We are about to retrace our path.
% That means we're done.
done = 1;
found_next_pixel = 1;
break;
end
% Take the next step along the boundary.
next_search_direction = ...
next_search_direction_lut(direction);
found_next_pixel = 1;
numPixels = numPixels + 1;
if numPixels > size(scratch, 1)
% Double the scratch space.
scratch(2*size(scratch, 1)) = 0;
end
scratch(numPixels) = neighbor;
if Lp(neighbor) ~= START
Lp(neighbor) = BOUNDARY;
end
currentPixel = neighbor;
break;
end
direction = next_direction_lut(direction);
end
if ~found_next_pixel
% If there is no next neighbor, the object must just
% have a single pixel.
numPixels = 2;
scratch(2) = scratch(1);
done = 1;
end
end
% Convert linear indices to row-column coordinates and save
% in the output cell array.
[row, col] = ind2sub(size(Lp), scratch(1:numPixels));
B{which} = [row - 1, col - 1];
end
end
if strcmp(dir, 'ccw')
for k = 1:length(B)
B{k} = B{k}(end:-1:1, :);
end
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -