detect square shape of the grayscale image

5 views (last 30 days)
I have a grayscale image (as preview). I'd like to threshold the circle and square (dark) shape individually in that image. I've found the way to threshold the circle shape (from binary image) using imfindcircles and viscircles. However, I couldn't find the way to threshold and display (without crop) the square shape . One more thing, I'd like also find the center of both shape.
Could anyone please help me.
Thank you.

Accepted Answer

Image Analyst
Image Analyst on 11 Nov 2016
Try this. Adapt as needed. Let me know if you can or not.
% Program to find the circle regions in a demo image.
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 = 22;
% Check that user has the Image Processing Toolbox installed.
hasIPT = license('test', 'image_toolbox');
if ~hasIPT
% User does not have the toolbox installed.
message = sprintf('Sorry, but you do not seem to have the Image Processing Toolbox.\nDo you want to try to continue anyway?');
reply = questdlg(message, 'Toolbox missing', 'Yes', 'No', 'Yes');
if strcmpi(reply, 'No')
% User said No, so exit.
% Read in the gray scale demo image.
folder = pwd;
baseFileName = 'iso.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.
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);
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[rows, columns, numberOfColorBands] = size(grayImage);
if numberOfColorBands > 1
% It's not really gray scale like we expected - it's color.
% Convert it to gray scale by taking only the green channel.
grayImage = grayImage(:, :, 2); % Take green channel.
% Display the original gray scale image.
subplot(2, 3, 1);
imshow(grayImage, []);
axis on;
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);
% The first and last bin of pixelCount are so huge that it suppresses the height
% of the rest of the histogram when plotted. Zero out these bins so we can see the other bins.
pixelCount(1) = 0;
pixelCount(end) = 0;
subplot(2, 3, 2);
bar(grayLevels, pixelCount, 'BarWidth', 1, 'FaceColor', 'b');
grid on;
title('Histogram of Original Image', 'FontSize', fontSize);
xlim([0 grayLevels(end)]); % Scale x axis manually.
% Threshold (binarize) the image.
thresholdValue = 25;
% Draw a red line on the histogram at this value.
line([thresholdValue, thresholdValue], ylim, 'LineWidth', 2, 'Color', 'r');
% Label the regions for the two body zones.
text(28, 1500, 'Threshold = 25', 'Color', 'r', 'FontSize', 20, 'FontWeight', 'bold');
binaryImage = grayImage > thresholdValue; % Do the thresholding.
% Display the binary image.
subplot(2, 3, 3);
imshow(binaryImage, []);
axis on;
title('Binary Image', 'FontSize', fontSize);
% Get rid of stuff touching the border
binaryImage = imclearborder(binaryImage);
% Extract only the two largest blobs.
binaryImage = bwareafilt(binaryImage, 1);
% Fill holes in the blob to make it solid.
binaryImage = imfill(binaryImage, 'holes');
% Display the binary image.
subplot(2, 3, 4);
imshow(binaryImage, []);
axis on;
title('Circle-Only Binary Image', 'FontSize', fontSize);
% Mask image with circle-only mask.
% This will produce a gray scale image in the circle and black everywhere else.
maskedImage = grayImage; % Initialize
maskedImage(~binaryImage) = 0;
% Display the masked gray scale image of only the circle.
subplot(2, 3, 5);
imshow(maskedImage, []);
axis on;
title('Masked Circle-Only Image', 'FontSize', fontSize);
% Label the image
labeledImage = bwlabel(binaryImage);
props = regionprops(labeledImage, 'Centroid', 'Area');
% Plot a big red cross over the centroid.
hold on;
plot(props.Centroid(1), props.Centroid(2), 'r+', 'MarkerSize', 50);
message = sprintf('The Area = %f.\nThe Centroid is at (x,y) = (%f, %f)', ...
props.Area, props.Centroid);
Image Analyst
Image Analyst on 11 Nov 2016
  1. Didn't I detect the circle? What was that bright thing in the middle of the image? I thought it was the circle - that's what I detected. If it's not, then please indicate clearly where the circle it. True, I did it via a different way than imfindcircles() so you can see an alternate way. You can use whichever method you want to.
  2. When I suggested that you find the square similar to how I found the circle you say "I managed to do just like you." but then you say "my problem is to detect square shape". So did you follow my example to find the square, or not? Your answer seems ambiguous, and even contradictory. If you don't know how to modify my code, let me know and I'll do it for you.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!