how to select the interior boundary of an object?

3 views (last 30 days)
having an object with enough border width to make 2 boundaries interior and exterior with stdfilt , I just want to select the interior one

Accepted Answer

Image Analyst
Image Analyst on 25 May 2013
Edited: Image Analyst on 25 May 2013
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.

More Answers (2)

Image Analyst
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');

Image Analyst
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;

Categories

Find more on Image Processing and Computer Vision in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!