get the width of bounding box

i'm trying to make a size sorter but ran into a problem; does anyone know how to make matlab draw a box around this potato and then determine the width of this box?

 Accepted Answer

It seems that regionprops function will be helpful, like:
% Read the image and binarize
I = imread('aardappels.jpg');
% Create the region of interest (ROI)
Igray = rgb2gray(I);
ROI = ~imbinarize(Igray, 0.9);
ROI = bwconvhull(ROI);
% Measure properties of the ROI
stats = regionprops(ROI, 'BoundingBox','MajorAxisLength','MinorAxisLength');
% Show the result
imshow(I);
hold on;
rectangle('Position', stats.BoundingBox,'EdgeColor','b');
The major and minor axis of the bounding box is stored in stats.
>> stats
stats =
BoundingBox: [53.5000 68.5000 698 883]
MajorAxisLength: 899.6647
MinorAxisLength: 708.4894

3 Comments

best Akira Agata, Frist I want to say thanks for the time and your answer, but do you perhaps know a simple way to make sure that the potato is always in the smallest possible box? if, for example the potato on the picture is rotated (like in this picture(test.jpg)) can the box be rotated with it, so I can still get the width of the potato?(like in potatobox.png) thanks for the help.
Hi wille-san,
In my script, unfortunately, the potato is NOT always in the smallest box if rotated. But I have an idea to obtain such a bounding box. Please give me a few more days :-)
I've just modified. As far as shape of a potato is similar to ellipse, I believe it works!
% Read the image and binarize
I = imread('test.jpg');
% Create the region of interest (ROI)
Igray = rgb2gray(I);
ROI = ~imbinarize(Igray, 0.9);
ROI = bwconvhull(ROI);
% Measure properties of the ROI
stats = regionprops(ROI,...
'Centroid','MajorAxisLength','MinorAxisLength','Orientation');
% Make position array of rectangle w/o rotation and translate
pos = [-stats.MajorAxisLength/2, -stats.MinorAxisLength/2,...
stats.MajorAxisLength, stats.MinorAxisLength];
% Show the result
imshow(I)
hold on
g = hgtransform;
g.Matrix = makehgtform('translate',[stats.Centroid, 0])*...
makehgtform('zrotate', -deg2rad(stats.Orientation));
rectangle('Position', pos,'EdgeColor','b','Parent',g)
The result is stored in stats:
>> stats
stats =
Centroid: [727.8221 735.9809]
MajorAxisLength: 1.4733e+03
MinorAxisLength: 935.3463
Orientation: 17.0534

Sign in to comment.

More Answers (3)

jue xi
jue xi on 26 Apr 2018
can i know the major/minor axis length unit? cos i need to get the measurement in cm. so i need to know its unit to convert it to cm. tq

4 Comments

The major/minor axis length is in pixels. So, to measure in cm, you need to know the ratio of pixel-length in your image against cm in real world.
jue xi
jue xi on 26 Apr 2018
Edited: jue xi on 26 Apr 2018
thank you.. but here one more question.. how to get the ratio of pixel-length in my image ? i have the manual measurement in cm but in pixel..?
if true
% code
folder=('C:\Users\user\MATLAB');
baseFileName=('img11.jpg');
fullFileName=fullfile(folder,baseFileName);
format long g;
format compact;
fontSize = 20;
%IMAGE SEGMENTATION
img=imread(fullFileName);
img=rgb2ycbcr(img);
for i=1:size(img,1)
for j= 1:size(img,2)
cb = img(i,j,2);
cr = img(i,j,3);
if(~(cr > 132 && cr < 173 && cb > 76 && cb < 126))
img(i,j,1)=235;
img(i,j,2)=128;
img(i,j,3)=128;
end
end
end
img=ycbcr2rgb(img);
subplot(2,2,1);
image1=imshow(img);
axis on;
title('Skin Segmentation', 'FontSize', fontSize);
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
%SEGMENTED IMAGE TO GRAYIMAGE
grayImage=rgb2gray(img);
subplot(2,2,2);
image2=imshow(grayImage);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize);
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
%GRAY TO BINARY IMAGE
binaryImage = grayImage < 245;
subplot(2, 2, 3);
axis on;
image3=imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize);
% Label the image
labeledImage = bwlabel(binaryImage); % label the connected components in an image and assigning each one a unique label
measurements = regionprops(labeledImage, 'BoundingBox', 'Area');
for k = 1 : length(measurements)
thisBB = measurements(k).BoundingBox;
rectangle('Position', [thisBB(1),thisBB(2),thisBB(3),thisBB(4)],...
'EdgeColor','r','LineWidth',2 )
end
% Let's extract the second biggest blob - that will be the hand.
allAreas = [measurements.Area];
[sortedAreas, sortingIndexes] = sort(allAreas, 'descend');
handIndex = sortingIndexes(2); % The hand is the second biggest, face is biggest.
% Use ismember() to extact the hand from the labeled image.
handImage = ismember(labeledImage, handIndex);
% Now binarize
handImage = handImage > 0;
% Display the image.
subplot(2, 2, 4);
image4=imshow(handImage, []);
axis on;
axis image;
title('Hand Image', 'FontSize', fontSize);
% Label the image
labeledImage = bwlabel(handImage); % label the connected components in an image and assigning each one a unique label
measurements = regionprops(labeledImage, 'BoundingBox', 'Area');
for k = 1 : length(measurements)
thisBB = measurements(k).BoundingBox;
rectangle('Position', [thisBB(1),thisBB(2),thisBB(3),thisBB(4)],...
'EdgeColor','r','LineWidth',2 )
end
% Make measurements of bounding box
props = regionprops(labeledImage, 'BoundingBox');
width = props.BoundingBox(3);
height = props.BoundingBox(4);
hold on;
rectangle('Position', props.BoundingBox, 'EdgeColor', 'r', 'LineWidth', 2);
message = sprintf('The width = %f.\nThe height = %f', width, height);
uiwait(helpdlg(message));
end
Akira Agata
Akira Agata on 26 Apr 2018
Edited: Akira Agata on 26 Apr 2018
OK, let's take a look at these two images. They show the same contents --- red rectangle with 3cm width --- in different resolution.
Then, by using imtool or something, you can measure the length of the width in pixel for each file. The result will be as follows (around 114 pixels and 183 pixels, respectively).
Since the resolution of each picture is different, pixel length becomes different even when the same object in real world. That's why you have to know the ratio between pixel length and cm in real world (in this case, 3/114 [cm/pixel] for the first picture, and 3/183 [cm/pixel] for the second).
scale1.jpg:
scale2.jpg:
i see, i'll try it,thanks you btw for your time.

Sign in to comment.

jue xi
jue xi on 26 Apr 2018
is this what u mean? if im not mistaken. my ratio is 4:3
hi, i combining this coding to convert it to cm.. is this the right coding to use?
if true
% codeprops = regionprops(labeledImage, 'BoundingBox','MajorAxisLength');
X= props.BoundingBox(3);
Y = props.BoundingBox(4);
res=info.ResolutionUnit;
resX=info.XResolution;
resY=info.YResolution;
if strcmp( res,'Inch');
width=2.54*X/resX;
height=2.54*Y/resY;
else
width=X/ resX;
height=Y/resY;
end
fprintf('X Resolution = %.2f %s\n', resX, res);
fprintf('Y Resolution = %.2f %s\n', resY, res);
disp('Size of Object:');
fprintf('Width = %.2f cm\n', width);
fprintf('Height = %.2f cm\n', height);
end
then after i get the width and height, i apply the Pythagoras theorem to get the hand measurement from elbow line to finger.. below are the whole coding to get as pic above..

1 Comment

if true
% code
folder=('C:\Users\user\MATLAB');
baseFileName=('img2.jpg');
info=imfinfo(baseFileName);
fullFileName=fullfile(folder,baseFileName);
format long g;
format compact;
fontSize = 20;
%IMAGE SEGMENTATION
img=imread(fullFileName);
img=rgb2ycbcr(img);
for i=1:size(img,1)
for j= 1:size(img,2)
cb = img(i,j,2);
cr = img(i,j,3);
if(~(cr > 132 && cr < 173 && cb > 76 && cb < 126))
img(i,j,1)=235;
img(i,j,2)=128;
img(i,j,3)=128;
end
end
end
img=ycbcr2rgb(img);
subplot(2,2,1);
image1=imshow(img);
axis on;
title('Skin Segmentation', 'FontSize', fontSize);
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
%SEGMENTED IMAGE TO GRAYIMAGE
grayImage=rgb2gray(img);
subplot(2,2,2);
image2=imshow(grayImage);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize);
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
%GRAY TO BINARY IMAGE
binaryImage = grayImage < 245;
subplot(2, 2, 3);
axis on;
image3=imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize);
% Label the image
labeledImage = bwlabel(binaryImage); % label the connected components in an image and assigning each one a unique label
measurements = regionprops(labeledImage, 'BoundingBox', 'Area');
for k = 1 : length(measurements)
thisBB = measurements(k).BoundingBox;
rectangle('Position', [thisBB(1),thisBB(2),thisBB(3),thisBB(4)],...
'EdgeColor','r','LineWidth',2 )
end
% Let's extract the second biggest blob - that will be the hand.
allAreas = [measurements.Area];
[sortedAreas, sortingIndexes] = sort(allAreas, 'descend');
handIndex = sortingIndexes(2); % The hand is the second biggest, face is biggest.
% Use ismember() to extact the hand from the labeled image.
handImage = ismember(labeledImage, handIndex);
% Now binarize
handImage = handImage > 0;
% Display the image.
subplot(2, 2, 4);
image4=imshow(handImage, []);
axis on;
axis image;
title('Hand Image', 'FontSize', fontSize);
% Label the image
labeledImage = bwlabel(handImage); % label the connected components in an image and assigning each one a unique label
measurements = regionprops(labeledImage, 'BoundingBox', 'MajorAxisLength');
for k = 1 : length(measurements)
thisBB = measurements(k).BoundingBox;
rectangle('Position', [thisBB(1),thisBB(2),thisBB(3),thisBB(4)],...
'EdgeColor','r','LineWidth',2 )
end
% Make measurements of bounding box
props = regionprops(labeledImage, 'BoundingBox','MajorAxisLength');
X= props.BoundingBox(3);
Y = props.BoundingBox(4);
res=info.ResolutionUnit;
resX=info.XResolution;
resY=info.YResolution;
if strcmp( res,'Inch');
width=2.54*X/resX;
height=2.54*Y/resY;
else
width=X/ resX;
height=Y/resY;
end
fprintf('X Resolution = %.2f %s\n', resX, res);
fprintf('Y Resolution = %.2f %s\n', resY, res);
disp('Size of Object:');
fprintf('Width = %.2f cm\n', width);
fprintf('Height = %.2f cm\n', height);
hold on;
rectangle('Position', props.BoundingBox, 'EdgeColor', 'r', 'LineWidth', 2);
message = sprintf('The width = %f.\nThe height = %f', width, height);
uiwait(helpdlg(message));
end

Sign in to comment.

Categories

Find more on Deep Learning Toolbox in Help Center and File Exchange

Asked:

on 11 Oct 2017

Commented:

on 3 May 2018

Community Treasure Hunt

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

Start Hunting!