How to isolate and display the largest connected component

Hello all,
I am looking to isolate the largest connected component in an image, and then display it by itself. Right now, the code I am using deletes the largest connected component and keeps everything else. I want everything else in the image to be deleted, and the largest component to remain. My code for the isolation is as follows:
CC = bwconncomp(B);
numOfPixels = cellfun(@numel,CC.PixelIdxList);
[unused,indexOfMax] = max(numOfPixels);
B(CC.PixelIdxList{indexOfMax}) = 0;
imshow(B);

댓글 수: 2

CC = bwconncomp(B);
numOfPixels = cellfun(@numel,CC.PixelIdxList);
[unused,indexOfMax] = max(numOfPixels);
biggest = zeros(size(B));
biggest(CC.PixelIdxList{indexOfMax}) = 1;
imshow(biggest);
With recent versions of MATLAB, you simply do
biggest = bwareafilt(B);
instead of the 6 lines of code you showed.

댓글을 달려면 로그인하십시오.

 채택된 답변

Image Analyst
Image Analyst 2013년 5월 14일
See my demo:
function ExtractBiggestBlob()
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;
% Read in a standard MATLAB gray scale demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
baseFileName = 'coins.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);
% Display the original gray scale image.
subplot(2, 2, 1);
imshow(grayImage, []);
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(2, 2, 2);
bar(pixelCount);
grid on;
title('Histogram of original image', 'FontSize', fontSize);
xlim([0 grayLevels(end)]); % Scale x axis manually.
% Threshold the image to binarize it.
binaryImage = grayImage > 100;
% Fill holes
binaryImage = imfill(binaryImage, 'holes');
% Display the image.
subplot(2, 2, 3);
imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize);
% Get all the blob properties. Can only pass in originalImage in version R2008a and later.
[labeledImage, numberOfBlobs] = bwlabel(binaryImage);
blobMeasurements = regionprops(labeledImage, 'area', 'Centroid');
% Get all the areas
allAreas = [blobMeasurements.Area] % No semicolon so it will print to the command window.
menuOptions{1} = '0'; % Add option to extract no blobs.
% Display areas on image
for k = 1 : numberOfBlobs % Loop through all blobs.
thisCentroid = [blobMeasurements(k).Centroid(1), blobMeasurements(k).Centroid(2)];
message = sprintf('Area = %d', allAreas(k));
text(thisCentroid(1), thisCentroid(2), message, 'Color', 'r');
menuOptions{k+1} = sprintf('%d', k);
end
% Ask user how many blobs to extract.
numberToExtract = menu('How many do you want to extract', menuOptions) - 1;
% Ask user if they want the smallest or largest blobs.
promptMessage = sprintf('Do you want the %d largest, or %d smallest, blobs?',...
numberToExtract, numberToExtract);
titleBarCaption = 'Largest or Smallest?';
sizeOption = questdlg(promptMessage, titleBarCaption, 'Largest', 'Smallest', 'Cancel', 'Largest');
if strcmpi(sizeOption, 'Cancel')
return;
elseif strcmpi(sizeOption, 'Smallest')
% If they want the smallest, make the number negative.
numberToExtract = -numberToExtract;
end
%---------------------------------------------------------------------------
% Extract the largest area using our custom function ExtractNLargestBlobs().
% This is the meat of the demo!
biggestBlob = ExtractNLargestBlobs(binaryImage, numberToExtract);
%---------------------------------------------------------------------------
% Display the image.
subplot(2, 2, 4);
imshow(biggestBlob, []);
% Make the number positive again. We don't need it negative for smallest extraction anymore.
numberToExtract = abs(numberToExtract);
if numberToExtract == 1
caption = sprintf('Extracted %s Blob', sizeOption);
elseif numberToExtract > 1
caption = sprintf('Extracted %d %s Blobs', numberToExtract, sizeOption);
else % It's zero
caption = sprintf('Extracted 0 Blobs.');
end
title(caption, 'FontSize', fontSize);
msgbox('Done with demo!');
% Function to return the specified number of largest or smallest blobs in a binary image.
% If numberToExtract > 0 it returns the numberToExtract largest blobs.
% If numberToExtract < 0 it returns the numberToExtract smallest blobs.
% Example: return a binary image with only the largest blob:
% binaryImage = ExtractNLargestBlobs(binaryImage, 1)
% Example: return a binary image with the 3 smallest blobs:
% binaryImage = ExtractNLargestBlobs(binaryImage, -3)
function binaryImage = ExtractNLargestBlobs(binaryImage, numberToExtract)
try
% Get all the blob properties. Can only pass in originalImage in version R2008a and later.
[labeledImage, numberOfBlobs] = bwlabel(binaryImage);
blobMeasurements = regionprops(labeledImage, 'area');
% Get all the areas
allAreas = [blobMeasurements.Area];
if numberToExtract > 0
% For positive numbers, sort in order of largest to smallest.
% Sort them.
[sortedAreas, sortIndexes] = sort(allAreas, 'descend');
elseif numberToExtract < 0
% For negative numbers, sort in order of smallest to largest.
% Sort them.
[sortedAreas, sortIndexes] = sort(allAreas, 'ascend');
% Need to negate numberToExtract so we can use it in sortIndexes later.
numberToExtract = -numberToExtract;
else
% numberToExtract = 0. Shouldn't happen. Return no blobs.
binaryImage = false(size(binaryImage));
return;
end
% Extract the "numberToExtract" largest blob(a)s using ismember().
biggestBlob = ismember(labeledImage, sortIndexes(1:numberToExtract));
% Convert from integer labeled image into binary (logical) image.
binaryImage = biggestBlob > 0;
catch ME
errorMessage = sprintf('Error in function ExtractNLargestBlobs().\n\nError Message:\n%s', ME.message);
fprintf(1, '%s\n', errorMessage);
uiwait(warndlg(errorMessage));
end

댓글 수: 5

In what variable is the largest connected component being stored? I feel like that would be the easiest way to isolate it, because I could then just use imshow(variablewithlargestcomponent).
Thanks for your response.
You feel like what would be the easiest way to isolate it? How would that, whatever it is, be easier than saying
biggestBlobImage = ExtractNLargestBlobs(binaryImage, 1);
imshow(biggestBlobImage);
like you do with my code? Also be aware that my function is a very useful multi-purpose function where you can specify any number of blobs and get either the largest or smallest of that number.
Is your entire code above the, ExtractNLargestBlobs, function?
The first function is the demo code. The main function that does all the work is the second function. As you know, you cannot have a script followed by a function in the same file. You can either have a script and a function in two separate files, OR you can put them both in the same file but you have to make your script into a function. It is this latter method that I used. So save the code into ExtractBiggestBlob.m. ExtractBiggestBlob() will run and do some setup stuff to create the binary image, but then call the main function that you want, which is ExtractNLargestBlobs()
Thank you for the clarification!

댓글을 달려면 로그인하십시오.

추가 답변 (3개)

Fazal Hassan
Fazal Hassan 2014년 3월 20일

0 개 추천

Sir i have used above code on CT scan of heart in png format .but it give me wrong largest blog area when i change threshod it give an other blob with largest area...in image it should give me AROTA as largest blob but it give me some thing else Need your help plz...why this code is behaving like that Thanks in advance. Engr fazalhassan

댓글 수: 2

Post your image so I can try my method on it.
Is it possible to use a similar code on a 3D mesh, to find the largest connected component of the mesh? I have two CT scans of the skull before and after a piece of the bone has been removed. I have subtracted them and meshed the result, and I want to extract only the largest component. Thanks, Neeru.

댓글을 달려면 로그인하십시오.

MoonPie1
MoonPie1 2015년 12월 10일

0 개 추천

How can i display 4 largest connected component?

댓글 수: 10

Use bwareafilt():
biggest4 = bwareafilt(binaryImage, 4, 'largest');
imshow(biggest4);
i am unable to use bwareafilt as it is a medical image... please let me know how to delete 30 elements out of 34 and display only 4 largest
bwareafilt() does not care if the binary image came from a medical image or not. What is the real reason you are unable to use it? Do you have an antique version of MATLAB that did not have it yet?
I have implemented the same.But,I dont get output.It displays error message.What should I do to rectify it?
I get the bellow error messages.
Error using bwpropfilt
Expected input number 1, BW, to be two-dimensional.
Error in bwpropfilt>parse_inputs (line 121)
validateattributes(bw, {'logical'}, {'nonsparse', '2d'}, mfilename, 'BW', 1);
Error in bwpropfilt (line 58)
[bw, I, attrib, p, direction, conn] = parse_inputs(args{:});
Error in bwareafilt (line 34)
bw2 = bwpropfilt(bw, 'area', p, direction, conn);
Error in test (line 3)
biggest4 = bwareafilt(binaryImage, 4, 'largest');
img=imread('test.png');
binaryImage=imbinarize(img);
biggest4 = bwareafilt(binaryImage, 4, 'largest');
imshow(biggest4);
test.png
Your binary image was color. Convert it to binary. This works:
img=imread('test.png');
subplot(2, 1, 1);
imshow(img);
if ndims(img) > 1
img = img(:,:,1); % Take red plane
end
binaryImage = imbinarize(img);
% Get rid of anything touching the edge of the image
% because this will definitely not be a license plate.
binaryImage = imclearborder(binaryImage);
% Extract the biggest 4 blobs
biggest4 = bwareafilt(binaryImage, 4, 'largest');
subplot(2, 1, 2);
imshow(biggest4);
0000 Screenshot.png
ezhil K
ezhil K 2019년 1월 21일
편집: ezhil K 2019년 1월 21일
Thank You for your answer.It works perfectly well.Thank you so much.But I could'nt understand the logic behind it.Can you please explain me in detail?
This code works only if I specify it in a seperate script file.But if I use it as a function this returns the following error.Why is it so?
Error using imbinarize
Expected I to be one of these types:
uint8, uint16, uint32, int8, int16, int32, single, double
Instead its type was logical.
Error in imbinarize>validateImage (line 261)
validateattributes(I,supportedClasses,supportedAttribs,mfilename,'I');
Error in imbinarize>parseInputs (line 197)
validateImage(I);
Error in imbinarize (line 133)
[I,isNumericThreshold,options] = parseInputs(I,varargin{:});
Error in Shi_tomashi (line 80)
binaryImage = imbinarize(c);
I don't know what c really means, but your c is a binary (logical) image, not a gray scale image. It makes no sense at all to call imbinarize() on an image that is already binary, don't you agree?
Yeah,it's my mistake.Thanks for your clarification.I got the output.
I have to crop the plate region automatically.So what should I do to make it possible?

댓글을 달려면 로그인하십시오.

Sultan
Sultan 2017년 7월 12일

0 개 추천

Hello all,
I am looking to mark the largest connected component in an image with special color say 'red', and then color the other components in black while the empty space I wanted to be colored in white. cheers

댓글 수: 1

Use regionprops to find the largest blob. Then setup a colormap where the row with the largest blob number is red, row 1 is white, and all the other rows are black, then use labeled2rgb() to apply that colormap and produce an RGB image.
[labeledImage, numBlobs] = bwlabel(binaryImage);
props = regionprops(labeledImage, 'Area');
[maxArea, largestIndex] = max([props.Area])
cmap = zeros(numBlobs+1, 3);
cmap(largestIndex, :) = [1, 0, 0];
cmap(1, :) = 0;
rgbImage = labeled2rgb(labeledImage, cmap);
Start your own question and upload your binary image if you can't figure it out.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Image Processing Toolbox에 대해 자세히 알아보기

질문:

2013년 5월 14일

댓글:

2019년 1월 22일

Community Treasure Hunt

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

Start Hunting!

Translated by