hi ı am a master student and I have a home work
3 views (last 30 days)
Show older comments
I have A BİNARY PİCTURE AND I WANT TO CALCULATE İT'S MAXİMUM width and length.can you help me?
8 Comments
Jan
on 27 Mar 2017
Posting the picture is very useful. Immediately I know what "length" and "width" mean.
Accepted Answer
Jan
on 27 Mar 2017
Edited: Jan
on 9 Apr 2017
The properties 'MajorAxisLength' and 'MinorAxisLength' might be useful. Please try to call regionprops with them.
I hesitate to post the code, because you should be able to provide it as solution without cheating. Your professor knows this forum also. If I post the corresponding line of code, he could think that you have just copied them from me.
[EDITED] I trust Image Analyst's statement, that regionprops is not perfect, but a cheap approxination only. But your professor asked explicitely for this command. Perhaps he only wants to encourage you to play with this command to get familar with it. Therefore an alternative cheap and rough idea:
Determine the 'Orientation' with regionprops. Then rotate the image with imrotate and call regionprops again to determine the 'BoundingBox'. This might not be perfect, but perhaps it satisfies your professor and solves the homework with some lines of code.
And for a serious solution, please consider Image Analyst's valuable answer.
0 Comments
More Answers (3)
Image Analyst
on 28 Mar 2017
I'm saying it again: regionprops will not give you the answer. If that's what your professor thought, then he's wrong.
I use regionprops() all day long, every day, so I'm very familiar with it. I've scratched the help documentation for it onto the insides of my eyelids. The MajorAxisLength will not return the farthest distance. Extrema won't either because it doesn't go from pixel center-to-pixel center but is half a pixel away/outside of the pixel centers. The way to do it is what I said in my other answer.
Maybe it was a bit challenging for you so I've rewritten it, and I also added the regionprops/extrema way also, so you can see that they give different answers. I didn't even ask for MajorAxisLength because that is so clearly wrong. The regionprops/extrema method is close to the right answer but not exact because it goes a half pixel outside of the blob perimeter.
% Cleanup/initialization
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
format short g;
format compact;
fontSize = 20;
%===============================================================================
% Get the name of the image the user wants to use.
baseFileName = 'abdullahmavikapali.jpg'; % Assign the one on the button that they clicked on.
% Get the full filename, with path prepended.
folder = []; % Determine where demo folder is (works with all versions).
fullFileName = fullfile(folder, baseFileName);
%===============================================================================
% Read in a demo image.
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
grayImage = rgb2gray(grayImage);
% ALTERNATE METHOD: Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
% grayImage = grayImage(:, :, 2); % Take green channel.
end
% Display the image.
imshow(grayImage, []);
axis on;
caption = sprintf('Original Gray Scale Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo();
% grayImage is a gray scale image with values of mostly 0 and 254 but some other in between values
% because of the JPG artifacts, which is why you should never use JPG for image analysis.
% Binarize the image by thresholding.
binaryImage = grayImage > 128;
imshow(binaryImage);
axis on;
axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
title('Binary Image Mask with boundaries shown in blue and longest line in red', 'fontSize', fontSize);
hold on;
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
% Plot the borders of all the coins on the original grayscale image using the coordinates returned by bwboundaries.
boundaries = bwboundaries(binaryImage);
numberOfBoundaries = size(boundaries, 1);
for blobIndex = 1 : numberOfBoundaries
thisBoundary = boundaries{blobIndex};
x = thisBoundary(:, 2); % x = columns.
y = thisBoundary(:, 1); % y = rows.
% Find which two boundary points are farthest from each other.
maxDistance = -inf;
for k = 1 : length(x)
distances = sqrt( (x(k) - x) .^ 2 + (y(k) - y) .^ 2 );
[thisMaxDistance, indexOfMaxDistance] = max(distances);
if thisMaxDistance > maxDistance
maxDistance = thisMaxDistance;
index1 = k;
index2 = indexOfMaxDistance;
end
end
% Index1 is one end of the longest line. Index2 is the other end.
% Draw a line between the endpoints.
% Plot the boundary over the gray scale image going around the blob.
plot(x, y, 'b-', 'LineWidth', 3);
% For this blob, put a line between the points farthest away from each other.
line([x(index1), x(index2)], [y(index1), y(index2)], 'Color', 'r', 'LineWidth', 3);
message = sprintf('The longest line is red.\nMax distance for blob #%d = %.2f\n', ...
blobIndex, maxDistance);
fprintf('%s\n', message);
uiwait(helpdlg(message));
end
hold off;
%========================================================================================
% Do it again, this time using regionprops.
% But we need to use Extreme, not MajorAxisLength
[labeledImage, numBlobs] = bwlabel(binaryImage);
props = regionprops(labeledImage, 'Extrema');
extrema = props.Extrema
x = extrema(:, 1); % x = columns.
y = extrema(:, 2); % y = rows.
% Find which two boundary points are farthest from each other.
maxDistance = -inf;
for k = 1 : length(x)
distances = sqrt( (x(k) - x) .^ 2 + (y(k) - y) .^ 2 );
[thisMaxDistance, indexOfMaxDistance] = max(distances);
if thisMaxDistance > maxDistance
maxDistance = thisMaxDistance;
index1 = k;
index2 = indexOfMaxDistance;
end
end
% Index1 is one end of the longest line. Index2 is the other end.
% Draw a line between the endpoints.
figure;
imshow(binaryImage);
axis on;
axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
title('Binary Image Mask with boundaries shown in blue and longest line in red', 'fontSize', fontSize);
hold on;
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
% Plot the boundary over the gray scale image going around the blob.
plot(x, y, 'b-', 'LineWidth', 3);
% For this blob, put a line between the points farthest away from each other.
line([x(index1), x(index2)], [y(index1), y(index2)], 'Color', 'r', 'LineWidth', 3);
distanceByExtrema = sqrt((x(index1) - x(index2))^2 + (y(index1) - y(index2))^2);
message = sprintf('The distance using regionprops() and Extreme is %f\n', distanceByExtrema);
fprintf('%s\n', message);
uiwait(helpdlg(message));

2 Comments
Jan
on 28 Mar 2017
@Image Analyst: +1. I agree with you, that 'MajorAxisLength' is not correct from the scientific point of view. But the professor asked specifically for this command - perhaps this has an intention. As long as this is a homework question only, and neither research nor productive work, I assume that a semi-professional "solution" might satisfy the professor already. This would be just the next example for a "bad" homework question.
It might reveal what the question actually means, if "width" and "length" is defined exactly.
Guillaume
on 28 Mar 2017
Regardless of what the professor asked, I would expect a master student:
- To work out the answer for themselves without having to ask on a forum. A good student would go to their library and grab a book on image processing.
- To engage their critical thinking and if the suggested function (regionprops) does not give the appropriate result, to a) notice and comment on it, and b) supply a solution that gives the correct result.
Image Analyst
on 27 Mar 2017
regionprops() will not get you the maximum length (distance between two points on the outer perimeter). Your teacher must not use it very much. It finds the MajorAxisLength, which is the major axis of an ellipse fitted to the blob. It also finds "Extrema" which is closer to what you want, but will take a lot of extra analysis to get the actual distance.
To find the actual farthest distance between any two points, you'll have to use my attached function. Basically it calls bwboundaries() and gets the distance of envery point to every other point and finds the pair that are the farthest apart. Then it finds the farthest apart in the perpendicular direction.
0 Comments
John BG
on 28 Mar 2017
Edited: John BG
on 29 Mar 2017
Hi Hasan
Let me show you 2 ways to get the long axis distance you want measured, one way without regionprops and another way with regionprops, showing both results match.
Then we are going to measure the minor axis, that I agree with Image Analyst, regionprops may not be the best command to measure the second axis.
1.
clear all;clc;close all
A=imread('001.jpg');
A1=A(:,:,1);
A1(A1>125)=255;A1(A1<=125)=0;
imshow(A1);hold all
.

.
[fy,fx]=find(A1>0);plot(fx,fy,'ro')
plot([min(fx) max(fx) max(fx) min(fx) min(fx)],[min(fy) min(fy) max(fy) max(fy) min(fy)],'b')
.

.
the diagonal distance I understand you want is:
D=((max(fx)-min(fx))^2+(max(fy)-min(fy))^2)^.5
D =
123.57
The way your professor wants, with regionprops
2.
mxL=regionprops(A1,'MajorAxisLength')
D2=max(cell2mat(struct2cell(mxL)))
D2 =
123.77
3.
now the minor axis
angle that regionprops measures
ang=regionprops(A1,'Orientation')
a=max(cell2mat(struct2cell(ang)))
a =
68.72
measuring attitude angle directly
p1=[min(fx) min(fy)];p2=[max(fx) max(fy)]
p3=[max(fx) min(fy)];p4=[min(fx) max(fy)]
a1=atan((p2(2)-p1(2))/(p2(1)-p1(1)))*180/pi
a2=atan((p4(2)-p3(2))/(p4(1)-p3(1)))*180/pi
a1 =
66.13
a2 =
-66.13
So, there's an angle error of 2º, difference between regionprops Orientation angle measurement and the angle out of rectangle vertices
if a-a1 < a-a2 % choose angle closest to orientation angle from regionprops
a0=a2;
plot([p3(1) p4(1)],[p3(2) p4(2)],'y','LineWidth',2) % plotting diagonal
v1=p3;v2=p4;
elseif a-a1 > a-a2
a0=a1;
plot([p1(1) p2(1)],[p1(2) p2(2)],'y','LineWidth',2) % plotting diagonal
v1=p1;v2=p2;
end
plot(v1(1),v1(2),'g*')

capturing the points of the yellow diagonal
N=floor(max(abs(v1(1)-v2(1)),abs(v1(2)-v2(2))));
n1=floor(linspace(v1(1),v2(1),N));
n2=floor(linspace(v1(2),v2(2),N));
adding rails to measure small scross section
N0=floor(N/2)
T={}
for k=1:1:N
plot(n1(k)-N0*sind(a),n2(k)-N0*cosd(a),'r*')
plot(n1(k)+N0*sind(a),n2(k)+N0*cosd(a),'r*')
d1=floor(linspace(n1(k)-N0*sind(a),n1(k)+N0*sind(a),floor(max(N0*cosd(a),N0*sind(a)))))
d2=floor(linspace(n2(k)-N0*cosd(a),n2(k)+N0*cosd(a),floor(max(N0*cosd(a),N0*sind(a)))))
% plot(d1,d2,'g')
L=[0 0]
for s=1:1:numel(d1)
if(A1(d2(s),d1(s))>0)
L=[L ;d2(s) d1(s)]
end
end
T=[T ; L];
% n1(k)-N0*cosd(a),n2(k)-N0*sind(a)
% n1(k)+N0*cosd(a),n2(k)+N0*sind(a)
end

.
capture extreme poins of each cross section angled angle a
C=[0 0 0 0] [x1 x2 y1 y2 d(p1,p2) mid]
for k=1:1:size(T,1)
D=T{k}
D1=nonzeros(D(:,1));D2=nonzeros(D(:,2));
C=[C; min(D1) max(D1) min(D2) max(D2)];
end
C(1,:)=[]
find angled cross sections with max distance
E=[0 0 0];
for k=1:1:size(C,1)
E=[E; ((C(k,1)-C(k,2))^2+(C(k,3)-C(k,4))^2)^.5 (C(k,1)+C(k,2))/2 (C(k,3)+C(k,4))/2]
end
figure(2);plot(E(:,1))
.

L=E(:,1);max(L)
=
13.60
Result: max minor cross section at 66º is 22.47 pixels
.
E0=find(L==max(L));hold all
figure(1);plot(E(E0,3),E(E0,2),'g*')
marking boundaries of broadest angled cross sections
for k=E0
plot([C(k,3) C(k,4)],[C(k,1) C(k,2)],'go')
plot([C(k,3) C(k,4)],[C(k,1) C(k,2)],'bo')
end
.

.
if you find these lines useful would you please be so kind to mark my answer as Accepted Answer?
To any other reader, if you find this answer of any help, would you please click on the thumbs-up vote link,
thanks in advance for time and attention
John BG
.
additional note: just in case you need hte contour, capturing the contour points of the sample is immediate with del2
A2=del2(double(A1))
figure(3);h2=imshow(A2)
pcontour=h2.CData;
[cntx,cnty]=ind2sub(size(A1),find(pcontour>0));
hold all;plot(cnty,cntx,'g*')
.

0 Comments
See Also
Categories
Find more on Image Processing Toolbox in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!