如何从OpenCv中的太空中检测太阳? [英] How to detect the Sun from the space sky in OpenCv?

查看:643
本文介绍了如何从OpenCv中的太空中检测太阳?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从太空中检测太阳。

I need to detect the Sun from the space sky.

这些是输入图像的示例:

These are examples of the input images:


我在Morphologic过滤( open 两次)

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


< img src =http://i.stack.imgur.com/35cFH.pngwidth =300>

这里是这个处理的算法代码: / p>

Here's the algorithm code of this processing:

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

// color threshold
cvThreshold(gray,gray,150,255,CV_THRESH_BINARY);

// 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.

更新1:

尝试获取 centroid {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. :(

更新2:

尝试 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
    cvCircle( image, cvPoint(cvRound(circle[0]),cvRound(circle[1])), 
        cvRound(circle[2]), CV_RGB(255,0,0), 3, 8, 0 ); 
}


第一个例子:bingo,但第二个 - 不是(

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

不同配置 cvHoughCircles() - 找不到适合我所有示例照片的配置。

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

UPDATE3:

matchTemplate 方法适用于我( mevatron )。

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

推荐答案

如何尝试一个简单的 matchTemplate 方法。我使用了此模板图片:

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

并且,它检测到我尝试的3个太阳图像中的3个:

And, it detected the 3 out of 3 of the sun images I tried:

这应该适用,因为圆圈太阳)是旋转不变的,并且由于你离太阳太远,它应该是大致不变的。

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);
    normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());

    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);
    rectangle(result, maxLoc, Point( maxLoc.x + templ.cols , maxLoc.y + templ.rows ), Scalar(0, 255, 0), 2);

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

    imwrite(outputName, img);

    waitKey(0);

    return 0;
}

希望您觉得有用!

这篇关于如何从OpenCv中的太空中检测太阳?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆