How can i divide an image into sectors with MATLAB?

Hi
How I can divide an image into 8 equi-angular areas using as center the center of mass of the region? Then the contour points of region are identified and if the distribution of the radii of the polar coordinates of the contour points exhibit large variation for one of the eight areas the 'border' value is increased by one. This happens for all eighths until the final value is estimated that should be between 0 and 8.
Can you help me to do this with MATLAB?

Réponses (3)

Are the "contour points" the boundary points of the sectors? Do you have those? That's just simple 10th grade trigonometry. Do you have the center of mass? That's just using regionprops where the binary image is true(size(grayImage)), and you ask for 'WeightedCentroid':
measurements = regionprops(true(size(grayImage)), grayImage, 'WeightedCentroid');
centerOfMass = measurements.WeightedCentroid;
or something like that. Then use trig to send out lines from the center of mass to the border of the image. Then use poly2mask() to create a binary image which you then multiply by your gray scale image to get the masked sector.
% Mask the image.
maskedImage = bsxfun(@times, grayImage, cast(mask, class(grayImage)));
So I think that's the step by step process I think you need to follow, if I understood you correctly.

14 commentaires

Pamela
Pamela le 20 Oct 2012
Modifié(e) : Pamela le 3 Jan 2013
thanks Image Analyst for your reply. The region is detected very well using the function imagesegmentation
img=imread('image');
imshow(img);
I=imagesegmentation(img)
1-What's the difference between 'Centroid' and 'WeightedCentroid'??
2-How can i add the two other lines?? How can I find their length and their orientation??
3-How can I use poly2mask() and what's the purpose??
4-I couldn't understand these lines
% Mask the image.
maskedImage = bsxfun(@times, grayImage, cast(mask, class(grayImage)));
5-How i can detect the large variation of distribution of the radii of the polar coordinates of the contour for every eighths and use it to increase the value 'border'
Image Analyst
Image Analyst le 20 Oct 2012
Modifié(e) : Image Analyst le 20 Oct 2012
1. WeightedCentroid takes into account the graylevels of the original grayscale image while Centroid does not. So a skewed Gaussian spot would show the weighted centroid near the peak while a centroid would be off the peak. I don't have imagesegmentation() so I don't know what I is. But if I is a binary image, then you can't get weighted centroid from that.
2. not sure what this means.
3. poly2mask() turns a list of (x,y) coordinates into a binary image that you can then multiply by your original image to blacken parts outside the mask.
4. It's like
maskedImage = grayImage; % Initialize
maskedImage(~binaryImage) = 0; % Blacken outside binary (white) regions.
5. I don't know what this means. As usual, I think uploading an image would help.
Pamela
Pamela le 20 Oct 2012
Modifié(e) : Pamela le 3 Jan 2013
this an image that explains the purpose of the code
Well I can't run your code because of that custom "imagesegmentation" function, but is it now working for you? You might have to invert your image to get weighted centroid since it gives higher weight to brighter pixels, not darker ones. But I still don't know what you want to do if you had sectors. Let's say you had one sector - one slice of the pie. Then what would you do with it?
Pamela
Pamela le 20 Oct 2012
Modifié(e) : Pamela le 3 Jan 2013
I had a correct segmentation with the function imagesegmentation. With the previous code I managed to trace only two axes of the 4 because I couldn't find the lengths and the orientations of the two others. I asked my question in this forum because I found this paragraph with the uploaded image but I couldn't translate all this in matlab.
The paragraph: "Irregularities of border can be mesured using these steps: The image is divided into 8 equi-angular areas using as center the center of mass O of the region. Then the contour points of region are identified and if the distribution of the radii of the polar coordinates of the contour points exhibit large variation for one of the eight areas the 'border' value is increased by one."
Get the binary image. Then use bwboundaries to get the boundary coordinates. Then find the centroid or weighted centroid. Then go around the boundary and computer the Euclidean distance between each boundary coordinate and the centroid. Also compute the angle and which of the 8 sectors it belongs in. For each of the 8 groups of distances you computed, get their standard deviation. If it's more than some predetermined amount, increment the "border" value by one. After all this you will have 8 "border" values. If a sector has a smooth circular shape, it's std dev will be zero, and the std dev will increase the more tortuous the border is.
Pamela
Pamela le 21 Oct 2012
Modifié(e) : Pamela le 29 Oct 2012
Thank you for your reply
1-How can I find the number of piwels in the border to use it to compute the euclidean distanse
2-"Also compute the angle and which of the 8 sectors it belongs in". The angle of each sector is pi/4??
3-"For each of the 8 groups of distances you computed, get their standard deviation". How??
4-"If it's more than some predetermined amount, increment the "border" value by one." How can I have determine this amount??
  1. numberOfRegions = length(B);
  2. Yes
  3. Get the pixel values from measurements(k).PixelValues. Then use std() on that.
  4. That is a parameter you specify. The paper probably gave the value that they used.
Pamela
Pamela le 21 Oct 2012
Modifié(e) : Pamela le 21 Oct 2012
Hi thank you for your reply but I ploted only two axes and I couldn't plot the two others. I couldn't also get the derivation of distance for each of the 8 segment. thank you for helping me by completing the code. I need your help urgently
Bw = bwboundaries(J)
border=0;
measurements = regionprops(J, 'Centroid', 'MinorAxisLength', 'MajorAxisLength', 'Orientation', 'PixelValues');
or=measurements.Orientation
m1=measurements.MajorAxisLength;
ax1 = m1*[-1 1]./2*cos(or*pi/180);
ay1 = m1*[1 -1]./2*sin(or*pi/180);
Major = line(ax1+measurements.Centroid(1),ay1+measurements.Centroid(2));
m2=measurements.MinorAxisLength;
ax2 = m2*[-1 1]./2*cos(or*pi/180+pi/2);
ay2 = m2*[1 -1]./2*sin(or*pi/180+pi/2);
Minor = line(ax2+measurements.Centroid(1),ay2+measurements.Centroid(2));
x2=measurements.Centroid(1);
y2=measurements.Centroid(2);
for k = 1:length(Bw)
boundary = Bw{k};
y1=boundary(k,2);
x1=boundary(k,1);
distance = sqrt((x2-x1).^2+(y2-y1).^2);
end
regionprops is only used to find the centroid. You don't use it to measure orientation the way it does, where it fits an ellipse to your blob. You don't want that, so get rid of all the stuff about major and minor axis lengths. You want to just look at the binary image and calculate the distances as you have done. But you need to look at the angle of each x1,y1, which is atand(y1/x1) and determine if this is in the 0-45, 45-90, 90-135, etc. sector. There will be 8 sectors each 45 degrees wide going from 0 to 360 degrees. So you'd increment the sector it's in inside your loop
theSector = ...... % some number between 1 and 8 that you figure out
% Now add the point to the list of distances you're keeping for this sector.
% First, extract distances for only this particular sector.
thisSectorsDistances = caDistances{theSector};
% Add the new distance.
thisSectorsDistances = [thisSectorsDistances distance];
% Now stick it back in the cell array, into the cell for this particular sector.
caDistances(theSector} = thisSectorsDistances;
Note that because the border varies, each sector can have a different number of boundary points in it. Sector 1 might have 123 coordinates in it, while sector 2 might have 210 points in it and sector 3 might have 176 points in it, etc. That's why we use a cell array.
Now when that loop ends, you have caDistances which is now complete for all points and it has 8 cells in it. So you have to put it in a loop over the 8 cells, extracting thisSectorsDistances from it and getting their standard deviation
for c = 1 : 8
thisSectorsDistances = caDistances {c};
stddev = std(thisSectorsDistances);
% Determine if it's big
if stddev > someAmount
borderValue = 1;
else
borderValue = 0
end
or something like that. I don't know the exact algorithm (I don't have time to read the paper), I know only what you said.
Pamela
Pamela le 22 Oct 2012
Modifié(e) : Pamela le 23 Oct 2012
thank you but I have some difficulties with matlab:
for k = 1:length(Bw)
boundary = Bw{k};
y1=boundary(k,2);
x1=boundary(k,1);
distance = sqrt((x2-x1).^2+(y2-y1).^2);
angle = atand(y1,x1)
if (angle<=45)
thisSectorsDistances = caDistances{1};
thisSectorsDistances = [thisSectorsDistances distance];
elseif (angle<=90)
thisSectorsDistances = caDistances{2};
thisSectorsDistances = [thisSectorsDistances distance];
elseif (angle<=135)
thisSectorsDistances = caDistances{3};
thisSectorsDistances = [thisSectorsDistances distance];
.
.
.
end
end
for c = 1 : 8
thisSectorsDistances = caDistances {c};
stddev = std(thisSectorsDistances);
% Determine if it's big
if stddev > someAmount
borderValue = 1;
else
borderValue = 0
end
Is this correct? In your opinion, how can i set the someAmount value because thre is no indication in the paper?
I will try to find the time if I can. Realize that I have a full time job working 10 - 10.5 hours a day, 5 days a week.
Pamela
Pamela le 25 Oct 2012
thanks

Connectez-vous pour commenter.

Pamela
Pamela le 28 Oct 2012
Hi
img=imread('image');
imshow(img);
I=imagesegmentation(img)
Bw = bwboundaries(I)
border=0;
caDistances = cell(secteur,1);
for k = 1:length(Bw)
boundary = Bw{k};
y1=boundary(k,2);
x1=boundary(k,1);
distance = sqrt((x2-x1).^2+(y2-y1).^2);
angle = atand(y1,x1)
if (angle<=45)
thisSectorsDistances = caDistances{1};
thisSectorsDistances = [thisSectorsDistances distance];
elseif (45<angle<=90)
thisSectorsDistances = caDistances{2};
thisSectorsDistances = [thisSectorsDistances distance];
elseif (90<angle<=135)
thisSectorsDistances = caDistances{3};
thisSectorsDistances = [thisSectorsDistances distance];
.
.
.
elseif (315<angle<=360)
thisSectorsDistances = caDistances{3};
thisSectorsDistances = [thisSectorsDistances distance];
end
end
for c = 1 : 8
thisSectorsDistances = caDistances {c};
stddev = std(thisSectorsDistances);
% Determine if it's big
if stddev > someAmount
borderValue = 1;
else
borderValue = 0
end
Should I transform the polar coordinates to cartesian coordinates? The statements if condition are correct?
I'm sorry for the inconvenience

1 commentaire

No. Anyway, you have both already. You have the x,y and you have the distance from the centroid. What did you set for someAmount? You need to run through it and see what the stddev for normal lesions is, and then set someAmount a little more than that.

Connectez-vous pour commenter.

Pamela
Pamela le 29 Oct 2012
Modifié(e) : Pamela le 29 Oct 2012
Hi,
Before runing, I first want to make sure that the method used is correct, for example: First, secteur is an undefined variable. I don't know how can I initialize it. Second, I don't know if the line used to calculate the angle is correct or not
angle = atand(y1,x1)
Concerning the coordinates, I thought to use this method. Is this correct?
x2=measurements.Centroid(1);
y2=measurements.Centroid(2);
x2=x2/numbrows;
y2=y2/numbcolumns;
and
y1=boundary(:,2);
x1=boundary(:,1);
x1 = x1 - x2;
y1 = y1 - y2;
distance = sqrt((x2-x1).^2+(y2-y1).^2)
[angle,rho] = cart2pol(x1,y1); %find the orientation of every point in the border
angle = ((angle/(pi*2)) * 360);
thanks

7 commentaires

Why don't you check it for a point in each quadrant? For example to make sure that you get 300 instead of -60 for a point in the lower right quadrant for example? If it works for a point in each quadrant, then it works.
Pamela
Pamela le 29 Oct 2012
Modifié(e) : Pamela le 29 Oct 2012
I didn't understand what do you mean
Check these points
  1. For Quadrant 1: 1, 1
  2. For Quadrant 2: -1, 1
  3. For Quadrant 3: -1, -1
  4. For Quadrant 4: 1, -1
See what angle it gives you. For example Quadrant 4 points you're looking for 270-360. If your test point gives you -45 degrees, then you need to add 360 to it to get it into the range 270-360.
JovanS
JovanS le 15 Sep 2022
As you said , secteur is an undefined variable.How could we initialize it?
You can do something like
secteur = 10;
I have no idea how many sectors she used but it's probably an assignment like that. Just assign it to however many sectors you want. There is no "right" answer. It's whatever you want.
JovanS
JovanS le 17 Sep 2022
Modifié(e) : JovanS le 18 Sep 2022
@Image Analyst, on the comments above you said that we have to "compute the angle and which of the 8 sectors it belongs in. For each of the 8 groups of distances you computed, get their standard deviation."
I tried to follow your directions but I am not sure if the line used to calculate the angle is correct or not and if the sectors are divided in the right way. I will attach a part of matlab code if you can help me @Image Analyst
@Ioanna St I can't run that. Please attach the whole m-file with the paper clip icon along with any image needed to run it.

Connectez-vous pour commenter.

Question posée :

le 20 Oct 2012

Modifié(e) :

le 18 Sep 2022

Community Treasure Hunt

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

Start Hunting!

Translated by