how do i assign a color to the same type of shape (2024)

It's no surprise OP got lost. That's an awful lot of duplicated code, unused code, and misleading variable names. I got lost.

This is an attempt to clean it up so that it runs at least as much as it did before. There are still a lot of things that could be simplified, fixed, or otherwise improved.

The code as given wouldn't run with the given image, since the edge detection generates a bunch of spurious blobs. That's probably because the input is a crusty JPG.

clearvars % clean up

close all

clc

fontsize = 8; % used for figure labels

textbgc = 'y';

RGB = imread('test_shapes.jpg'); %read the loaded image

sharp=imsharpen(RGB); %sharpen the read image

grayscale=rgb2gray(sharp); %convert from rgb image to grayscale format

h = fspecial('gaussian',40,1); %create a smoothing filter

filtered = imfilter(grayscale,h); %filtering

Edgecanny = edge(filtered,'canny'); %edge detection

X = imfill(Edgecanny,'holes'); %fill in with holes

% get rid of all the tiny blobs created by doing edge detection on a JPG

Bw = bwareaopen(X,1500);

% get the label image

[L numblobs] = bwlabel(Bw);

% define shape class names

shapeclasses = {'Circle','Square','Triangle','Rectangle','Pentagon', ...

'Hexagon','Ellipse','Octagon','Diamond','Unknown'};

% preallocate

blobcentroids = zeros(numblobs,2); % the [x y] centroid location for each blob

blobclasses = zeros(numblobs,1); % the class number for each blob

blobaream = zeros(numblobs,1); % the unrounded area for each blob (in sq m)

for n=1:numblobs

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% SHAPE FACTORS

thisblobonly = L==n; % do it once instead of 14 times

[row, col] = find(thisblobonly);

% Find Bounding Box

sx = min(col)-0.5; %starting position for column

sy = min(row)-0.5; %starting position for row

breadth = max(col)-min(col)+1; %gives breadth of the box

BBox = [sx sy breadth length]; %Bounding Box value for the range of n

% Find area ratio

blobarea = bwarea(thisblobonly); %calculates the area of each binary component

blobaream(n) = round(blobarea) * 0.001; %converting from mm to m

bboxarea = (length*breadth); %calculates the area of each bounding box

extent = blobarea/bboxarea; %calculates the ratio of area's

fprintf('Extent: %.4f\n',extent)

% Find Perimeter

thisboundary = bwboundaries(thisblobonly); %Find the boundary of the labeled components boundary pixels

c = cell2mat(thisboundary(1)); %converts the cell to a matrix

Perimeter = 0; %declaring a start at zero for sum

for i = 1:size(c,1)-1 %creates a loop that extracts perimeter of each binary component

Perimeter = Perimeter+sqrt((c(i,1)-c(i+1,1)).^2+(c(i,2)-c(i+1,2)).^2);

end

fprintf('Perimeter: %.3f\n',Perimeter); %display perimeter

% Find Roundness

Roundness = (4*blobarea*pi)/Perimeter.^2; %defines how close the binary component is to a circle

fprintf('Roundness: %.3f\n',Roundness); %display roundness factor

% Find aspect ratio instead of distance between first three vertices

aspectratio = min(BBox(3:4))/max(BBox(3:4)); % normalized

fprintf('Aspect: %.3f\n',aspectratio);

% Find Centroid

X = mean(col); %calculates average of columns

Y = mean(row); %calculates average of rows

blobcentroids(n,:) = [X Y]; %matrix of centroid dimensions

fprintf('Centroid: [%d %d]\n',round(blobcentroids(n,:))); %display centroid

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% SHAPE CLASSIFICATION

if extent>=0.782 && extent<=0.800 && Roundness>=0.909

blobclasses(n) = 1; % CIRCLE

elseif aspectratio>=0.9 && extent>=0.97

blobclasses(n) = 2; % SQUARE

elseif extent>=0.526 && extent<=0.550 && Roundness>=0.541 && Roundness<=0.559

blobclasses(n) = 3; % TRIANGLE

elseif aspectratio<0.9 && extent>=0.97

blobclasses(n) = 4; % RECTANGLE

elseif extent>=0.694 && extent<=0.714

blobclasses(n) = 5; % PENTAGON

elseif extent>=0.758 && extent<=0.769

blobclasses(n) = 6; % HEXAGON

elseif extent>=0.782 && extent<=0.800 && Roundness<0.909

blobclasses(n) = 7; % ELLIPSE

elseif extent>=0.833 && extent<=0.909

blobclasses(n) = 8; % OCTAGON

elseif extent>=0.526 && extent<=0.535 && Roundness>=0.714 && Roundness<=0.769

blobclasses(n) = 9; % DIAMOND

else

blobclasses(n) = 10; % NOT CLASSIFIED SHAPE

end

% dump another message into the console

fprintf('Blob %d is a %s\n\n',n,lower(shapeclasses{blobclasses(n)}));

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% create a bunch of subplots

% doing the junk with blind axes position manipulation is a nightmare

% it's entirely dependent on the relationship between the aspect ratio of the figure window

% and the aspect ratio of the images.

% there's no reason to expect that the titles will even be visible.

% the modern suggestion would be to use tiledlayout, but that wasn't an option in 2014.

% FEX subplot_tight() would have probably been sufficient at the time

subplot_tight(2,2,1)

imshow(RGB)

title('Original Image');

subplot_tight(2,2,3)

% idk why the original plotted the input image twice

% i'm just going to plot the binarized image

% since that's why this whole mess wouldn't work in the first place

imshow(Bw)

title('Binarized Image');

subplot_tight(2,2,2)

imshow(Bw)

title('Classified Shapes');

for k = 1:numblobs

ht = text(blobcentroids(k,1),blobcentroids(k,2),shapeclasses{blobclasses(k)});

set(ht,'horizontalalignment','center','fontsize',fontsize,'backgroundcolor',textbgc)

end

subplot_tight(2,2,4)

imshow(Bw)

title('Area in m^2');

for k = 1:numblobs

ht = text(blobcentroids(k,1),blobcentroids(k,2),sprintf('%.3f',blobaream(k)));

set(ht,'horizontalalignment','center','fontsize',fontsize,'backgroundcolor',textbgc)

end

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% create an image with blobs colored by class

% this could also have been done in the main loop

labeledbyclass = zeros(size(Bw),'uint16'); % integer-class

for k = 1:numblobs

thisblobonly = L==k;

labeledbyclass(thisblobonly) = blobclasses(k);

end

% labeloverlay() was not available in 2014

% treat the new label image as an indexed image

% indexed image mapping depends on the numeric class

% for float inputs, mapping starts at 1

% for integer-class inputs, mapping starts at 0

CT = brewermap(numblobs,'paired'); % create the color table

CT = [0 0 0; CT]; % include a black row for the background

coloredbyclass = ind2rgb(labeledbyclass,CT);

figure

imshow(coloredbyclass)

This uses subplot_tight() and brewermap() from the File Exchange. Both would have been available at the time, so I think that's fair. I used brewermap() here simply as a quick way to get a categorical colormap that's long enough for the 10 classes given. The built-in lines() map is not. There would have been alternatives to both.

Note that the classification doesn't actually work very well. I didn't bother to fix that. This was mostly just an exercise creating the colored label image with period-correct tools, but it got sidetracked by simplifying existing code without actually digging into OP's classification approach. Similarly, I'm not touching the question of whether doing edge detection is even an appropriate part of the binarization task. Maybe I'll come back to this some other day.

EDIT: Nevermind; I went ahead and made the classification work at least. It's still not great, but at least it works for this image, and the console dump is helpfully formatted.

You might ask why there aren't any circles or squares detected. That's because there aren't any. Test it with a different image:

how do i assign a color to the same type of shape (2024)

References

Top Articles
Latest Posts
Article information

Author: Rubie Ullrich

Last Updated:

Views: 5442

Rating: 4.1 / 5 (52 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Rubie Ullrich

Birthday: 1998-02-02

Address: 743 Stoltenberg Center, Genovevaville, NJ 59925-3119

Phone: +2202978377583

Job: Administration Engineer

Hobby: Surfing, Sailing, Listening to music, Web surfing, Kitesurfing, Geocaching, Backpacking

Introduction: My name is Rubie Ullrich, I am a enthusiastic, perfect, tender, vivacious, talented, famous, delightful person who loves writing and wants to share my knowledge and understanding with you.