Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

To resolve issues starting MATLAB on Mac OS X 10.10 (Yosemite) visit: http://www.mathworks.com/matlabcentral/answers/159016

how to select the interior boundary of an object?

Asked by hend on 25 May 2013

having an object with enough border width to make 2 boundaries interior and exterior with stdfilt , I just want to select the interior one

0 Comments

hend

3 Answers

Answer by Image Analyst on 25 May 2013
Edited by Image Analyst on 25 May 2013
Accepted answer

bwboundaries allows you to do that. See my demos in my other answers here. You can get boundaries and select those that are inside other boundaries. Feel free to upload an image to http://snag.gy if you want more advice. And upload your code too.

0 Comments

Image Analyst
Answer by Image Analyst on 25 May 2013

bwboundaries demo #1:

clc;    % Clear the command window.
clear;  % Erase all existing variables.
close all;
format compact;
format long g;
workspace;  % Make sure the workspace panel is showing.
% Create a sample image.
binaryImage = false(15,15);
binaryImage(2:14, 2:14) = true;
binaryImage(4:12, 4:12) = false;
binaryImage(6:10, 6:10) = true;
binaryImage(8:9, 8:9) = false
% Display the image.
imshow(binaryImage, 'InitialMagnification', 4000);
hold on;
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Find the blobs and label them and get their pixel coordinates.
[labeledImage numberOfBlobs] = bwlabel(binaryImage)
blobMeasurements = regionprops(labeledImage, 'PixelList');
% Find the boundaries of the two blobs.
[boundaries labeledImage numberOfBlobs2 adjacencyMatrix] = bwboundaries(binaryImage);
numberOfBoundaries = size(boundaries, 1);
fprintf('There are %d blobs, and %d boundaries.\n', numberOfBlobs, numberOfBoundaries);
% Array to keep track of which blobs "owns" which boundaries
ownersOfBoundary = zeros(numberOfBoundaries, 1, 'int32');
% Now try to find out which blobs and which boundaries are associated.
for k = 1 : numberOfBoundaries
	% Try to find out which blob this boundary belongs to.
	fprintf('This is boundary #%d:\n', k);
	thisBoundary = boundaries{k} % It's (row, column), NOT (x, y)
	% Get the first pixel on the boundary.
	row = thisBoundary(1,1);
	column = thisBoundary(1,2);
	plot(thisBoundary(:, 2), thisBoundary(:, 1), 'b-', 'LineWidth', 2);
	caption = sprintf('Boundary #%d', k);
	text(column, row, caption, 'Color', 'r', 'FontSize', 20);
	foundIt = false;
	for blob = 1 : numberOfBlobs
		fprintf('Searching for boundary location (row, column) = (%d, %d) of boundary #%d inside blob #%d\n', ...
			row, column, k, blob);
		thisBlobsPixels = blobMeasurements(blob).PixelList;
		% IMPORTANT NOTE: thisBlobsPixels has each row as x,y and not as row,column, like bwboundaries has.
		% We need to check that the coordinates are in the right order when we compare them with ismember.
		if ismember([column row], thisBlobsPixels, 'rows'); % Compare (column, row) against (x,y).
			foundIt = true;
			% Save this blob as the owner of this boundary
			ownersOfBoundary(k) = blob;
			fprintf('    Found boundary location (row, column) = (%d, %d) of boundary #%d inside blob #%d\n', ...
				row, column, k, blob);
			message = sprintf('Found boundary #%d in blob %d!', k, blob);
			uiwait(msgbox(message));
			break;
		else
			fprintf('    Did not find boundary location (row, column) = (%d, %d) of boundary #%d inside blob #%d\n', ...
				row, column, k, blob);			
		end
	end
	if ~foundIt
		message = sprintf('Did not find boundary #%d in any blob', k);
		uiwait(msgbox(message));
		% See if we can find boundary "k" within another blob's hole by looking at the adjacency matrix.
		for outerBoundary = 1 : numberOfBoundaries
			if adjacencyMatrix(k, outerBoundary) == 1
				% Then this boundary is inside the other boundary.
				message = sprintf('Boundary #%d is within boundary #%d', k, outerBoundary);
				uiwait(msgbox(message));
				% OK fine, but now we need to know what blob that boundary k belongs to.
				% As example 2 in the help shows, you can't assume that it will find all the outer boundaries first.
				% Save this blob as the owner of this boundary
				outerBoundaryOwner = ownersOfBoundary(outerBoundary);
				% Make this boundary have the same owner as its outer boundary.
				ownersOfBoundary(k) = outerBoundaryOwner;
				message = sprintf('I think blob #%d owns boundary #%d.', outerBoundaryOwner, k);
				uiwait(msgbox(message));
			end
		end
	end
end
ownersOfBoundary
fprintf('\nWe expected to find boundaries #1 and #3 in blob 1, and boundary #2 and #4 in blob #2.\n');

0 Comments

Image Analyst
Answer by Image Analyst on 25 May 2013

bwboundaries demo #2:

% Demo to find and distinguish between inner and out boundaries on a binary region.
clc;    % Clear the command window.
close all;  % Close all figures (except those of imtool.)
imtool close all;  % Close all imtool figures if you have the Image Processing Toolbox.
clear;  % Erase all existing variables. Or clearvars if you want.
workspace;  % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
% Check that user has the Image Processing Toolbox installed.
hasIPT = license('test', 'image_toolbox');
if ~hasIPT
	% User does not have the toolbox installed.
	message = sprintf('Sorry, but you do not seem to have the Image Processing Toolbox.\nDo you want to try to continue anyway?');
	reply = questdlg(message, 'Toolbox missing', 'Yes', 'No', 'Yes');
	if strcmpi(reply, 'No')
		% User said No, so exit.
		return;
	end
end
% Read in a standard MATLAB gray scale demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
baseFileName = 'saturn.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
	% File doesn't exist -- didn't find it there.  Check the search path for it.
	fullFileName = baseFileName; % No path this time.
	if ~exist(fullFileName, 'file')
		% Still didn't find it.  Alert user.
		errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
		uiwait(warndlg(errorMessage));
		return;
	end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image.  
% numberOfColorBands should be = 1.
[rows, columns, numberOfColorBands] = size(grayImage);
if numberOfColorBands > 1
	% It's not really gray scale like we expected - it's color.
	% Convert it to gray scale by taking only the green channel.
	grayImage = grayImage(:, :, 2); % Take green channel.
end
% Display the original gray scale image.
subplot(2, 2, 1);
imshow(grayImage, []);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Give a name to the title bar.
set(gcf,'name','Demo by ImageAnalyst','numbertitle','off') 
% Let's compute and display the histogram.
[pixelCount, grayLevels] = imhist(grayImage);
subplot(1, 2, 2); 
bar(pixelCount);
grid on;
title('Histogram of Original Grayscale Image', 'FontSize', fontSize);
xlim([0 grayLevels(end)]); % Scale x axis manually.
% threshold (binarize) the image.
binaryImage = grayImage > 20;
% Get rid of small blobs:
binaryImage = bwareaopen(binaryImage, 500);
binaryImage = imclose(binaryImage, ones(15));
% Display the original gray scale image.
subplot(2, 2, 3);
imshow(binaryImage, []);
title('Binary Image with Boundaries', 'FontSize', fontSize);
axis on;
% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
% Plot all the boundaries on the original grayscale image using the coordinates returned by bwboundaries.
hold on;
[boundaries, L, N, A] = bwboundaries(binaryImage);
numberOfBoundaries = size(boundaries, 1);
% Find out which are interior boundaries (interior to boundary #1):
enclosed_boundaries = find(A(:,1))
for k = 1 : numberOfBoundaries
	thisBoundary = boundaries{k};
	if ismember(enclosed_boundaries, k)
		% It's not an enclosed boundary - it's an outer one.  Plot in red.
		plot(thisBoundary(:,2), thisBoundary(:,1), 'r', 'LineWidth', 3);
	else
		% It's an enclosed boundary.  Plot in green.
		plot(thisBoundary(:,2), thisBoundary(:,1), 'g', 'LineWidth', 3);
	end
end
hold off;

0 Comments

Image Analyst

Contact us