Extract the largest object in the RGB image

24 views (last 30 days)
Hi,
I have an image with multipe objects as seen in the first image below and I want just extract part of that image (the largest object in the image) as seen in the second image. How can I do that?
* It is better to keep the image in RGB

Accepted Answer

Image Analyst
Image Analyst on 2 May 2020
OK, if you really need to it work for a full color image, here is code for that:
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 = 22;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'image.jpeg';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
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
rgbImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(rgbImage);
% Display the image.
hFig = figure;
subplot(2, 2, 1);
imshow(rgbImage, []);
impixelinfo;
title('Original RGB Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
%--------------------------------------------------------------------------------------------------------
% EXTRACTION OF IMAGE
% Get the max image
grayImage = min(rgbImage, [], 3);
subplot(2, 2, 2);
imshow(grayImage, []);
impixelinfo;
title('Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
threshold = 240; % Whatever....
mask = grayImage < threshold; % Create a binary image (a mask)
% Extract the largest blob only.
mask = bwareafilt(mask, 1);
% Fill holes
mask = imfill(mask, 'holes');
% Display the image.
subplot(2, 2, 3);
imshow(mask, []);
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
% Get the mean gray levels in R, G, and B.
meanGLR = mean(rgbImage(redChannel > threshold))
meanGLG = mean(rgbImage(greenChannel > threshold))
meanGLB = mean(rgbImage(blueChannel > threshold))
% Mask the individual color channel images.
% Make outside the mask the mean of what's above the threshold.
redChannel(~mask) = meanGLR;
greenChannel(~mask) = meanGLG;
blueChannel(~mask) = meanGLB;
% Recombine separate color channels into a single, true color RGB image.
rgbImage2 = cat(3, redChannel, greenChannel, blueChannel);
% Display the cropped image.
subplot(2, 2, 4);
imshow(rgbImage2, []);
title('Final Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
  5 Comments
Mona Al-Kharraz
Mona Al-Kharraz on 3 May 2020
ok. Is there any way to count the number of objects in the image because I have some images with only one object (as seen below) so it is not necessary to go through the above steps for these images.
Image Analyst
Image Analyst on 3 May 2020
Yes, after you segment the image and get the mask image, you can pass it into bwlabel():
[labeledImage, numberOfRegions] = bwlabel(maskImage);

Sign in to comment.

More Answers (2)

Ameer Hamza
Ameer Hamza on 2 May 2020
Try this
im = im2double(imread('image.jpeg'));
im_mask = rgb2gray(im) < 0.9;
rgs = bwconncomp(im_mask);
[max_area, idx] = max(cellfun(@(x) numel(x), rgs.PixelIdxList));
mask = zeros(size(im_mask));
mask(rgs.PixelIdxList{idx}) = 1;
im(~mask(:,:,[1 1 1])==1) = 1;
imshow(im)
  1 Comment
Mona Al-Kharraz
Mona Al-Kharraz on 3 May 2020
Many thanks for your quick answer. Also your code is working with me :))

Sign in to comment.


Image Analyst
Image Analyst on 2 May 2020
Edited: Image Analyst on 2 May 2020
Very simple. Simply use the built-in function bwareafilt() to extract the largest blob from your segmented image (your mask):
threshold = 240; % Whatever....
mask = grayImage < threshold; % Create a binary image (a mask)
% Extract the largest blob only.
mask = bwareafilt(mask, 1);
Here is a full demo with fancy graphics and everything. Simply copy, paste, change the image file name, and run:
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 = 22;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'image.jpeg';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
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
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage);
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
grayImage = rgb2gray(grayImage);
% ALTERNATE METHOD: Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
% grayImage = grayImage(:, :, 2); % Take green channel.
end
% Display the image.
hFig = figure;
subplot(2, 2, 1);
imshow(grayImage, []);
impixelinfo;
title('Original Grayscale Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
% Let's get the histogram
subplot(2, 2, 2);
imhist(grayImage);
title('Histogram of Image', 'FontSize', fontSize, 'Interpreter', 'None');
xlabel('Gray Level', 'FontSize', fontSize);
ylabel('Count', 'FontSize', fontSize);
grid on;
%--------------------------------------------------------------------------------------------------------
% EXTRACTION OF IMAGE
threshold = 240; % Whatever....
mask = grayImage < threshold; % Create a binary image (a mask)
% Extract the largest blob only.
mask = bwareafilt(mask, 1);
% Fill holes
mask = imfill(mask, 'holes');
% Display the segmented image of the triangles.
subplot(2, 2, 3);
imshow(mask, []);
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
% Mask the gray level image.
maskedGrayImage = grayImage; % Initialize
% Make outside the mask the mean of what's above the threshold.
meanGL = mean(grayImage(grayImage > threshold))
maskedGrayImage(~mask) = meanGL;
% Display the cropped image.
subplot(2, 2, 3);
imshow(maskedGrayImage, []);
title('Cropped Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');

Community Treasure Hunt

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

Start Hunting!