Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect partial circles in an image using python and opencv [closed]

Tags:

python

opencv

I took about 220 images of the partial solar eclipse today and plan to put together a timelapse animation of the event. As expected the image of the partially eclipsed Sun jumps around a bit and I need to register the shots before making the animation.

Here are sample photos:

http://www.trivalleystargazers.org/gert/sofi_141023/sofi.htm

I would like to center the images on the Sun which is obviously a segment of a circle during the eclipse. I guess the Moon would be a distraction for the algorithm (I don't want to center on the Moon). I have some knowledge on Python and none on opencv.

Is there an easy way to find the Sun in the images and center it to approx. 1pixel accuracy? Is opencv + python the proper approach at all? Are there particular tricks to work out to get to the best result?

Thanks & Clear Skies, Gert

like image 580
Gert Gottschalk Avatar asked Jun 30 '26 01:06

Gert Gottschalk


1 Answers

You can try this:

  • threshold the image
  • get the largest contour
  • find the minimum area circle that encloses this contour

Once you find the center and radius, it'll be easier to register. If the radii are different between snapshots, you'll have to resize all circles to a predefined size and adjust the center accordingly in the registration phase.

I tried this in OpenCV and C++.

    Mat im = imread(INPUT_FOLDER_PATH + string("SoFi_400_20141023_163450.jpg"));

    Mat gray;
    cvtColor(im, gray, CV_BGR2GRAY);

    Mat bw;
    threshold(gray, bw, 0, 255, CV_THRESH_BINARY|CV_THRESH_OTSU);

    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(bw, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
    /* in actual implementation you'll have to find the largest contour. 
    here i'm just assuming i get one and it's the largest*/
    for(int idx = 0; idx >= 0; idx = hierarchy[idx][0])
    {
        Point2f center;
        float radius;
        minEnclosingCircle(contours[idx], center, radius);
        cout << idx << " (" << center.x << ", " << center.y << ") : " << radius << endl;

        circle(im, Point(center.x, center.y), radius, Scalar(0, 255, 255), 2);
    }

    imshow("", im);
    waitKey();

Some results:

enter image description here enter image description here

like image 98
dhanushka Avatar answered Jul 05 '26 18:07

dhanushka



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!