2012-05-14 32 views
5

He hecho previamente una pregunta Marking an interest point in an image using c++. Usé la misma solución y obtuve el punto requerido usando el umbral adaptativo y Blob Detection Algorithm (Regiones en crecimiento). Tengo la cifra fuente original donde quiero para detectar la región rectangular en el centroDetección de área brillante rectangular en una imagen usando OpenCv

imagen original:

Original Image .Pero después de utilizar el algoritmo, tengo algo como esto (los detalles son visibles si la abres en una nueva pestaña)

imagen marcados:

enter image description here donde además de la región rectangular de los puntos de luz brillante día iluminados son también visibles. He utilizado el filtrado bilateral, pero todavía no puedo detectar la región rectangular. Pero este algoritmo funciona para la imagen nocturna, donde el fondo es más oscuro como se esperaba.

Puede alguien sugerir si el mismo algoritmo con algunas modificaciones es suficiente o cualquier otros medios eficientes están disponibles ..

Gracias

Respuesta

4

Usando una combinación simple de desenfoque & umbral me las arreglé para conseguir este resultado (redimensionado para fines de visualización):

Después de eso, la aplicación de erosión & the squares.cpp technique (que es una muestra de OpenCV) salidas:

que es casi el resultado que está buscando: la parte inferior del rectángulo se detectó con éxito. Todo lo que necesita hacer es aumentar la altura del rectángulo detectado (cuadrado rojo) para adaptarse a su área de interés.

Código:

Mat img = imread(argv[1]); 

    // Blur 
Mat new_img = img.clone(); 
medianBlur(new_img, new_img, 5); 

// Perform threshold 
double thres = 210; 
double color = 255; 
threshold(new_img, new_img, thres, color, CV_THRESH_BINARY); 
imwrite("thres.png", new_img); 

// Execute erosion to improve the detection 
int erosion_size = 4; 
Mat element = getStructuringElement(MORPH_CROSS, 
            Size(2 * erosion_size + 1, 2 * erosion_size + 1), 
            Point(erosion_size, erosion_size)); 
erode(new_img, new_img, element); 
imwrite("erode.png", new_img); 

vector<vector<Point> > squares; 
find_squares(new_img, squares); 
std::cout << "squares: " << squares.size() << std::endl; 

draw_squares(img, squares); 

imwrite("area.png", img); 

EDITAR:

La función find_squares() devuelve un vector con todas las plazas que se encuentran en la imagen.Debido a que itera en cada canal de la imagen, en su ejemplo detecta con éxito la región rectangular en cada uno de ellos, por lo que imprime squares.size() salidas 3.

como un cuadradopuede ser visto como un vector de 4 (X, Y) coordina, OpenCV expresar este concepto como vector<Point> lo que le permite acceder a la parte X e Y las coordenadas.

Ahora, la impresión squares, reveló que el se detectaron los puntos en sentido antihorario:

1st ------ 4th 
|   | 
|   | 
|   | 
2nd ------ 3rd 

Siguiendo este ejemplo, está bastante obvio que si es necesario aumentar la altura del rectángulo es necesario cambiar la Y del 1 al 4 puntos:

for (int i = 0; i < squares.size(); i++) 
{ 
    for (int j = 0; j < squares[i].size(); j++) 
    { 
    // std::cout << "# " << i << " " << squares[i][j].x << ","<< squares[i][j].y << std::endl; 
     if (j == 0 || j == 3) 
      squares[i][j].y = 0; 
    } 
} 

+0

@Karlphilip wow..Thats Great..Thanks mucho por su hel p. Estoy obteniendo el resultado deseado para las imágenes más oscuras también, pero con un límite codificado digamos (alrededor de 80) .Si se va de la región. No puedo encontrar los cuadrados. Así que utilicé el valor umbral de Otsu, pero tengo que agregar 30 para la detección satisfactoria. Cualquier otra forma de detectar tanto las imágenes más oscuras como las más brillantes – ShivShambo

+0

Ese es el único en el que puedo pensar. – karlphillip

+0

@ Karlphilip..Utilizando este algoritmo, quiero encontrar las coordenadas del centro del área rectangular en la figura original. cualquier idea a la que pueda acercarme – ShivShambo

1

En la imagen aparecen arriba, sugeriría

  1. ya sea una operación de umbralización normal que debería funcionar bastante bien o

  2. a line-wise código de cadena "calculati en "o

  3. encontrando gradientes en su histograma.

Habría muchas otras soluciones. Consideraría restar el sombreado de fondo si esto es consistente.

Cuestiones relacionadas