代码
%
These are commands you can use
in
order to test the different region
% based segmentation algorithms. Paste them in the Matlab command window
% and things should work.
% Test the merging algorithm
% Clear everything
clear all
close all
% Go to your image catalog and read your image (exchange with your own
% catalog)
i = double (imread( ' cameraman.tif ' ));
% i = double (rgb2gray(imread( ' mm3.tif ' )));
% Take a look at the image
figure
imshow(i,[min(min(i)) max(max(i))])
% Make initial suggestion for segmented image
tmp_seg = reshape( 1 :prod(size(i)),size(i));
% Test elementary region growing on this image. Try changing the value
% for the criterion and the connectivity. And obviously, try different
% images.
[seg,seg_arr,reg] = region_grow1(i,tmp_seg, 25 , 8 );
% Take a look at the result
map = rand(max(max(seg)), 3 );
figure
imshow(seg,[])
colormap(map)
function [seg,seg_arr,reg_info] = region_grow1(im,seg,criterion,connectivity)
% This function performs basic region growing on an image.
%
% The input arguments are the following:
% im: The image to be segmented
% seg: An initial labelling of the image, typically you would let
% this image be an image where every pixel has its own label
% criterion: The value of the similarity criterion that is used to decide
% between fusion of segments or not.
% connectivity: The connectivity of regions considered for fusion.
%
% The output arguments are the following:
%
% seg: The final segmented image
% seg_arr: A stack of all the segmented images from every
% iteration
% reg_info: A structure containing all the information about
% the different segments.
%
% Copyright Lars Aurdal, The Norwegian Computing Centre
% Get size of input image
rows = size(im, 1 );
cols = size(im, 2 );
% Here comes a slightly tricky part. In order to keep the computation
% time down we need to use s data structure to keep track of information
% about the regions. A MATLAB struct is what we need. Each element in
% the reg_info array of structures holds the size in pixels of the
% element, the mean of the pixels assigned to the element as well as the
% row and column coordinates of all the pixels assigned to the region,
% this is nice to have in order to be able to quickly adress all the
% pixels belonging to a single element.
% Start by initialising
reg_info = struct ( ' size ' ,num2cell(zeros( 1 ,max(max(seg)))),... % Initially we don ' t know their size
' crt ' ,num2cell(zeros( 1 ,max(max(seg)))),... % ...nor their criterion value
' row_coord ' ,[],... % Coordinates go here
' col_coord ' ,[]); % and here
% Now loop over all the pixels in the initial segmented image and gather
% information about the existing regions
for m = 1 :rows
for n = 1 :cols
c_lab = seg(m,n);
reg_info(c_lab).size = reg_info(c_lab).size + 1 ;
% The following calculation of criterion corresponds to a calculation
% of the segment means
reg_info(c_lab).crt = ((reg_info(c_lab).size - 1 ) * reg_info(c_lab).crt + ...
im(m,n)) / reg_info(c_lab).size;
reg_info(c_lab).row_coord = [reg_info(c_lab).row_coord m];
reg_info(c_lab).col_coord = [reg_info(c_lab).col_coord n];
end
end
% Initially we assume that something will change in the first iteration
changed = 1 ;
% Keep track of iterations in order to display this
iter = 0 ;
% Now loop over the segmented image as long as something changes.
while (changed)
% Give user some feedback
disp([ ' Currently in iteration: ' num2str(iter + 1 )]);
% Check if something changes in this iteration
changed = 0 ;
% Now loop
for m = 1 :rows
for n = 1 :cols
% Get the label of the current pixel considered
c_lab = seg(m,n);
% Get the coordinates of the current pixels neighbours. This
% can be done in 4 or 8 connectivity
if (connectivity == 4 )
ngb = get4ngb(rows,cols,m,n);
end
if (connectivity == 8 )
ngb = get8ngb(rows,cols,m,n);
end
% Loop over all these neighbours and check if they should
% receive the same label as the pixel we are currently
% examining
for k = 1 :size(ngb, 2 )
n_lab = seg(ngb( 1 ,k),ngb( 2 ,k));
if (n_lab ~= c_lab)
if (abs(reg_info(n_lab).crt - reg_info(c_lab).crt) < criterion)
% First update the mean of the segment having the
% c_lab label
reg_info(c_lab).crt = (reg_info(c_lab).size * reg_info(c_lab).crt + ...
reg_info(n_lab).size * reg_info(n_lab).crt) / ...
(reg_info(c_lab).size + reg_info(n_lab).size);
% Then we are ready to update the size
reg_info(c_lab).size = reg_info(c_lab).size + reg_info(n_lab).size;
% Then give all pixels with n_lab the c_lab label
tmp_row_coord = reg_info(n_lab).row_coord;
tmp_col_coord = reg_info(n_lab).col_coord;
for p = 1 :reg_info(n_lab).size
seg(tmp_row_coord(p),tmp_col_coord(p)) = c_lab;
end
% Finally update the coordinates of the pixels
% belonging to this segment
reg_info(c_lab).row_coord = [reg_info(c_lab).row_coord reg_info(n_lab).row_coord];
reg_info(c_lab).col_coord = [reg_info(c_lab).col_coord reg_info(n_lab).col_coord];
% ...and mark it for deletion
reg_info(n_lab).size = 0 ;
% If we have reached this point then we know that
% something changed in this iteration
changed = 1 ;
end
end
end
end
end
iter = iter + 1 ;
% We will store the temporary results in seg_arr for demonstration
% purposes, the first layer equals the initial segmentation
seg_arr(:,:,iter) = seg;
end
% Clean up the reg_info structure
index = 1 ;
for m = 1 :max(max(seg))
if (reg_info(m).size > 0 )
tmp_reg_info(index) = reg_info(m);
index = index + 1 ;
end
end
reg_info = tmp_reg_info;
function ngb = get4ngb(rows,cols,x,y)
% function ngb = get4ngb(rows,cols,x,y)
% This function returns the cooridinates of the 8 - neighbours
% of an element in a matrix. The values are returned in the
% list ngb. If the neighbour does not exist, - that is (x,y)
% corredsponds to an edge or corner of the array,
% the list of neighbours contains only those coordinates corresponding
% to real neighbours.
% Copyright Lars Aurdal / FFIE.
% Handle left edge.
% Handle upper left corner.
if ((x == 1 ) & (y == 1 ))
ngb( 1 : 2 , 1 : 1 ) = [ 2 1 ] ' ;
ngb( 1 : 2 , 2 : 2 ) = [ 1 2 ] ' ;
% Handle lower left corner.
elseif ((x == rows) & (y == 1 ))
ngb( 1 : 2 , 1 : 1 ) = [rows 2 ] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(rows - 1 ) 1 ] ' ;
% Handle left edge in general.
elseif (y == 1 )
ngb( 1 : 2 , 1 : 1 ) = [(x + 1 ) 1 ] ' ;
ngb( 1 : 2 , 2 : 2 ) = [x 2 ] ' ;
ngb( 1 : 2 , 3 : 3 ) = [(x - 1 ) 1 ] ' ;
% Handle right edge.
% Handle upper right corner.
elseif ((x == 1 ) & (y == cols))
ngb( 1 : 2 , 1 : 1 ) = [ 1 (cols - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [ 2 cols] ' ;
% Handle lower right corner.
elseif ((x == rows) & (y == cols))
ngb( 1 : 2 , 1 : 1 ) = [rows (cols - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(rows - 1 ) cols] ' ;
% Handle right edge in general.
elseif (y == cols)
ngb( 1 : 2 , 1 : 1 ) = [(x + 1 ) cols] ' ;
ngb( 1 : 2 , 2 : 2 ) = [x (cols - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [(x - 1 ) cols] ' ;
% Handle top line.
elseif (x == 1 )
ngb( 1 : 2 , 1 : 1 ) = [ 1 (y - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [ 2 y] ' ;
ngb( 1 : 2 , 3 : 3 ) = [ 1 (y + 1 )] ' ;
% Handle bottom line.
elseif (x == rows)
ngb( 1 : 2 , 1 : 1 ) = [rows (y - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(rows - 1 ) y] ' ;
ngb( 1 : 2 , 3 : 3 ) = [rows (y + 1 )] ' ;
% Handle general case
else
ngb( 1 : 2 , 1 : 1 ) = [(x - 1 ) y] ' ;
ngb( 1 : 2 , 2 : 2 ) = [x (y - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [(x + 1 ) y] ' ;
ngb( 1 : 2 , 4 : 4 ) = [x (y + 1 )] ' ;
end
function ngb = get8ngb(rows,cols,x,y)
% function ngb = get8ngb(rows,cols,x,y)
% This function returns the cooridinates of the 8 - neighbours of an element
% in a matrix. The values are returned in the list neighbours. If the neighbour
% does not exist, - that is center corredsponds to an edge or corner of the array,
% the list of neighbours contains only those coordinates corresponding to real
% neighbours.
% Copyright Lars Aurdal / FFIE.
% Handle left edge.
% Handle upper left corner.
if ((x == 1 ) & (y == 1 ))
ngb( 1 : 2 , 1 : 1 ) = [ 2 1 ] ' ;
ngb( 1 : 2 , 2 : 2 ) = [ 2 2 ] ' ;
ngb( 1 : 2 , 3 : 3 ) = [ 1 2 ] ' ;
% Handle lower left corner.
elseif ((x == rows) & (y == 1 ))
ngb( 1 : 2 , 1 : 1 ) = [rows 2 ] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(rows - 1 ) 2 ] ' ;
ngb( 1 : 2 , 3 : 3 ) = [(rows - 1 ) 1 ] ' ;
% Handle left edge in general.
elseif (y == 1 )
ngb( 1 : 2 , 1 : 1 ) = [(x + 1 ) 1 ] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(x + 1 ) 2 ] ' ;
ngb( 1 : 2 , 3 : 3 ) = [x 2 ] ' ;
ngb( 1 : 2 , 4 : 4 ) = [(x - 1 ) 2 ] ' ;
ngb( 1 : 2 , 5 : 5 ) = [(x - 1 ) 1 ] ' ;
% Handle right edge.
% Handle upper right corner.
elseif ((x == 1 ) & (y == cols))
ngb( 1 : 2 , 1 : 1 ) = [ 1 (cols - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [ 2 (cols - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [ 2 cols] ' ;
% Handle lower right corner.
elseif ((x == rows) & (y == cols))
ngb( 1 : 2 , 1 : 1 ) = [rows (cols - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(rows - 1 ) (cols - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [(rows - 1 ) cols] ' ;
% Handle right edge in general.
elseif (y == cols)
ngb( 1 : 2 , 1 : 1 ) = [(x + 1 ) cols] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(x + 1 ) (cols - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [x (cols - 1 )] ' ;
ngb( 1 : 2 , 4 : 4 ) = [(x - 1 ) (cols - 1 )] ' ;
ngb( 1 : 2 , 5 : 5 ) = [(x - 1 ) cols] ' ;
% Handle top line.
elseif (x == 1 )
ngb( 1 : 2 , 1 : 1 ) = [ 1 (y - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [ 2 (y - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [ 2 y] ' ;
ngb( 1 : 2 , 4 : 4 ) = [ 2 (y + 1 )] ' ;
ngb( 1 : 2 , 5 : 5 ) = [ 1 (y + 1 )] ' ;
% Handle bottom line.
elseif (x == rows)
ngb( 1 : 2 , 1 : 1 ) = [rows (y - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(rows - 1 ) (y - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [(rows - 1 ) y] ' ;
ngb( 1 : 2 , 4 : 4 ) = [(rows - 1 ) (y + 1 )] ' ;
ngb( 1 : 2 , 5 : 5 ) = [rows (y + 1 )] ' ;
% Handle general case
else
ngb( 1 : 2 , 1 : 1 ) = [(x - 1 ) y] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(x - 1 ) (y - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [x (y - 1 )] ' ;
ngb( 1 : 2 , 4 : 4 ) = [(x + 1 ) (y - 1 )] ' ;
ngb( 1 : 2 , 5 : 5 ) = [(x + 1 ) y] ' ;
ngb( 1 : 2 , 6 : 6 ) = [(x + 1 ) (y + 1 )] ' ;
ngb( 1 : 2 , 7 : 7 ) = [x (y + 1 )] ' ;
ngb( 1 : 2 , 8 : 8 ) = [(x - 1 ) (y + 1 )] ' ;
end
% based segmentation algorithms. Paste them in the Matlab command window
% and things should work.
% Test the merging algorithm
% Clear everything
clear all
close all
% Go to your image catalog and read your image (exchange with your own
% catalog)
i = double (imread( ' cameraman.tif ' ));
% i = double (rgb2gray(imread( ' mm3.tif ' )));
% Take a look at the image
figure
imshow(i,[min(min(i)) max(max(i))])
% Make initial suggestion for segmented image
tmp_seg = reshape( 1 :prod(size(i)),size(i));
% Test elementary region growing on this image. Try changing the value
% for the criterion and the connectivity. And obviously, try different
% images.
[seg,seg_arr,reg] = region_grow1(i,tmp_seg, 25 , 8 );
% Take a look at the result
map = rand(max(max(seg)), 3 );
figure
imshow(seg,[])
colormap(map)
function [seg,seg_arr,reg_info] = region_grow1(im,seg,criterion,connectivity)
% This function performs basic region growing on an image.
%
% The input arguments are the following:
% im: The image to be segmented
% seg: An initial labelling of the image, typically you would let
% this image be an image where every pixel has its own label
% criterion: The value of the similarity criterion that is used to decide
% between fusion of segments or not.
% connectivity: The connectivity of regions considered for fusion.
%
% The output arguments are the following:
%
% seg: The final segmented image
% seg_arr: A stack of all the segmented images from every
% iteration
% reg_info: A structure containing all the information about
% the different segments.
%
% Copyright Lars Aurdal, The Norwegian Computing Centre
% Get size of input image
rows = size(im, 1 );
cols = size(im, 2 );
% Here comes a slightly tricky part. In order to keep the computation
% time down we need to use s data structure to keep track of information
% about the regions. A MATLAB struct is what we need. Each element in
% the reg_info array of structures holds the size in pixels of the
% element, the mean of the pixels assigned to the element as well as the
% row and column coordinates of all the pixels assigned to the region,
% this is nice to have in order to be able to quickly adress all the
% pixels belonging to a single element.
% Start by initialising
reg_info = struct ( ' size ' ,num2cell(zeros( 1 ,max(max(seg)))),... % Initially we don ' t know their size
' crt ' ,num2cell(zeros( 1 ,max(max(seg)))),... % ...nor their criterion value
' row_coord ' ,[],... % Coordinates go here
' col_coord ' ,[]); % and here
% Now loop over all the pixels in the initial segmented image and gather
% information about the existing regions
for m = 1 :rows
for n = 1 :cols
c_lab = seg(m,n);
reg_info(c_lab).size = reg_info(c_lab).size + 1 ;
% The following calculation of criterion corresponds to a calculation
% of the segment means
reg_info(c_lab).crt = ((reg_info(c_lab).size - 1 ) * reg_info(c_lab).crt + ...
im(m,n)) / reg_info(c_lab).size;
reg_info(c_lab).row_coord = [reg_info(c_lab).row_coord m];
reg_info(c_lab).col_coord = [reg_info(c_lab).col_coord n];
end
end
% Initially we assume that something will change in the first iteration
changed = 1 ;
% Keep track of iterations in order to display this
iter = 0 ;
% Now loop over the segmented image as long as something changes.
while (changed)
% Give user some feedback
disp([ ' Currently in iteration: ' num2str(iter + 1 )]);
% Check if something changes in this iteration
changed = 0 ;
% Now loop
for m = 1 :rows
for n = 1 :cols
% Get the label of the current pixel considered
c_lab = seg(m,n);
% Get the coordinates of the current pixels neighbours. This
% can be done in 4 or 8 connectivity
if (connectivity == 4 )
ngb = get4ngb(rows,cols,m,n);
end
if (connectivity == 8 )
ngb = get8ngb(rows,cols,m,n);
end
% Loop over all these neighbours and check if they should
% receive the same label as the pixel we are currently
% examining
for k = 1 :size(ngb, 2 )
n_lab = seg(ngb( 1 ,k),ngb( 2 ,k));
if (n_lab ~= c_lab)
if (abs(reg_info(n_lab).crt - reg_info(c_lab).crt) < criterion)
% First update the mean of the segment having the
% c_lab label
reg_info(c_lab).crt = (reg_info(c_lab).size * reg_info(c_lab).crt + ...
reg_info(n_lab).size * reg_info(n_lab).crt) / ...
(reg_info(c_lab).size + reg_info(n_lab).size);
% Then we are ready to update the size
reg_info(c_lab).size = reg_info(c_lab).size + reg_info(n_lab).size;
% Then give all pixels with n_lab the c_lab label
tmp_row_coord = reg_info(n_lab).row_coord;
tmp_col_coord = reg_info(n_lab).col_coord;
for p = 1 :reg_info(n_lab).size
seg(tmp_row_coord(p),tmp_col_coord(p)) = c_lab;
end
% Finally update the coordinates of the pixels
% belonging to this segment
reg_info(c_lab).row_coord = [reg_info(c_lab).row_coord reg_info(n_lab).row_coord];
reg_info(c_lab).col_coord = [reg_info(c_lab).col_coord reg_info(n_lab).col_coord];
% ...and mark it for deletion
reg_info(n_lab).size = 0 ;
% If we have reached this point then we know that
% something changed in this iteration
changed = 1 ;
end
end
end
end
end
iter = iter + 1 ;
% We will store the temporary results in seg_arr for demonstration
% purposes, the first layer equals the initial segmentation
seg_arr(:,:,iter) = seg;
end
% Clean up the reg_info structure
index = 1 ;
for m = 1 :max(max(seg))
if (reg_info(m).size > 0 )
tmp_reg_info(index) = reg_info(m);
index = index + 1 ;
end
end
reg_info = tmp_reg_info;
function ngb = get4ngb(rows,cols,x,y)
% function ngb = get4ngb(rows,cols,x,y)
% This function returns the cooridinates of the 8 - neighbours
% of an element in a matrix. The values are returned in the
% list ngb. If the neighbour does not exist, - that is (x,y)
% corredsponds to an edge or corner of the array,
% the list of neighbours contains only those coordinates corresponding
% to real neighbours.
% Copyright Lars Aurdal / FFIE.
% Handle left edge.
% Handle upper left corner.
if ((x == 1 ) & (y == 1 ))
ngb( 1 : 2 , 1 : 1 ) = [ 2 1 ] ' ;
ngb( 1 : 2 , 2 : 2 ) = [ 1 2 ] ' ;
% Handle lower left corner.
elseif ((x == rows) & (y == 1 ))
ngb( 1 : 2 , 1 : 1 ) = [rows 2 ] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(rows - 1 ) 1 ] ' ;
% Handle left edge in general.
elseif (y == 1 )
ngb( 1 : 2 , 1 : 1 ) = [(x + 1 ) 1 ] ' ;
ngb( 1 : 2 , 2 : 2 ) = [x 2 ] ' ;
ngb( 1 : 2 , 3 : 3 ) = [(x - 1 ) 1 ] ' ;
% Handle right edge.
% Handle upper right corner.
elseif ((x == 1 ) & (y == cols))
ngb( 1 : 2 , 1 : 1 ) = [ 1 (cols - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [ 2 cols] ' ;
% Handle lower right corner.
elseif ((x == rows) & (y == cols))
ngb( 1 : 2 , 1 : 1 ) = [rows (cols - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(rows - 1 ) cols] ' ;
% Handle right edge in general.
elseif (y == cols)
ngb( 1 : 2 , 1 : 1 ) = [(x + 1 ) cols] ' ;
ngb( 1 : 2 , 2 : 2 ) = [x (cols - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [(x - 1 ) cols] ' ;
% Handle top line.
elseif (x == 1 )
ngb( 1 : 2 , 1 : 1 ) = [ 1 (y - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [ 2 y] ' ;
ngb( 1 : 2 , 3 : 3 ) = [ 1 (y + 1 )] ' ;
% Handle bottom line.
elseif (x == rows)
ngb( 1 : 2 , 1 : 1 ) = [rows (y - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(rows - 1 ) y] ' ;
ngb( 1 : 2 , 3 : 3 ) = [rows (y + 1 )] ' ;
% Handle general case
else
ngb( 1 : 2 , 1 : 1 ) = [(x - 1 ) y] ' ;
ngb( 1 : 2 , 2 : 2 ) = [x (y - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [(x + 1 ) y] ' ;
ngb( 1 : 2 , 4 : 4 ) = [x (y + 1 )] ' ;
end
function ngb = get8ngb(rows,cols,x,y)
% function ngb = get8ngb(rows,cols,x,y)
% This function returns the cooridinates of the 8 - neighbours of an element
% in a matrix. The values are returned in the list neighbours. If the neighbour
% does not exist, - that is center corredsponds to an edge or corner of the array,
% the list of neighbours contains only those coordinates corresponding to real
% neighbours.
% Copyright Lars Aurdal / FFIE.
% Handle left edge.
% Handle upper left corner.
if ((x == 1 ) & (y == 1 ))
ngb( 1 : 2 , 1 : 1 ) = [ 2 1 ] ' ;
ngb( 1 : 2 , 2 : 2 ) = [ 2 2 ] ' ;
ngb( 1 : 2 , 3 : 3 ) = [ 1 2 ] ' ;
% Handle lower left corner.
elseif ((x == rows) & (y == 1 ))
ngb( 1 : 2 , 1 : 1 ) = [rows 2 ] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(rows - 1 ) 2 ] ' ;
ngb( 1 : 2 , 3 : 3 ) = [(rows - 1 ) 1 ] ' ;
% Handle left edge in general.
elseif (y == 1 )
ngb( 1 : 2 , 1 : 1 ) = [(x + 1 ) 1 ] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(x + 1 ) 2 ] ' ;
ngb( 1 : 2 , 3 : 3 ) = [x 2 ] ' ;
ngb( 1 : 2 , 4 : 4 ) = [(x - 1 ) 2 ] ' ;
ngb( 1 : 2 , 5 : 5 ) = [(x - 1 ) 1 ] ' ;
% Handle right edge.
% Handle upper right corner.
elseif ((x == 1 ) & (y == cols))
ngb( 1 : 2 , 1 : 1 ) = [ 1 (cols - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [ 2 (cols - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [ 2 cols] ' ;
% Handle lower right corner.
elseif ((x == rows) & (y == cols))
ngb( 1 : 2 , 1 : 1 ) = [rows (cols - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(rows - 1 ) (cols - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [(rows - 1 ) cols] ' ;
% Handle right edge in general.
elseif (y == cols)
ngb( 1 : 2 , 1 : 1 ) = [(x + 1 ) cols] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(x + 1 ) (cols - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [x (cols - 1 )] ' ;
ngb( 1 : 2 , 4 : 4 ) = [(x - 1 ) (cols - 1 )] ' ;
ngb( 1 : 2 , 5 : 5 ) = [(x - 1 ) cols] ' ;
% Handle top line.
elseif (x == 1 )
ngb( 1 : 2 , 1 : 1 ) = [ 1 (y - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [ 2 (y - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [ 2 y] ' ;
ngb( 1 : 2 , 4 : 4 ) = [ 2 (y + 1 )] ' ;
ngb( 1 : 2 , 5 : 5 ) = [ 1 (y + 1 )] ' ;
% Handle bottom line.
elseif (x == rows)
ngb( 1 : 2 , 1 : 1 ) = [rows (y - 1 )] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(rows - 1 ) (y - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [(rows - 1 ) y] ' ;
ngb( 1 : 2 , 4 : 4 ) = [(rows - 1 ) (y + 1 )] ' ;
ngb( 1 : 2 , 5 : 5 ) = [rows (y + 1 )] ' ;
% Handle general case
else
ngb( 1 : 2 , 1 : 1 ) = [(x - 1 ) y] ' ;
ngb( 1 : 2 , 2 : 2 ) = [(x - 1 ) (y - 1 )] ' ;
ngb( 1 : 2 , 3 : 3 ) = [x (y - 1 )] ' ;
ngb( 1 : 2 , 4 : 4 ) = [(x + 1 ) (y - 1 )] ' ;
ngb( 1 : 2 , 5 : 5 ) = [(x + 1 ) y] ' ;
ngb( 1 : 2 , 6 : 6 ) = [(x + 1 ) (y + 1 )] ' ;
ngb( 1 : 2 , 7 : 7 ) = [x (y + 1 )] ' ;
ngb( 1 : 2 , 8 : 8 ) = [(x - 1 ) (y + 1 )] ' ;
end