Utilizzando una semplice combinazione di sfocatura & soglia sono riuscito ad ottenere questo risultato (ridimensionata per scopi di visualizzazione):
Dopo di che, l'applicazione di erosione & the squares.cpp technique (che è un esempio di OpenCV):
che è quasi il risultato che si sta cercando: la parte inferiore del rettangolo è stata rilevata correttamente. Tutto ciò che devi fare è aumentare l'altezza del rettangolo rilevato (riquadro rosso) per adattarlo alla tua area di interesse.
Codice:
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);
EDIT:
La funzione find_squares()
restituisce un vettore con tutte le piazze trovate nell'immagine.Poiché itera su ogni canale dell'immagine, sul tuo esempio rileva con successo la regione rettangolare in ciascuna di esse, quindi stampa le uscite squares.size()
3
.
Come quadrato può essere vista come un vettore di 4 (X, Y) coordinate, OpenCV esprimere questo concetto come vector<Point>
permette di accedere X e Y parte la coordinata.
Ora, la stampa squares
revelead che i punti sono stati rilevati in senso antiorario:
1st ------ 4th
| |
| |
| |
2nd ------ 3rd
Seguendo questo esempio, la sua abbastanza ovvio che se è necessario aumentare l'altezza del rettangolo è necessario modificare la Y del 1 ° e 4 ° punti:
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 molto per il vostro hel p.Io sto ottenendo il risultato desiderato per le immagini più scure anche se dico con soglia hardcoded (circa 80). Se si allontana dalla regione. Non riesco a trovare i quadrati. Quindi ho usato il valore di soglia di Otsu, ma devo aggiungere 30 per il rilevamento soddisfacente. Qualsiasi altro modo per rilevare entrambe le immagini più scure e luminose – ShivShambo
Questo è l'unico che riesco a pensare. – karlphillip
@ Karlphilip..Usando questo algoritmo voglio solo trovare le coordinate del centro dell'area rettangolare nella figura originale. tutte le idee a cui posso avvicinarmi. – ShivShambo