2011-06-12 49 views
15

Sto scrivendo una piccola applicazione per il rilevamento di forme. Quello che devo fare in primo luogo è trovare la forma più significativa su un'immagine. Ho iniziato da una pre-elaborazione inclusa la conversione dell'immagine in scala di grigi, il rilevamento delle soglie e dei bordi. Immagine prima e dopo queste operazioni si presenta sottorilevamento forme - approssimazione del contorno con OpenCV

Prima

enter image description here

Dopo

enter image description here

Così come si può vedere la forma principale è visibile (ma è un po 'sparso) e ci sono anche alcuni rumori (piccoli alberi ecc.). Quello che devo fare è estrarre in qualche modo solo la forma più significativa (la più grande) - in questo caso è una torre. Quello che volevo fare è usare la funzione di ricerca dei contorni in opencv e poi in qualche modo approssimati contur trovati con poligono. Quindi vorrei (in qualche modo) calcolare l'area di countours e selezionare solo la più grande. Finora ho consumassimo (solo) per trovare i contorni utilizzando

cvFindContours(crated,g_storage,&contours); 

So che c'è una funzione

cvApproxPoly 

, ma io non sono in grado di ottenere tutte le informazioni utili per il risultato di questa funzione . Qualcuno potrebbe dirmi se è possibile calcolare l'area del contorno o approssimare il contur con il poligono. Forse hai un'idea migliore di come estrarre solo la forma più significativa?

risposta

5

Il tuo problema principale è che il contorno della torre è sparpagliato. Sarà difficile ricreare l'intero contorno da quei piccoli pezzi. Ottimizzare la fase di rilevamento dei bordi (provate cvAdaptiveThreshold), o utilizzare approccio diverso (forse qualcosa come object segmentation)

Dopo che avete il vostro profilo in un unico pezzo, è possibile controllare il suo settore come questo:

CvSeq* convex_hull=cvConvexHull2(contour, storage, CV_CLOCKWISE, 2); 
CvSeq* quad=cvApproxPoly(convex_hull, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.02, 0); 
float size=fabs(cvContourArea(quad,CV_WHOLE_SEQ,0)); 

Avrete necessità di sintonizzare i parametri. È stato usato per rilevare i rettangoli.

8

Non è necessario eseguire il rilevamento dei bordi qui. Solo soglia a un'immagine binaria e quindi trovare blob (cvFindContours) su quello. Puoi usare cvContourArea su ogni CvSeq restituito per trovare la sua area.

2

È possibile utilizzare le operazioni morfologiche per sopprimere il "disturbo del contorno" (dilatazione nel caso). Ma devi ricordare che l'usabilità delle operazioni morfologiche dipende dal compito corrente. Ad esempio, se hai due oggetti vicini tra loro, la dilatazione può fare un oggetto da loro.

6

Se si ha sempre un fondo controllato, vorrei andare per questi passaggi (come suggerito anche da @damian):

  1. Binarizzazione, vale a dire, la creazione di un'immagine come lo sfondo = 0 e la regioni oggetto = 1 (o 255). Dopodiché, avrai diverse regioni bianche sull'immagine. Ci sono diversi metodi per farlo, ma se il tuo sfondo è controllato puoi usare una soglia fissa. Nota che qui hai rimosso il rumore all'interno degli oggetti.Nell'immagine binaria è sempre possibile utilizzare l'apertura/chiusura morfologica per appianare gli oggetti
  2. Utilizzare cvFindContours per trovare tutti gli oggetti: dovrebbe essere più facile ora.
  3. Riempi i contorni più piccoli con il colore di sfondo utilizzando cvFloodFill.
+0

Come un'adesione al processo di Binarizzazione. È sempre difficile trovare un buon valore di soglia. Io calcolo sempre un Hisogram e cerco un "Low Point". Lì di solito hai un valore di soglia Nive. Se stai usando JPEG questo metodo potrebbe non funzionare così bene. –

Problemi correlati