0

Say that we have an irregular shape. How can we obtain the best ellipse fit of such shape? Does regionprops work for that? If so, can you kindly guide me on that?

Thanks.

productive
  • 81
  • 3
  • 9

1 Answers1

2

Ok here is a bit of code to get you started. This is by no means perfect but it was fun doing it and I hope it will help you. The most important part of the code was actually written by @Amro in this great answer: check me!. I incorporated Amro's code to plot the ellipse (Thanks Amro!).

As I mentioned in my comment, you can use regionprops with a couple of parameters to estimate an ellipse that fit some shape. The names are self-explanatory and can be used to describe an ellipse. Here is my dummy shape which looks like a potato:

enter image description here

The parameters we will use in regionprops are:

  • 'Centroid'
  • 'MajorAxisLength'
  • 'MinorAxisLength'
  • 'Orientation' and
  • 'PixelList'

Pixel list is used to plot the original shape of the image. Quick and dirty way to see how good is the fit.

So here is the code:

1) Read the image, convert it to black and white (i.e. binary) and apply regionprops:

clear all
clc

A = im2bw(imread('DummyEllipse.jpg'));

s = regionprops(A,'Centroid','MajorAxisLength','MinorAxisLength','Orientation','PixelList')

2) Recover the parameters from the s structure. Note that I access the 2nd element from the structure since the 1st one corresponds to the edges of the plotting area (I don't know how to call it sorry).:

PixList = s(2).PixelList;

x = s(2).Centroid(1);
y = s(2).Centroid(2);
a = s(2).MajorAxisLength/2;
b = s(2).MinorAxisLength/2;
angle = s(2).Orientation;
steps = 50;

3) Provide these parameters to Amro code to compute the ellipse:

%#  @param x     X coordinate
%#  @param y     Y coordinate
%#  @param a     Semimajor axis
%#  @param b     Semiminor axis
%#  @param angle Angle of the ellipse (in degrees)

beta = angle * (pi / 180);
sinbeta = sin(beta);
cosbeta = cos(beta);

alpha = linspace(0, 360, steps)' .* (pi / 180);
sinalpha = sin(alpha);
cosalpha = cos(alpha);

X = x + (a * cosalpha * cosbeta - b * sinalpha * sinbeta);
Y = y + (a * cosalpha * sinbeta + b * sinalpha * cosbeta);

4) Plot the results:

figure

plot(PixList(:,1),rot90(PixList(:,2),2),'-r') % flip the y coordinates because indexing in Matlab starts form the top of the image.
hold on
plot(X,Y,'k','LineWidth',2)

hold off

which gives me this:

enter image description here

So it's not perfect but hopefully it will help you get started.

Community
  • 1
  • 1
Benoit_11
  • 13,905
  • 2
  • 24
  • 35
  • Thanks a lot for your detailed answer. I just got an error with this line: `PixList = s(2).PixelList;`, mentioning that: `Index exceeds matrix dimensions.`. Why is that? Thanks – productive Oct 03 '14 at 16:22
  • Oh in that case you want to use s(1).PixelList and s(1).Centroid (etc.) instead of s(2) as I wrote above. In my case regionprops outputs 2 "regions", including the actual boundaries of the figure in position 1, so I use 2 as an index. If you get that error the figure boundaries are probably not considered and this the size of the structure s is 1 instead of 2 as in my case. I'll check into that to see how come it's like that, but that should solve your problem. – Benoit_11 Oct 03 '14 at 17:52
  • Thanks @Benoit_11 for your kind support. The issue I'm having now is that I get a blank screen for "figure". Also, I want to mention that, I want such ellipse to show on the same image, and not as a separate plot. – productive Oct 06 '14 at 11:22