2012-06-19 18 views
8

Sto sviluppando un progetto usando java per identificare i componenti usando il pacchetto opencv ma sono nuovo di javacv e voglio solo sapere come identificare i rettangoli in una particolare immagine sorgente per favore qualche persona esperta può dare qualche linea guida di base per archiviare questo compito. Cerco di utilizzare la corrispondenza dei modelli qui, ma è in grado di identificare solo il rettangolo delle dimensioni esatte. Ma nel mio caso ho bisogno di identificare un rettangolo di lunghezza variabile?Come identificare il quadrato o il rettangolo con lunghezze e larghezze variabili usando javacv?

import java.util.Arrays; 
import static com.googlecode.javacv.cpp.opencv_core.*; 
import static com.googlecode.javacv.cpp.opencv_imgproc.*; 
import static com.googlecode.javacv.cpp.opencv_highgui.*; 
public class TestingTemplate { 
public static void main(String[] args) { 
//Original Image 
IplImage src = cvLoadImage("src\\lena.jpg",0); 
//Template Image 
IplImage tmp = cvLoadImage("src\\those_eyes.jpg",0); 
//The Correlation Image Result 
IplImage result = cvCreateImage(cvSize(src.width()-tmp.width()+1, src.height()-tmp.height()+1), IPL_DEPTH_32F, 1); 
//Init our new Image 
cvZero(result); 
cvMatchTemplate(src, tmp, result, CV_TM_CCORR_NORMED); 

double[] min_val = new double[2]; 
double[] max_val = new double[2]; 

//Where are located our max and min correlation points 
CvPoint minLoc = new CvPoint(); 
CvPoint maxLoc = new CvPoint(); 
cvMinMaxLoc(result, min_val, max_val, minLoc, maxLoc, null); //the las null it's for 
optional mask mat() 

System.out.println(Arrays.toString(min_val)); //Min Score 
System.out.println(Arrays.toString(max_val)); //Max Score 

CvPoint point = new CvPoint(); 
point.x(maxLoc.x()+tmp.width()); 
point.y(maxLoc.y()+tmp.height()); 
cvRectangle(src, maxLoc, point, CvScalar.WHITE, 2, 8, 0); //Draw the rectangule result in original img. 
cvShowImage("Lena Image", src); 
cvWaitKey(0); 
//Release 
cvReleaseImage(src); 
cvReleaseImage(tmp); 
cvReleaseImage(result); 
} 
} 

Si prega di qualcuno può aiuto per raggiungere questo

+2

Squares? Gli scudieri sono più difficili. –

+0

Dave: Si prega di fornire qualche riga di gilda per archiviare questo> –

+2

È scudiero o SQUARE? se no, che cosa è lo scudiero? google dice che è armatura di soldati. E 'questo quello che vuoi? Meglio aggiungere un'immagine. –

risposta

9

(Così è fissato come piazza.)

Per il rilevamento quadrato, OpenCV viene fornito con alcuni campioni per questo. I codici sono in C++, C, Python. Spero che tu possa portarlo a JavaCV.

C++ code, Python Code.

Mi limito a illustrare come funziona:

1 - In primo luogo è dividere l'immagine a piani R, G, B.

2 - Quindi, per ogni piano di eseguire il rilevamento dei bordi , e in aggiunta a ciò, soglia per diversi valori come 50, 100, ecc ....

3 - e in tutti questi binario immagini, trova contorni (ricorda che sta elaborando molte immagini, quindi potrebbe essere un po 'lento, se non vuoi, puoi rimuovere alcuni valori di soglia).

4 - Dopo aver individuato i contorni, rimuovere alcuni piccoli rumori indesiderati tramite il filtro in base all'area.

5 - Quindi, approssimare il profilo. (More about contour approximation).

6 - Per un rettangolo, ti darà i quattro angoli. Per gli altri, verranno assegnati angoli corrispondenti.

Quindi filtrare questi contorni rispetto al numero di elementi in un contorno approssimato che dovrebbe essere quattro, che è uguale al numero di angoli. Prima proprietà del rettangolo.

7 - Successivamente, potrebbero esserci delle forme con quattro angoli ma non rettangoli. Quindi prendiamo la proprietà di rettangoli, cioè tutti gli angoli interni sono 90. Così troviamo l'angolo in tutti gli angoli utilizzando la relazione di seguito:

enter image description here

E se cos (theta) < 0.1, vale a dire theta> 84 gradi, che è un rettangolo.

8 - Allora che dire della piazza? Usa la sua proprietà, che tutti i lati sono uguali.

È possibile trovare la distanza tra due punti dalla relazione come mostrato sopra. Controlla se sono tutti uguali, quindi quel rettangolo è un quadrato.

Ecco come funziona il codice.

Di seguito è l'output ottenuto applicando sopra codice di cui su un'immagine:

enter image description here

EDIT:

E 'stato chiesto come rimuovere il rettangolo rilevato alla frontiera. È perché, opencv trova oggetti bianchi su sfondo nero, così è il bordo. Basta capovolgere l'immagine usando la funzione cv2.bitwise_not() per risolvere il problema. otteniamo il risultato come di seguito:

enter image description here

è possibile trovare ulteriori informazioni su contorno qui: Contours - 1 : Getting Started

+0

Puoi spiegare come posso ottenere rettangoli con larghezza inferiore a quella specifica? in realtà ho bisogno di rimuovere quei rettangoli di grandi dimensioni che mostra in immagine (bordi). –

+0

Questo bordo rettangolo grande viene rilevato perché, i contorni opencv trovano oggetti bianchi su sfondo nero. Quindi fai dei quadrati bianchi, cioè inverti semplicemente l'immagine. Ho aggiornato la risposta. –

+0

Quindi non posso ottenere separatamente ogni singolo rettangolo? Se è in grado di farlo, puoi fornire un esempio di codice per questo. –

Problemi correlati