2011-11-21 10 views
7

Necesito detectar el Sol desde el cielo del espacio.¿Cómo detectar el Sol desde el cielo del espacio en OpenCv?

Estos son ejemplos de las imágenes de entrada:

Tengo estos resultados después de filtrado morfológico (open operación de dos veces)

Aquí está el código del algoritmo de este procesamiento:

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

¿No es un proceso demasiado pesado para una tarea tan simple? ¿Y cómo encontrar el centro del sol? Si encuentro puntos blancos, entonces encontraré puntos blancos de la Tierra grande (esquina superior izquierda en la primera imagen de ejemplo)

Por favor avísenme, por favor, mis medidas adicionales para detectar el sol.

ACTUALIZACIÓN 1:

Tratando algoritmo de conseguir centroid por la fórmula: {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); 

Y donde está la Tierra en la foto, me dieron este resultado:

Así , centroide está en la Tierra. :(

ACTUALIZACIÓN 2:

Tratando 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); 
} 

Primer ejemplo: bingo, pero el segundo - no; (

I' he probado una configuración diferente de cvHoughCircles(): no pude encontrar la configuración para que se ajuste a todas mis fotos de ejemplo.

Update3:

matchTemplate enfoque funcionó para mí (respuesta de mevatron). Funcionó con una gran cantidad de pruebas.

Respuesta

8

¿Qué le parece intentar un enfoque simple de matchTemplate? He utilizado esta imagen Modelo:
enter image description here

Y, se detectó el 3 de cada 3 de las imágenes del sol que probé: enter image description hereenter image description hereenter image description here

Esto debería funcionar debido al hecho de que los círculos (en su caso del sol) son invariantes de forma rotativa, y dado que estás tan lejos del sol, también deberían ser invariables a escala general. Entonces, la coincidencia de plantillas funcionará muy bien aquí.

Por último, aquí está el código que he utilizado para hacer esto:

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

Esperamos que encuentre que ayuda!

+2

En realidad, las razones por las que esto funciona son diferentes a las mencionadas. Para empezar, no hay nada parecido a la plantilla utilizada en ningún otro lugar en estas imágenes. Además, es mucho más probable que sea varias veces más lento que el enfoque morfológico inicial. – mmgp

+1

De hecho, son buenos puntos :) Sin embargo, dado que estaba asumiendo que la nave espacial está en nuestro sistema solar, creo que es seguro decir que solo aparecerá un Sol: D – mevatron

+0

Supongo que esto fallaría si alguna parte del HUD (el piloto interfaz de usuario) se pone encima del sol. A menos que la coincidencia de la plantilla arroje un puntaje sobre cuán buena es la coincidencia, de esa manera podría establecer el umbral de los mejores resultados y probablemente funcionaría con algunas obstrucciones. –

2

Enfoque color Segmentación

Haz una segmentación de color en las imágenes para identificar objetos en el fondo negro. Puede identificar el sol de acuerdo con su área (dado que esto lo identifica de manera única, o no varía en gran medida a través de las imágenes). Un enfoque más sofisticado podría calcular momentos de imagen, p. hu momentos de los objetos. Vea this page para estas características.

Utilice un algoritmo de clasificación de su elección para hacer la clasificación real de los objetos encontrados. El enfoque más simple es especificar manualmente los umbrales, resp. rangos de valores que funcionan para todas (la mayoría) de las combinaciones de objeto/imagen.

Es posible calcular la posición real de los momentos primas, como for the circular sun the position is equal to the center of mass

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

Enfoque Edge Mapa

Otra opción sería una transformación círculo Hough del mapa de borde, este será de esperar el retorno algunos círculos candidatos (por posición y radio). Puede seleccionar el círculo solar de acuerdo con el radio que espera (si tiene suerte, hay como máximo uno).

+0

Creo que con momentos de imagen no funcionará. Si solo habrá sol en la pantalla, entonces, el centro del Sol es el punto "Centroide". Pero si la Tierra toma parte de la pantalla (como en la imagen n. ° 1, arriba a la izquierda), entonces esta parte es "más pesada" que el Sol y el Centroide se desplazará. Lo he intentado con CircleHough, y no funciona con todas mis fotos de ejemplo ... –

+0

He actualizado mis preguntas - se agregaron ejemplos –

2

Una simple adición a su código es filtrar los objetos en función de su tamaño. Si siempre espera que la Tierra sea mucho más grande que el Sol, o que el Sol tenga casi la misma área en cada imagen, puede filtrarla por área.

Pruebe Blob detector para esta tarea.

Y tenga en cuenta que puede ser útil aplicar una apertura/cierre morfológico en lugar de simplemente erosionar o dilatar, por lo que su sol tendrá casi la misma área antes y después del procesamiento.

+0

gracias, creo que sería útil para mí, pero mi versión de OpenCv no tiene detector de manchas, y soy novato en C++ (no seré capaz de compilar el versión más reciente) –

+0

Tome el último OpenCV de sourceforge http://sourceforge.net/projects/opencvlibrary/ Y usarlo es tan simple como el operador de incremento :) Ya está compilado. Y ... ¿añadiste usando namespace cv? ¿Cómo no tienes el detector de manchas? – Sam

Cuestiones relacionadas