I've tried the solutions given in How to find circular objects in an image? to detect the ellipse, but the detection result was not quite what I wanted. The reason might be that ChanVeseBinarize function can't separate the rim from the body. Therefore SelectComponents will view the whole cup as one component and consequently detect nothing.

Then I tried to use edge detection. After manipulating the parameters, I can detect the edge of the rim like this:

But I can't find an algorithm that detect the line of an ellipse. How might I do that?

What I can think of right now: try to isolate the ellipse e.g. through Image[ ImageData@EdgeDetect[pic] - ImageData@EdgeDetect[pic, "StraightEdges" -> 0.2]] and then apply MorphologicalComponents and then on each component (one will be the ellipse, you may be able to delete the other somehow) use ComponentMeasurements. Look in the documentation for the properties that it can give you, that you may want, e.g. best fit ellipse semiaxes and so on.
–
PickettMay 21 '13 at 13:34

@RodLm It would be easier If he did that himself when editting his question. Now it's been 5 times editted. Wouldn't like to make it a community-wiki question.
–
ArtesMay 21 '13 at 13:46

Well you will need to use a fuzzy ellipse. The basic idea is to generate a number of ellipses until one of them is such that most of its points are within a certain distance of a white point of your edge detection output. Now the question is reduced to how to effectively generate ellipses.
–
SMeznaricMay 21 '13 at 14:05

1

Substantial progress towards a solution can be found by reviewing these related posts. A Hough transform looks attractive.
–
whuberMay 21 '13 at 15:03

3

I'm not sure about the hough transform: an ellipse has 5 degrees of freedom, that's a huge parameter space to update for each point.
–
nikieMay 21 '13 at 17:01

isValidEllipse is a simple ad-hoc criterion to filter out completely deformed conics.

Normally, we'd need 5 points to fit a conic. The image contains about 50% outliers, so the chance to randomly select 5 points on the ellipse we're looking for is about $0.5^5$, which is not good. We'd need a lot of samples to be reasonably sure that at least one 5-tuple of points contains only non-outlier points.

But fortunately, the location of the edge is not the only information we have: We also know the local orientation at each pixel, which should be perpendicular to the conic's normal vector.

orientation = GradientOrientationFilter[img, 3];

Now 3 points and their orientations give us 6 equations, so we have an overdetermined equation system:

This function returns not only the best-fit conic's coefficients, but also the residual error, which is a cheap way to compare between different fitted conics. The assumption is: If randomly sampled 3 points are all parts of the ellipse, the residual error will be low. If the points don't belong to one conic, the residual error will be much higher.

(There is room for improvement here: the ellipse you're looking for might not be contained in these 100 samples, or it might not be the one with the lowest residual error. A smarter algorithm would take e.g. 50 samples, take the best one or two of these and count the number of nearby points. If enough points are close to it, keep that ellipse, otherwise, take 50 new samples. But that's just a straightforward programming exercise left to the reader ;-) .)

Next step: Find points nearest to the conic. I've tried to calculate the geometric distance exactly (using FindMinimumValue) but that's very slow. A simple, fast approximation is to find N points on the ellipse and simply use Nearest to estimate the distance:

Repeat the last steps until convergence. (Possible improvements: You could try to reduce the distance threshold in each iteration. Or you could add a "weight" to the curve fitting and give points closer to the current estimate a higher weight when calculating the next estimate.)

It's close, but not close enough. And now I can see where I went wrong - I've assumed the cup is aligned with the camera and geometrically accurate, but I don't think it is. (And what exactly is the rim anyway?) I wonder whether this method would work if the cup was aligned.

The best ellipsoidal fit for the rim has the given length, width, semiaxes, orientation, elongation, and eccentricity. The other is the best ellipsoidal fit for the cup sides (which is not a good fit at all).

Mathematica is a registered trademark of Wolfram Research, Inc. While the mark is used herein with the limited permission of Wolfram Research, Stack Exchange and this site disclaim all affiliation therewith.