MATLAB Answers

A function similar to bwareaopen and imdilate?

12 views (last 30 days)
Changoleon
Changoleon on 23 Sep 2016
Commented: Changoleon on 6 Oct 2016
Hi,
I have a picture with several particles in it. I have made the intensity in particles 255 and the background 0 so the particles are very detectable. But each particle has a different size of pixels. By using bwareaopen, I can eliminate particles bigger/smaller than a certain limit. But the questions is how can I set a limit so that my code erodes the particles which are greater than my threshold and dilate the ones smaller than threshold? at the end of the day, I should end up having a set of particles with a uniform size. There should be a way that I can use if statement.
Any idea would be appreciated

Accepted Answer

Image Analyst
Image Analyst on 24 Sep 2016
Edited: Image Analyst on 24 Sep 2016
Changolean, you can feel free to modify this:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
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;
%===============================================================================
% Get the name of the image the user wants to use.
baseFileName = 'coins.png'; % Assign the one on the button that they clicked on.
% Get the full filename, with path prepended.
folder = fileparts(which('cameraman.tif')); % Determine where demo folder is (works with all versions).
fullFileName = fullfile(folder, baseFileName);
%===============================================================================
% Read in a standard MATLAB gray scale demo image.
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[rows, columns, numberOfColorChannels] = size(grayImage);
if numberOfColorChannels > 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 image.
subplot(3, 3, 1);
imshow(grayImage, []);
caption = sprintf('Original Grayscale Image, %s', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
% Display the histogram so we can see what gray level we need to threshold it at.
subplot(3, 3, 2);
histogram(grayImage);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Threshold it.
binaryImage = grayImage > 80;
% Fill the blobs
binaryImage = imfill(binaryImage, 'holes');
% Get rid of blobs smaller than 50 pixels:
binaryImage = bwareaopen(binaryImage, 150);
subplot(3, 3, 3);
imshow(binaryImage, []);
axis on;
caption = sprintf('Binary Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Label the image
[labeledImage, numBlobs] = bwlabel(binaryImage);
props = regionprops(labeledImage, 'Area');
allAreas = [props.Area]
smallBlobIndexes = find(allAreas < 2000)
bigBlobIndexes = find(allAreas >= 2000)
% Extract the small blobs
smallBlobsImage = ismember(labeledImage, smallBlobIndexes);
% Show the small blobs.
subplot(3, 3, 4);
imshow(smallBlobsImage, []);
title('Small blobs', 'FontSize', fontSize);
axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
hold on;
% Extract the big blobs
bigBlobsImage = ismember(labeledImage, bigBlobIndexes);
% Show the big blobs.
subplot(3, 3, 5);
imshow(bigBlobsImage, []);
title('Big blobs', 'FontSize', fontSize);
axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
hold on;
% Grow the small blobs
radius = 5;
se = strel('disk', radius, 0);
smallBlobsImage = imdilate(smallBlobsImage, se);
% Show the small blobs.
subplot(3, 3, 7);
imshow(smallBlobsImage, []);
title('Small blobs Dilated', 'FontSize', fontSize);
axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
hold on;
% Shrink the big blobs
se = strel('disk', radius, 0);
bigBlobsImage = imerode(bigBlobsImage, se);
% Show the small blobs.
subplot(3, 3, 8);
imshow(bigBlobsImage, []);
title('Big blobs eroded', 'FontSize', fontSize);
axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
hold on;
% Combine them to form the final binary image
finalImage = smallBlobsImage | bigBlobsImage;
% Show the small blobs.
subplot(3, 3, [6,9]);
imshow(finalImage, []);
title('Final image', 'FontSize', fontSize);
axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
hold on;
However if all blobs must be the same area, what you'll have to do is to label the blobs, then use a loop to use ismember() to extract each blob one at a time. Then you need to dilate that image until the area of the single blob is as close to your desired area as possible. Then OR that image back into an accumulator image that you will build up one blob at a time. This will roughly keep each blob shape. If you don't care and just want all blobs to have the same shape, then just see which blob is closest to the average, or your desired area, and create a new image where that blob is pasted down at the centroid location of each original blob. If you would rather do either of those, and can't figure out the code on your own, let me know.
  1 Comment
Changoleon
Changoleon on 6 Oct 2016
Thank you Image Analyst, as you said, I needed to modify some parts of the code, but it's an accurate and general approach. Thank you

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!