gpt4 book ai didi

c++ - 如何在 OpenCv 中从太空天空检测太阳?

转载 作者:可可西里 更新时间:2023-11-01 15:54:11 26 4
gpt4 key购买 nike

我需要从太空天空探测太阳。

这些是输入图像的例子:

经过形态学过滤( open 操作两次)我得到了这样的结果

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

// 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);

这么简单的任务处理起来会不会太繁重了?以及如何找到太阳的中心?如果我找到白点,那么我会找到大地球的白点(第一个示例图像的左上角)

请告知我探测太阳的进一步行动。

更新 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);

而地球在照片中的位置,我得到了这样的结果:

所以,质心在地球上。 :(

更新 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 );
}

第一个例子:宾果游戏,但第二个 - 不是 ;(

我尝试了 cvHoughCircles() 的不同配置 - 找不到适合我的每张示例照片的配置。

更新 3:

matchTemplate 方法对我有用(mevatron 的响应)。它适用于大量测试。

最佳答案

试试简单的 matchTemplate 方法怎么样。我使用了这个模板图像:
enter image description here

而且,它检测到了我尝试过的 3 张太阳图像中的 3 张: enter image description here enter image description here enter image description here

这应该是可行的,因为圆(在你的例子中是太阳)是旋转不变的,而且由于你离太阳太远,它也应该大致是尺度不变的。因此,模板匹配在这里可以很好地工作。

最后,这是我用来执行此操作的代码:

#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;
}

希望对您有所帮助!

关于c++ - 如何在 OpenCv 中从太空天空检测太阳?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8218997/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com