title: OpenCV's fitEllipse() sometimes returns completely wrong ellipses
body: <p>My goal is to recognize all the shapes present in an image.
  The idea is:</p>
  
  <ol>
  <li>Extract contours</li>
  <li>Fit each contour with different shapes</li>
  <li>The correct shape should be the one with area closest to the
  contour's area.</li>
  </ol>
  
  <p>Example image:
  <img src="https://i.stack.imgur.com/w82xC.png" alt="enter image description here"></p>
  
  <p>I use <code>fitEllipse()</code> to find the best fit ellipse to the contours, but the result is a bit messy:
  <img src="https://i.stack.imgur.com/Gjnoh.png" alt="enter image description here"></p>
  
  <p>The likely-correct ellipses are filled with blue, and the bounding ellipses are yellow.
  The likely-incorrect contours are filled with green, and the (wrong) bounding ellipses are cyan.</p>
  
  <p>As you can see, the ellipse bounding the triangle in the first row looks pretty good for the best fit. The bounding ellipse of the triangle in the third row doesn't seem to be the best fit, but still acceptable as a criteria for rejecting an incorrect ellipse.</p>
  
  <p>But I can't understand why the remaining triangles have bounding ellipse completely outside their contour.
  And the worst case is the third triangle in the last row: The ellipse is completely wrong but it happens to have the area close to the contour's area, so the triangle is wrongly recognized as an ellipse.</p>
  
  <p>Do I miss anything? My code:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;opencv/cv.h&gt;
  #include &lt;opencv/highgui.h&gt;
  
  using namespace std;
  using namespace cv;
  
  void getEllipses(vector&lt;vector&lt;Point&gt; &gt;&amp; contours, vector&lt;RotatedRect&gt;&amp; ellipses) {
      ellipses.clear();
      Mat img(Size(800,500), CV_8UC3);
      for (unsigned i = 0; i&lt;contours.size(); i++) {
          if (contours[i].size() &gt;= 5) {
              RotatedRect temp = fitEllipse(Mat(contours[i]));
              if (area(temp) &lt;= 1.1 * contourArea(contours[i])) {
                  //cout &lt;&lt; area(temp) &lt;&lt; " &lt; 1.1* " &lt;&lt; contourArea(contours[i]) &lt;&lt; endl;
                  ellipses.push_back(temp);
                  drawContours(img, contours, i, Scalar(255,0,0), -1, 8);
                  ellipse(img, temp, Scalar(0,255,255), 2, 8);
                  imshow("Ellipses", img);
                  waitKey();
              } else {
                  //cout &lt;&lt; "Reject ellipse " &lt;&lt; i &lt;&lt; endl;
                  drawContours(img, contours, i, Scalar(0,255,0), -1, 8);
                  ellipse(img, temp, Scalar(255,255,0), 2, 8);
                  imshow("Ellipses", img);
                  waitKey();
              }
          }
      }
  }
  
  int main() {
      Mat img = imread("image.png", CV_8UC1);
      threshold(img, img, 127,255,CV_THRESH_BINARY);
      vector&lt;vector&lt;Point&gt; &gt; contours;
      vector&lt;Vec4i&gt; hierarchy;
      findContours(img, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
      vector&lt;RotatedRect&gt; ellipses;
      getEllipses(contours, ellipses);
      return 0;
  }
  </code></pre>