You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
Given a colour image containing a variety of shapes your MATLAB-based system /algorithm should be able to detect and classify/identify the distinct shapes. Your shape detection algorithm should be able to detect the following shapes
1 view (last 30 days)
Show older comments
keagan
on 24 Apr 2014
1. A binary (black and white) image with all the shapes in white and background in black. In addition, a number, indicating the classification according to the above numbered descriptors, must be inserted in the centre of each shape. A value of zero (0) should be placed in the centre of the shape that does not fall into one of the above classifications.
2. A colour image with each shape displayed in a pre-assigned colour i.e. instead of inserting a number into each shape they can be displayed in different colours e.g. blue for all circles and yellow for all hexagons. The colour black must be assigned to all unclassified shapes. The background of this image must be white.
3. A binary (black and white) image with all the shapes in white and background in black. In addition, a number, indicating the area (in m2 and 3 decimal places), must be inserted in the centre of each shape in the image. A text value of "N/A" should be placed in the centre of the shape that does not fall into one of the above classifications. Assume each pixel represents a distance of 1 mm.
Accepted Answer
Image Analyst
on 24 Apr 2014
OK, so what algorithm did you come up with. I can easily think of 2 or 3 off the top of my head. What's your algorithm? And what's your question ?
47 Comments
keagan
on 24 Apr 2014
thanks for reply. I dont have an algorithm yet, i want to know how to detect the shapes. and how do I enter text in the shapes after detecting it and also which commands do i use to fill the shapes with colour and how to get selection on cthese colours
Image Analyst
on 24 Apr 2014
Hint:
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
By extracting the proper color channel you can get the colored shapes.
For the black shaped, extract any of the color channels and threshold:
binaryImage = redChannel < 100;
Then label with bwlabel, and pass in to regionprops to get area and perimeter. Each shape will have a different ratio (perimeter.^2) ./ (4*pi*area).
See my Image Segmentation tutorial for how to filter it to extract just the shapes you want based on the ratio for the shape you want. It finds objects and puts up a label at the center of each shape. http://www.mathworks.com/matlabcentral/fileexchange/?term=authorid%3A31862
This is a huge hint/gift to you since basically all you need to do is to modify my demo. Really makes it easy.
Walter Roberson
on 24 Apr 2014
To fill shapes with color, use fill().
To put text onto the screen, use text()
keagan
on 3 May 2014
Thanks Image Analyst and Walter.
I am going to try these commands on test images. Question to Image Analyst, when you say each shape will have a different ratio with regards to, (perimeter.^2) ./ (4*pi*area).
How do I change ratio to detect other shapes or is that command going to remain the same.
Image Analyst
on 3 May 2014
For example, one shape may have a ratio near 1.5 and another shape may have ratios closer to 2.3, or whatever.
if abs(theRatio-1.5) < 0.2
% It's one shape
elseif abs(theRatio - 2.3) < 0.2
% It's some other shape.
elseif abs(theRatio - 3.3) < 0.8
% It's some third shape
elseif theRatio > 10
% It's a stick shape
end
Image Analyst
on 3 May 2014
Yes. Loop over all blobs getting the ratio and then testing what range it falls into to determine what shape it is.
keagan
on 4 May 2014
Edited: DGM
on 13 Feb 2023
Hello, thanks for above info. I have tried to use the above but cant get it to work when I run the algorithm. I am having a problem to incorporate this into my algorithm. Also I have read segmentation tutorial. Will I also be using regionprops and bounding functions in this algorithm, and also I want to know how many times will I be using the bwlabel loop. I have tried the algorithm below but need to know on which image am I using the bwlabel function on and how do I include the above in my loop.
close all;
img_file='imagefile';
img_wk=imread(img_file);
figure(1),imshow(img_file);
img_wk_gs=rgb2gray(img_wk);
figure(2),imshow(img_wk_gs);
img_wk_bw=img_wk_gs>100;
figure(3),imshow(img_wk_bw);
img_wk_bw_sobel=edge(img_wk_bw,'sobel');
figure(4),imshow(img_wk_bw_sobel),title('sobel');
img_wk_R=img_wk(:,:,1);
figure(11),imshow(img_wk_R);
img_wk_G=img_wk(:,:,2);
figure(12),imshow(img_wk_G);
img_wk_B=img_wk(:,:,3);
figure(13),imshow(img_wk_B);
img_wk_R_edge=edge(img_wk_R,'sobel');
figure(14),imshow(img_wk_R_edge);
img_wk_G_edge=edge(img_wk_G,'sobel');
figure(15),imshow(img_wk_G_edge);
img_wk_B_edge=edge(img_wk_B,'sobel');
figure(16),imshow(img_wk_B_edge);
img_wk_rgb_edge=(img_wk_R_edge+img_wk_G_edge+img_wk_B_edge)>0;
figure(17),imshow(img_wk_rgb_edge);
[L,Ne]=bwlabel(img_wk_rgb_edge);
img_wk_bw_L = L==100;
figure(18),imshow(img_wk_bw_L);
img_wk_bw_L_total=img_wk_bw*0;
for n = 1:Ne
img_wk_bw_L=L==n;
img_wk_bw_L_total=(img_wk_bw_L_total + img_wk_bw_L)>0;
figure(19),imshow(img_wk_bw_L_total);
end.
Image Analyst
on 4 May 2014
Edited: Image Analyst
on 4 May 2014
You haven't attached any image so we can't try your code. Also, I don't see any reason for using edge() if the image looks like what I think it does. Also, please read this: http://www.mathworks.com/matlabcentral/answers/13205-tutorial-how-to-format-your-question-with-markup so you don't need to double space your code.
keagan
on 6 May 2014
Hello Image Analyst
When I am extracting the RGB, is it going to be in a loop that will decide if the the image is a colour image or a binary image. Also when do I use the abs(ratio) function in this. Will I also be using the text function in a loop with the abs function to get numbers into those images detected. Please assist.
keagan
on 6 May 2014
Also the image I am using is a white background image with the different shapes in different colours,not overlapping.
Image Analyst
on 6 May 2014
You don't need a loop to determine if something is grayscale or RGB, just check ndims(). In a loop to put up text labels in the overlay above the image, yes you can use text(). I don't know what you'd use the abs() function for.
Image Analyst
on 6 May 2014
keagan's "Answer" moved here:
You said previously abs(ratio) to determmine shapes. I know rgb2gray. And then that image > 100. As each shape is detected I need to number that shape in the centre of it. Background black with the shapes in white and a number in centre. I am using the image attached as a test image.
Image Analyst
on 6 May 2014
Oh, right, that. That's to find out if the ratio is within some tolerance of the nominal number for that shape, like if the number is 1.5 but you want to check that it's between 1.3 and 1.7. Yes, that's in the loop over all blobs. So in the loop you'd do something like
allAreas = [measurements.Area];
allPerimeters = [measurements.Perimeter];
allRatios = allPerimeters .^ 2 ./ (4 * pi * allAreas);
for k = 1 : numberOfBlobs
% Get this centroid.
thisCentroid = measurements(k).Centroid;
x = thisCentroid(1);
y = thisCentroid(2);
% Get this area, perimeter, and ratio
% Check what shape it is
if abs(allRatios-1.5) < 0.2
shape = 'triangle';
and so on.
% Label each blob at the centroid with sprintf() and text().
textLabel = sprintf('This is a %s', shape);
text(x, y, textLabel, 'FontSize', 14);
end
keagan
on 6 May 2014
Edited: Image Analyst
on 6 May 2014
Thanks. What does the centroid function do, I came across it and tried it in a test but got errors. So in the above I'm going to repeat the above loop each time the same but goin to change the ratio each time and the (shape = triangle) part. Also I get an error for the above, it says an end is missing. So before this step must I imread the image and convert to binary. please assist
Also what value am I using for measurements and area.
Will I be using the bwlabel function here
Image Analyst
on 6 May 2014
Centroid is a measurement made by regionprops of the center of the blob. You will need to label your binary image before you measure it with regionprops. See the BlobsDemo tutorial in my File Exchange. You don't "use" any area for the program - those are measured quantities of the area of each blob. You just take whatever they are and compute the ratios from the.
keagan
on 6 May 2014
thanks When you say blobs u refering to the shapes in image? and where where do i use the imshow(image). and where is the original image being used above or the converted to binary image.
Image Analyst
on 6 May 2014
Yes.
Use imshow whenever/wherever you want to see what any image looks like.
You still haven't posted your image. If you want more help, post your image and your code.
keagan
on 7 May 2014
Ok I have the following code but I dont know how to continue to use the binary image with the code you have given me before this. Also when imshow the binary image, not all the shapes appear from the original image. I also have posted an image.
close all;
img_file = 'design.jpg';
img_w_k = imread(img_file);
figure(1),imshow(img_file);
img_wk_gs = rgb2gray(img_wk);
figure(2),imshow(img_wk_gs);
img_wk_bw = img_wk_gs < 100;
figure(3), imshow(img_wk_bw);
%{
allAreas = [measurements.Area];
allPerimeters = [measurements.Perimeter];
allRatios = allPerimeters .^ 2 ./ (4 * pi * allAreas);
for k = 1 : numberOfBlobs
% Get this centroid.
thisCentroid = measurements(k).Centroid;
x = thisCentroid(1);
y = thisCentroid(2);
% Get this area, perimeter, and ratio
% Check what shape it is
if abs(allRatios-1.5) < 0.2
shape = 'triangle';
and so on.
% Label each blob at the centroid with sprintf() and text().
textLabel = sprintf('This is a %s', shape);
text(x, y, textLabel, 'FontSize', 14);
end
%}
Image Analyst
on 7 May 2014
Edited: Image Analyst
on 7 May 2014
Where did you post the image? And all you did was paste in my code without adapting it. "and so on" is not MATLAB commands. And those numbers I picked out of the air are probably not right. You're going to have to put some effort into this and do something, not just copy and paste and say it doesn't work and keep repeating that until I've written all of your homework for you. How much do you expect me to do for you?
keagan
on 8 May 2014
Hello I do aplogise, but I dont know how to get started. I need some help with how to set up codes.I have only just started using matlab. It's a bit tricky. I used the Attached File icon to send the image. You have given me some hints above, ( you said 'extract and label with bwlabel and run into region props' ) and also you reply that there is no need for an edge detection, but I was under impression that you have to use an edge detection to use the bwlabel function.
Image Analyst
on 8 May 2014
No, you don't need to do edge detection before bwlabel. And I see no indication that you ever ran the tutorial I gave you the link to. I think if you rand and understood that you should have enough to go on.
OK, the image is now there but you haven't said how much of your homework I'm allowed to do before you can't turn it in as yours. Can you answer that?
keagan
on 8 May 2014
I tried to run the image segmentation blob demo, I get a picture with a grey backgoround and pictures with coins. I also tried to use some commands in that demo with my work but I still get pictures of coins appearing. With regards to your last question, I need to get this complteted and also to understand it. Please assist me to get started. I'm also not sure how many loops more I will be using after doing the ratios to figure out what the shapes are. I know I will be using IF, ELSE loop 9 times for the 9 shapes.
keagan
on 8 May 2014
I want to know also if I will be able to detect shapes like the hexagon, octagon, ellipse and pentagon using the ratios.
Image Analyst
on 8 May 2014
The reason for seeing the coins is that that is the demo image file that is being read in by the demo. It will stay that way until you change the filename to that of your image.
Yes you'll have to do an if test for each shape that you want to detect.
keagan
on 8 May 2014
Can you tell me which parts of the code in the image segmentation demo should I concentrate on. Also can you give me something to get started after converting my grayscale image to binary. From what I understood I need to get the first part of the program working to test different ratios to see what shape it represents.
Image Analyst
on 8 May 2014
OK, I've done practically all I can do for you in the attached file. I need to leave something for you to do on your homework or you may get in trouble. It produces the following image
All you have to do is to look for ratios that are unique to each shape and fill out the if/else blocks like I showed you earlier so that each shape gets labeled with its actual shape instead of "triangle" like in the attached code. I give you the region number and the ratio for that region number. You should be able to figure it out, even if you've only been using MATLAB for a week..
keagan
on 8 May 2014
Thanks alot for your help, will let you know if I get it. One more thing, I need to show 3 images for the 3 questions, once i've completed the shape detection part must I repeat the same steps for the next 2 questions but add in the function to colour these shapes instead of numbering it.
Image Analyst
on 8 May 2014
OK. I guess that's correct. You can use the color and ask regionprops for PixelIdxList and then fill it in, like this (untested) code.
Before the loop
% Initialize RGB image.
redImage = zeros(size(shapesBinaryImage), 'uint8');
greenImage = zeros(size(shapesBinaryImage), 'uint8');
blueImage = zeros(size(shapesBinaryImage), 'uint8');
Inside the loop:
redImage(measurements(k).PixelIdxList) = r;
greenImage(measurements(k).PixelIdxList) = g;
blueImage(measurements(k).PixelIdxList) = b;
Then after the loop has finished:
% Create an RGB image from the 3 color channels.
rgbShapes = cat(3, redImage, greenImage, blueImage);
keagan
on 22 May 2014
Moved: DGM
on 13 Feb 2023
Hello Image Analyst
I have been working with the ratios but only found ratios for the circle,sqaure,triangle and rectangle. And also when I run the program I get the diamond shape appearing with the text'square' in it also, just like the square. So I need to use a function with angles in it as a parameter. I also came across the hough transform. Is there any way I could use this
Pls assist
Image Analyst
on 22 May 2014
Moved: DGM
on 13 Feb 2023
Not that I know of. Use bwboundaries() and see the FAQ http://matlab.wikia.com/wiki/FAQ#How_do_I_find_.22kinks.22_in_a_curve.3F
yeshmeel
on 2 Jun 2014
Moved: DGM
on 13 Feb 2023
Like in this section of the code....
for k = 1 : numberOfRegions % Get this centroid.
thisCentroid = measurements(k).Centroid;
x = thisCentroid(1); y = thisCentroid(2); % Get the color at the centroid
r = redChannel(int32(y), int32(x));
g = greenChannel(int32(y), int32(x));
b = blueChannel(int32(y), int32(x));
strColor = sprintf('color = [%d, %d, %d]', r, g, b); % Check what shape it is
if abs(allRatios-1.12) < 0.2
shape = 'triangle'; % Label each blob at the centroid with sprintf() and text().
textLabel = sprintf('1', k, shape, strColor);
text(x, y, textLabel, 'FontSize', 8, 'Color', 'r');
% ...
end
% ...
end
what ratio would you fill in for it to detect a triangle in the image?
Image Analyst
on 2 Jun 2014
Moved: DGM
on 13 Feb 2023
Did you see my previous code in a comment where I showed how to find the rations of each shape:
labeledImage = bwlabel(binaryImage);
measurements = regionprops(labeledImage, 'Area', 'Perimeter', 'Centroid');
allAreas = [measurements.Area];
allPerimeters = [measurements.Perimeter];
allRatios = allPerimeters .^ 2 ./ (4 * pi * allAreas);
for k = 1 : numberOfBlobs
% Get this centroid.
thisCentroid = measurements(k).Centroid;
fprintf('For blob #%d, the Ratio = %f\n', k, allRatios(k));
x = thisCentroid(1);
y = thisCentroid(2);
% Get this area, perimeter, and ratio
% Check what shape it is
if abs(allRatios-1.5) < 0.2
shape = 'triangle';
and so on.
% Label each blob at the centroid with sprintf() and text().
textLabel = sprintf('This is a %s', shape);
text(x, y, textLabel, 'FontSize', 14);
end
yeshmeel
on 2 Jun 2014
Moved: DGM
on 13 Feb 2023
oh okay thanks mahhn, and where will i like see these ratios?? where will it be displayed?
im really confused with this part of the code :
if abs(allRatios-1.5) < 0.2
shape = 'triangle';
you are subtracting "allratios" from what value? and what value are you using on the right off the less than sign? i know they are probably ratios but when i run this code using the values youve given it does not detect a triangle.
Can you please give me an example of the ratios you would use to detect any shape maybe a triangle or a circle so i can use that as an example to detect the rest of the shapes, id really appreciate it :)
Image Analyst
on 2 Jun 2014
Moved: DGM
on 13 Feb 2023
That line says if the ratio is between 1.3 and 1.7, it's a triangle. There are different ranges for different shapes.
Image Analyst
on 2 Jun 2014
Moved: DGM
on 13 Feb 2023
I just made up some value. There is a fprintf() in there so you can see the ratios for each object. Examine those and figure out the ratio range for each shape. You can do that as well as I can.
More Answers (0)
See Also
Categories
Find more on Data Distribution Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)