How can I find the dimensions and area of an irregularly shaped region in an image?
4 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Tiffany Mao
il 5 Lug 2017
Modificato: Tiffany Mao
il 7 Lug 2017
I have an image with multiple irregularly shaped blobs. Is it possible to find the dimensions (ie max length, width etc) and area of each blob?
2 Commenti
Walter Roberson
il 5 Lug 2017
Given an irregular blob, how do you tell which axes is the "length" compared to which is the "width" ? Is this piece of wood 5 long and 3 wide, or is it 3 long and 5 wide?
Risposta accettata
Image Analyst
il 5 Lug 2017
See attached demo.
5 Commenti
Image Analyst
il 6 Lug 2017
Three problems. You left in the code that threw out blobs smaller than 10% of the image, which meant that you would have no blobs at all. Secondly the image has a white line running along the bottom and right side of the image - I got rid of that. Third, my code doesn't seem to handle blobs only a single pixel wide, like some of your blobs. Fixed code is below.
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 = 18;
% 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 = pwd
baseFileName = 'ex.jpg'
% 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.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, '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
originalImage = imread(fullFileName);
% Display the original gray scale image.
hFig = figure;
subplot(2, 2, 1);
imshow(originalImage, []);
axis on;
title('Original 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')
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[rows, columns, numberOfColorBands] = size(originalImage);
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 = originalImage(:, :, 2); % Take green channel.
else
% It's already grayscale.
grayImage = originalImage;
end
% Binarize the image
level = graythresh(grayImage);
binaryImage = im2bw(grayImage, level);
% Display the image.
subplot(2, 2, 2);
imshow(binaryImage, []);
axis on;
title('Initial Binary Image', 'FontSize', fontSize);
% Fill holes
binaryImage = imfill(binaryImage, 'holes');
% Get rid of anything touching the edge of the image
binaryImage = imclearborder(binaryImage);
% Get rid of anything less than 20 pixels
binaryImage = bwareaopen(binaryImage, 20);
% Extract the largest blob only
% binaryImage = bwareafilt(binaryImage, 1);
% Display the image.
subplot(2, 2, 4);
imshow(binaryImage, []);
axis on;
hold on;
caption = sprintf('Filled, Cleaned Binary Image with\nBoundaries and Feret Diameters');
title(caption, 'FontSize', fontSize);
% Copy the gray scale image to the lower left.
subplot(2, 2, 3);
imshow(originalImage, []);
caption = sprintf('Original Image with\nBoundaries and Feret Diameters');
title(caption, 'FontSize', fontSize);
axis on;
hold on;
% Label the image so we can get the average perpendicular width.
labeledImage = bwlabel(binaryImage);
% Let's find the areas
props = regionprops(labeledImage, 'Area');
allAreas = sort([props.Area], 'descend')
% Measure the area
measurements = regionprops(labeledImage, 'Area');
% Make larger version so we can see it
% Copy the gray scale image to the lower left.
figure;
imshow(originalImage, []);
caption = sprintf('Original Image with\nBoundaries and Feret Diameters');
title(caption, 'FontSize', fontSize);
axis on;
hold on;
% 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')
% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
% Plot the borders of all the coins on the original grayscale image using the coordinates returned by bwboundaries.
boundaries = bwboundaries(binaryImage);
numberOfBoundaries = size(boundaries, 1);
for blobIndex = 1 : numberOfBoundaries
thisBoundary = boundaries{blobIndex};
x = thisBoundary(:, 2); % x = columns.
y = thisBoundary(:, 1); % y = rows.
% Find which two boundary points are farthest from each other.
maxDistance = -inf;
for k = 1 : length(x)
distances = sqrt( (x(k) - x) .^ 2 + (y(k) - y) .^ 2 );
[thisMaxDistance, indexOfMaxDistance] = max(distances);
if thisMaxDistance > maxDistance
maxDistance = thisMaxDistance;
index1 = k;
index2 = indexOfMaxDistance;
end
end
% Plot the boundary over this blob.
plot(x, y, 'g-', 'LineWidth', 1);
% For this blob, put a line between the points farthest away from each other.
line([x(index1), x(index2)], [y(index1), y(index2)], 'Color', 'r', 'LineWidth', 1);
% Put big red spots at the ends.
plot([x(index1), x(index2)], [y(index1), y(index2)], 'r.', 'MarkerSize', 30);
message = sprintf('The longest line is red.\nMax distance for blob #%d = %.2f\nArea = %d', ...
blobIndex, maxDistance, measurements(blobIndex).Area);
fprintf('%s\n', message);
uiwait(helpdlg(message));
end
hold off;
Più risposte (0)
Vedere anche
Categorie
Scopri di più su Image Processing and Computer Vision in Help Center e File Exchange
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!