I determined the shape of the object in image, how i can determine the object's color?

4 views (last 30 days)
My project is about color and shape sorter, I used just two objects a circle and rectangle, Also three colors, Red, Green and blue. I determined what the shape is, But my problem now is how i can determine what the object color is? For example like this image.
clc
close all
clear
%%Reading Image And Save It In Array.
Image = 'Gertie-Ball-Image-Green-transparent.png';
RGBImage = imread(Image);
RGBImage = imresize(RGBImage,[500,500]);
subplot(2,2,1)
imshow(RGBImage)
title('Input Image')
%%Image Conversions To GrayScale.
GrayImage = rgb2gray(RGBImage);
subplot(2,2,2)
imshow(GrayImage)
title('GrayScale Image')
%%Binarize The Image.
BinaryImage = imbinarize(GrayImage);
subplot(2,2,3)
imshow(BinaryImage)
title('Initial (Noisy) Binary Image')
%%Remove Small Objects.
BinaryImage = bwareaopen(BinaryImage, 50);
% BinaryImage = imcomplement(BinaryImage); % Complement image
subplot(2,2,4)
imshow(BinaryImage)
title('Cleaned Binary Image')
%%Measure Properties Of BinaryImage Regions.
[LabeledImage, NumberOfObjects] = bwlabel(BinaryImage); % Label Connected Components In 2-D Binary Image.
Stats = regionprops('Table', LabeledImage, 'FilledArea','Perimeter');
%%Get The Outermost Boundaries Of The Objects.
FilledImage = imfill(BinaryImage, 'holes'); % Fill Image Regions And Holes.
Boundaries = bwboundaries(FilledImage); % Trace Region Boundaries In Binary Image.
%%Collect Some Of The Measurements Into Individual Arrays.
Perimeter = [Stats.Perimeter];
FilledArea = [Stats.FilledArea];
%%Calculate Circularies.
Circularities = Perimeter.^2./(4*pi*FilledArea);
%%Determaine The Shape
if Circularities(NumberOfObjects) < 1.10
disp Circle
elseif Circularities(NumberOfObjects) < 2.0
disp Square
else
disp Something
end
%%Determaine The Color.
  3 Comments
odai kiwan
odai kiwan on 7 Mar 2018
Well, At my code i didn't use a mask for determining the shape, I calculate the circularizes and compare it with a threshold.
if a took a pixel and it's distance in this case the result will not be a 100% correct i guess. i don't know, Could you explain more please.
Adam
Adam on 7 Mar 2018
It all depends on how wide is the scope of objects and colours you will be presented with and what variation of colour they are allowed, but since you seemed to say only 3 colours are allowed - Red, Green and Blue, and that the shape must be one of these then a sample of pixels from inside the shape should do. Obviously just 1 is not very robust, but if your shape were uniformly very close to green or blue or red then it would still give the right answer. Since you appear to have white patches in your shape though a sampling of points with a mean (and exclusion of white) would work fine to give you the data to determine if it is red, green or blue.

Sign in to comment.

Accepted Answer

Benjamin Kraus
Benjamin Kraus on 7 Mar 2018
Steve Eddins posted a series of blog posts that may help with this question:
  2 Comments
Benjamin Kraus
Benjamin Kraus on 7 Mar 2018
Based on the blog post by Steve Eddins, I suggest working in the L*a*b* color space:
The "a" in L*a*b* gives you a separation between red and green, while the "b" gives you separation between blue and yellow.
I would suggest reading the blog post for more context. The script below may not be perfect, you should definitely test it to make sure it works accurately, but it is a first shot that may work.
% Convert to L*a*b*
lab = applycform(RGBImage, makecform('srgb2lab'));
lab = lab2double(lab);
% Apply mask
a = lab(:,:,2);
a(~FilledImage) = NaN;
b = lab(:,:,3);
b(~FilledImage) = NaN;
% Average the a and b values
aavg = mean(a(:),'omitnan');
bavg = mean(b(:),'omitnan');
% Based on the blog post:
% blue = b < 0
% green = b > 0 & a < 0
% red = b > 0 & a > 0
if bavg < 0
disp Blue
elseif aavg < 0
disp Green
else
disp Red
end
Benjamin Kraus
Benjamin Kraus on 7 Mar 2018
Edited: Benjamin Kraus on 7 Mar 2018
Another tip you may want to consider:
When you are calling imread, you are ignoring the third output, which provides transparency values:
[RGBImage,~,mask] = imread(Image);
The mask output gives you the transparency values from your PNG. I would recommend using this as a first step in determining your shape, as you can probably immediately throw away any values that are completely transparent (have a value of 0), and only keep values that are not transparent (have a value of 255).
Image = 'Gertie-Ball-Image-Green-transparent.png';
[RGBImage,~,mask] = imread(Image);
RGBImage = imresize(RGBImage,[500,500]);
mask = imresize(mask,[500,500]);
subplot(2,2,1)
im = imshow(RGBImage);
im.AlphaData = mask;
title('Input Image')

Sign in to comment.

More Answers (1)

murk hassan memon
murk hassan memon on 11 Apr 2018
But what about when we have object in biconcave or disc shape? what value should be use in order to represent the biconcave and disc shape? i am working on microscopic blood images and normal blood cells are biconcave or disc in shape. kindly help me out.

Community Treasure Hunt

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

Start Hunting!