2011-09-18 17 views
15

Sto caricando un'immagine RGB a 24 bit da un file PNG nella mia applicazione OpenCV.Conversione di immagini OpenCV da RGB a scala di grigi usando imread dando scarsi risultati

Tuttavia il caricamento dell'immagine in scala di grigi direttamente utilizzando imread dà un risultato molto scarso.

Mat src1 = imread(inputImageFilename1.c_str(), 0); 

Il caricamento dell'immagine RGB come RGB e la conversione in scala di grigi forniscono un risultato molto più bello.

Mat src1 = imread(inputImageFilename1.c_str(), 1); 
cvtColor(src1, src1Gray, CV_RGB2GRAY); 

mi chiedo se sto usando imread per il mio tipo di immagini in modo corretto. Qualcuno ha avuto un comportamento simile?

L'immagine convertita in scala di grigi usando imread qui è mostrato: Bad result

L'immagine convertita in scala di grigi usando cvtColor è mostrato qui: Good result

+5

"Colore" immagine in OpenCV significa BGR. Quindi la seconda versione del tuo codice non è corretta. Dovrebbe usare 'CV_BGR2GRAY' per la conversione del colore. –

+0

Grazie per il commento. Ho provato a convertire l'immagine in scala di grigi usando CV_BGR2GRAY invece di CV_RGB2GRAY, ma ho ottenuto lo stesso risultato. – tisch

+0

Puoi allegare anche la tua immagine originale? –

risposta

16

Avevo lo stesso problema oggi. In definitiva, ho confrontato tre metodi:

//method 1 
cv::Mat gs = cv::imread(filename, CV_LOAD_IMAGE_GRAYSCALE); 

//method 2 
cv::Mat color = cv::imread(filename, 1); //loads color if it is available 
cv::Mat gs_rgb(color.size(), CV_8UC1); 
cv::cvtColor(color, gs_rgb, CV_RGB2GRAY); 

//method 3 
cv::Mat gs_bgr(color.size(), CV_8UC1); 
cv::cvtColor(color, gs_bgr, CV_BGR2GRAY); 

Metodi 1 (caricamento in scala di grigi) e 3 (CV_BGR2GRAY) producono risultati identici, mentre il metodo 2 produce un risultato diverso. Per i miei fini, ho iniziato a utilizzare CV_BGR2GRAY.

I miei file di input sono jpg, quindi potrebbero esserci problemi relativi al tuo particolare formato di immagine.

+0

Opencv imread restituisce l'immagine in formato BGR, quindi penso che la conversione corretta in GRAY Scale sia CV_BGR2GRAY come hai menzionato nel 3 ° metodo – evk1206

1

Ho avuto un problema simile volta, lavorando con shader OpenGL . Sembra che il primo contenitore con cui OpenCV legge l'immagine non supporta tutte le gamme di colori e quindi si vede che l'immagine è una scarsa trasformazione della scala di grigi. Tuttavia, una volta convertita l'immagine originale in scala di grigi usando cvtColor, il contenitore è diverso dal primo e supporta tutti gli intervalli. A mio parere, il primo utilizza meno di 8 bit per la scala di grigi o il passaggio alla scala di grigi utilizza un metodo errato. Ma il secondo dà un'immagine liscia a causa di più bit nel canale grigio.

+0

Hai trovato una documentazione per supportare questo ragionamento? Affrontando un problema simile e sono propenso a credere che questo potrebbe essere il caso ma non riesco a trovare nulla di decisivo da mettere nel mio ragionamento – Ani

+0

Beh, è ​​il caso dal momento che il frame buffer contiene un intervallo di 255 per ogni colore e anche 255 per monocromatico spettro. Hai bisogno di punti mobili per supportare una gamma migliore. –

10

La risposta semplice è che le funzioni openCV utilizzano il formato BGR. Se leggi un'immagine con imread o VideoCapture, sarà sempre BGR. Se si utilizza RGB2GRAY, si scambia il canale blu con il verde. La formula per ottenere la luminosità è

y = 0.587*green + 0.299*red + 0.114*blue 

quindi se si cambia verde e blu, ciò causerà un errore di calcolo enorme.

Greets

+1

Non è poi anche intercambiare il canale rosso? In questo caso interpretando il dato 'BGR' come' RGB' che poi porta (il reale) 'B' interpretato erroneamente come' R', e 'R' come' B'? Quindi, secondo la tua risposta, la correzione sostituirà 'CV_RGB2GRAY' nella chiamata 'cvtColor' con' CV_BGR2GRAY'? –

Problemi correlati