2014-12-04 27 views
10

Ho usato una tecnica di soglia adattativa per creare un quadro come quello qui sotto:Ottieni l'area nei contorni Opencv Python?

enter image description here

Il codice che ho usato era:

image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 45, 0) 

Poi, io uso questo codice per ottenere i contorni:

cnt = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0] 

il mio obiettivo è quello di generare una maschera utilizzando tutti i pixel all'interno del contorno esterno, quindi voglio riempire tutti i pixel all'interno dell'oggetto devono essere bianchi. Come posso fare questo?

Ho provato il codice qui sotto per creare una maschera, ma la maschera risultante sembra non è diverso quindi l'immagine dopo l'applicazione della soglia adattiva

mask = np.zeros(image.shape[:2], np.uint8) 
cv2.drawContours(mask, cnt, -1, 255, -1) 

risposta

10

Quello che hai è quasi corretto. Se date un'occhiata alla vostra immagine con soglia, il motivo per cui non funziona è perché l'oggetto da scarpe ha lacune nell'immagine. In particolare, quello che cerchi è che ti aspetti che la scarpa abbia il suo perimetro all connesso. Se ciò dovesse accadere, allora se estrai il contorno più esterno (che è ciò che sta facendo il tuo codice), dovresti avere solo un contorno che rappresenta il perimetro esterno dell'oggetto. Una volta completato il contorno, la scarpa dovrebbe essere completamente solida.

Poiché il perimetro della scarpa non è completo e rotto, ciò provoca aree bianche disconnesse. Se si utilizza findContours per trovare tutti i contorni, verranno individuati solo i contorni di ciascuna delle forme bianche e non il perimetro più esterno. Pertanto, se provi a utilizzare findContours, otterrai lo stesso risultato dell'immagine originale, perché stai semplicemente individuando il perimetro di ciascuna regione bianca all'interno dell'immagine, quindi riempiendo queste aree con findContours.


Quello che dovete fare è assicurarsi che l'immagine è completamente chiuso. Quello che vorrei raccomandare è usare morphology per chiudere tutte le regioni disconnesse insieme, quindi eseguire una chiamata findContours su questa nuova immagine. In particolare, eseguire una chiusura morfologica binaria. Ciò che fa è che prende le regioni bianche disconnesse che sono vicine e assicura che siano connesse. Usa una chiusura morfologica e forse usa qualcosa come un elemento strutturante quadrato 7 x 7 per chiudere la scarpa. Questo elemento strutturante può essere considerato come la separazione minima tra le regioni bianche per considerarle come connesse.

Come tale, fare qualcosa di simile:

import numpy as np 
import cv2 
image = cv2.imread('...') # Load your image in here 
# Your code to threshold 
image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 45, 0)  

# Perform morphology 
se = np.ones((7,7), dtype='uint8') 
image_close = cv2.morphologyEx(image, cv2.MORPH_CLOSE, se) 

# Your code now applied to the closed image 
cnt = cv2.findContours(image_close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0] 
mask = np.zeros(image.shape[:2], np.uint8) 
cv2.drawContours(mask, cnt, -1, 255, -1) 

Questo codice riprende in sostanza l'immagine thresholded, e si applica chiusura morfologica di questa immagine. Dopo, troviamo i contorni esterni di questa immagine e li riempiamo di bianco. FWIW, ho scaricato la tua immagine con soglia e l'ho provata da sola. Questo è quello che ottengo con la vostra immagine:

enter image description here

+0

Ciò è impressionante, non riesco a credere che questo funziona! In un pomeriggio sono riuscito a sfocare lo sfondo di un'immagine. Opencv è abbastanza bello. – emschorsch

+0

@emschorsch - grazie per l'upvote :) Sì, OpenCV è una piattaforma fantastica. Lo uso ogni giorno per lavoro. Buon divertimento! – rayryeng

+0

@rayryeng Ho provato questo codice ma sull'ultima riga lancia il seguente errore 'drawing.cpp: 2380: errore: (-215) npoints> 0 nella funzione cv :: drawContours' - Sto usando OpenCV 3.1 e Python 2.7 . Qualche idea? – g491