drjrm3
drjrm3

Reputation: 4718

Find cost of ellipse in OpenCV

I am using code based off of this example and wonder if there is any way to find out how 'good' the ellipse fit is. I have some ellipses which only very generally fit my data and I want to get rid of them while some of the ellipses are almost perfect.

I'd like to keep on the very good fits and get rid of the poor fits. How can I do this in opencv?

Upvotes: 4

Views: 1885

Answers (1)

Miki
Miki

Reputation: 41765

There are several method you can find in literature, for example:

  • check Dilip K. Prasad, Maylor K.H. Leung and Siu-Yeung Cho, “Edge curvature and convexity based ellipse detection method,” Pattern Recognition, 2012. at Section 4.2

  • check Fornaciari, Michele, Andrea Prati, and Rita Cucchiara. "A fast and effective ellipse detector for embedded vision applications." Pattern Recognition 47.11 (2014): 3693-3708. at Section 3.3.1

However, a very simple method can be the number of pixel that belong both to the contour and the ellipse. You can compute this, for example, drawing the contour and the ellipse on two separate black-initialized images, and counting the number of intersections, i.e. the number of white pixel of the logic AND of the two images.

To be more robust, you can draw both the contour and the ellipse with a line width of 2. This will account for slightly misaligned estimations, but still perceptually correct.

For example, given this input image:

enter image description here

You can see that good ellipses are toward green color, while bad results are toward red color:

enter image description here

Code:

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()
{
    // Load image
    Mat3b img = imread("path_to_image");

    // Convert to grayscale. Binarize if needed
    Mat1b bin;
    cvtColor(img, bin, COLOR_BGR2GRAY);

    // Find contours
    vector<vector<Point>> contours;
    findContours(bin.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);

    // For each contour
    for (int i = 0; i < contours.size(); ++i)
    {
        // Find ellipse
        RotatedRect ell = fitEllipse(contours[i]);

        // Draw contour
        Mat1b maskContour(img.rows, img.cols, uchar(0));
        drawContours(maskContour, contours, i, Scalar(255), 2);

        // Draw ellips
        Mat1b maskEllipse(img.rows, img.cols, uchar(0));
        ellipse(maskEllipse, ell, Scalar(255), 2);

        // Intersect
        Mat1b intersection = maskContour & maskEllipse;

        // Count amount of intersection
        float cnz = countNonZero(intersection);
        // Count number of pixels in the drawn contour
        float n = countNonZero(maskContour);
        // Compute your measure
        float measure = cnz / n;

        // Draw, color coded: good -> gree, bad -> red
        ellipse(img, ell, Scalar(0, measure*255, 255 - measure*255), 3);

    }

    imshow("Result", img);
    waitKey();


    return 0;
}

Upvotes: 5

Related Questions