Take the 2-minute tour ×

I need to detect the Sun from the space sky.

These are examples of the input images:

I've got such results after Morphologic filtering ( open operation for twice )

Here's the algorithm code of this processing:

// Color to Gray
cvCvtColor(image, gray, CV_RGB2GRAY);

// color threshold

// Morphologic open for 2 times
cvMorphologyEx( gray, dst, NULL, CV_SHAPE_RECT, CV_MOP_OPEN, 2);

Isn't it too heavy processing for such a simple task? And how to find the center of the Sun? If I find white points, than I'll find white points of big Earth ( left top corner on first example image )

Please advise me please my further action to detect the Sun.


Trying algorithm of getting centroid by formula : {x,y} = {M10/M00, M01/M00}

CvMoments moments;
cvMoments(dst, &moments, 1);
double m00, m10, m01;

m00 = cvGetSpatialMoment(&moments, 0,0);
m10 = cvGetSpatialMoment(&moments, 1,0);
m01 = cvGetSpatialMoment(&moments, 0,1);

// calculating centroid
float centroid_x = m10/m00;
float centroid_y = m01/m00;

    cvCircle( image, 
              cvPoint(cvRound(centroid_x), cvRound(centroid_y)), 
              50, CV_RGB(125,125,0), 4, 8,0);

And where Earth is in the photo, I got such a result:

So, centroid is on the Earth. :(


Trying cvHoughCircles:

CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* circles = cvHoughCircles(dst, storage, CV_HOUGH_GRADIENT, 12, 
                                dst->width/2, 255, 100, 0, 35);

if ( circles->total > 0 ) {
    // getting first found circle
    float* circle = (float*)cvGetSeqElem( circles, 0 ); 

    // Drawing:
    // green center dot
    cvCircle( image, cvPoint(cvRound(circle[0]),cvRound(circle[1])), 
          3, CV_RGB(0,255,0), -1, 8, 0 ); 
    // wrapping red circle
        cvRound(circle[2]), CV_RGB(255,0,0), 3, 8, 0 ); 

First example: bingo, but the second - no ;(

I've tried different configuration of cvHoughCircles() - couldn't find configuration to fit every my example photo.


matchTemplate approach worked for me ( response of mevatron ). It worked with big number of tests.

share|improve this question

3 Answers 3

up vote 6 down vote accepted

How about trying a simple matchTemplate approach. I used this template image:
enter image description here

And, it detected the 3 out of 3 of the sun images I tried: enter image description here enter image description here enter image description here

This should work due to the fact that circles (in your case the sun) are rotationally invariant, and since you are so far away from the sun it should be roughly scale invariant as well. So, template matching will work quite nicely here.

Finally, here is the code that I used to do this:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
    /// Load image and template
    string inputName = "sun2.png";
    string outputName = "sun2_detect.png";
    Mat img   = imread( inputName, 1 );
    Mat templ = imread( "sun_templ.png", 1 );

    /// Create the result matrix
    int result_cols =  img.cols - templ.cols + 1;
    int result_rows = img.rows - templ.rows + 1;

    Mat result( result_cols, result_rows, CV_32FC1 );

    /// Do the Matching and Normalize
    matchTemplate(img, templ, result, CV_TM_CCOEFF);

    Point maxLoc;
    minMaxLoc(result, NULL, NULL, NULL, &maxLoc);

    rectangle(img, maxLoc, Point( maxLoc.x + templ.cols , maxLoc.y + templ.rows ), Scalar(0, 255, 0), 2);

    imshow("img", img);
    imshow("result", result);

    imwrite(outputName, img);


    return 0;

Hope you find that helpful!

share|improve this answer
Actually, the reasons this is working are different from the mentioned ones. For a starter, there is nothing resembling the used template anywhere else in these images. Also, this is much more likely to be several times slower than the initial morphological approach. –  mmgp Dec 17 '12 at 23:43
Good points indeed :) However, since I was assuming the space ship is in our solar system, I believe it's safe to say only one Sun will show up :D –  mevatron Jan 24 '13 at 15:40
I guess this would fail if any part of the HUD (the pilot user interface) gets on top of the sun. Unless the template matching gives a score on how good the match is, that way you could threshold the top results and it would probably work with some obstructions. –  Rui Marques Feb 25 at 16:36

Color Segmentation Approach

Do a color segmentation on the images to identify objects on the black background. You may identify the sun according to its area (given this uniquely identifies it, resp. don't varies largely accross images). A more sophisticated approach could compute image moments, e.g. hu moments of the objects. See this page for these features.

Use a classification algorithm of your choice to do the actual classification of the objects found. The most simple approach is to manually specify thresholds, resp. value ranges that turn out to work for all(most) of your object/image combinations.

You may compute the actual position from the raw moments, as for the circular sun the position is equal to the center of mass

Centroid: {x, y } = { M10/M00, M01/M00 }

Edge Map Approach

Another option would be a circle hough transformation of the edge map, this will hopefully return some candidate circles (by position and radius). You may select the sun-circle according to the radius you expect (if you are lucky there is at most one).

share|improve this answer
I think with image moments it won't work. If there will be only the sun on the screen - than, the center of the Sun is Centroid point. But if Earth takes some screen's part (like in image #1 top left), than this part is "heavier" than Sun and Centroid will be shifted. I've tried with CircleHough, and it doesn't work for all my example photos... –  Innuendo Nov 22 '11 at 0:31
I've updated my questions - examples were added –  Innuendo Nov 22 '11 at 1:14

A simple addition to your code is to filter out objects based on their size. If you always expect the earth to be much bigger than the sun, or the sun to have almost the same area in each picture, you can filter it by area.

Try Blob detector for this task.

And note that it may be good to apply a morphological opening/closing instead of simple erode or dilate, so your sun will have almost the same area before and after processing.

share|improve this answer
thanx, i think it would be usefull for me, but my openCv build doesn't have blob detector, and I'm novice in C++ (i won't be able to compile the newest version) –  Innuendo Nov 22 '11 at 20:40
Take the latest OpenCV from sourceforge sourceforge.net/projects/opencvlibrary And to use it is as simple as the increment operator :) It's already compiled. And.. did you add using namespace cv? How don't you have the blob detector? –  sammy Nov 23 '11 at 6:50

Your Answer


