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;
}
}
@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
Ese es el único en el que puedo pensar. – karlphillip
@ 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