2012-05-01 10 views
10

Sto cercando di utilizzare OpenCV 2.3.1 per convertire un'immagine Bayer a 12 bit in un'immagine RGB a 8 bit. Questo sembra che dovrebbe essere abbastanza semplice utilizzando la funzione di cvCvtColor, ma la funzione genera un'eccezione quando lo chiamo io con questo codice:Converti immagini Bayer a 12 bit in RGB a 8 bit utilizzando OpenCV

int cvType = CV_MAKETYPE(CV_16U, 1); 
cv::Mat bayerSource(height, width, cvType, sourceBuffer); 
cv::Mat rgbDest(height, width, CV_8UC3); 
cvCvtColor(&bayerSource, &rgbDest, CV_BayerBG2RGB); 

ho pensato che stavo correndo oltre la fine del sourceBuffer, dal momento che i dati di input è 12-bit, e ho dovuto passare in un tipo a 16 bit perché OpenCV non ha un tipo a 12 bit. Quindi ho diviso la larghezza e l'altezza per 2, ma cvCvtColor ha comunque generato un'eccezione che non conteneva alcuna informazione utile (il messaggio di errore era "Eccezione sconosciuta").

C'è stato un similar question pubblicato qualche mese fa a cui non è mai stata data risposta, ma poiché la mia domanda riguarda in modo più specifico i dati Bayer a 12 bit, ho pensato che fosse sufficientemente distinto per meritare una nuova domanda.

Grazie in anticipo.

Edit: Devo mancare qualcosa, perché non posso anche ottenere la funzione cvCvtColor di lavorare su dati a 8-bit:

cv::Mat srcMat(100, 100, CV_8UC3); 
const cv::Scalar val(255,0,0); 
srcMat.setTo(val); 
cv::Mat destMat(100, 100, CV_8UC3); 
cvCvtColor(&srcMat, &destMat, CV_RGB2BGR); 
+2

Così si scopre che io * * è stato manca qualcosa. Il mio collega ha sottolineato che stavo mescolando le chiamate C e C++. Modifica dell'ultima riga su cv :: cvtColor (srcMat, destMat, CV_RGB2BGR); ha reso tutto funziona come un fascino. Sto ancora lavorando al problema originale della conversione dei dati Bayer a 16 bit in dati RGB a 8 bit, quindi pubblicherò un aggiornamento se trovo la risposta. – Gillfish

+2

'cvCvtColor' appartiene alla vecchia API C OpenCV, ma' cv :: Mat' è una classe dell'API C++. Mescolarli non è una buona idea e faresti meglio ad usare solo una versione dell'API. 'cv :: cvtColor (srcMat, dstMat, COLOR_RGB2BGR)' dovrebbe funzionare per te. –

+0

"Effetto filtro verde" probabilmente significa che hai specificato il modello Bayer sbagliato. Provali tutti. – user3443369

risposta

3

La risposta di Gillfish funziona tecnicamente ma durante la conversione utilizza una struttura dati più piccola (CV_8UC1) dell'input (che è CV_16UC1) e perde alcune informazioni sul colore.

Suggerisco prima di decodificare la codifica Bayer ma di rimanere a 16 bit per canale (da CV_16UC1 a CV_16UC3) e successivamente convertire in CV_8UC3.

Il codice del Gillfish modificato (supponendo che la macchina fotografica dà immagine a 16 bit codifica Bayer):

// Copy the data into an OpenCV Mat structure 
cv::Mat mat16uc1_bayer(height, width, CV_16UC1, inputBuffer); 

// Decode the Bayer data to RGB but keep using 16 bits per channel 
cv::Mat mat16uc3_rgb(width, height, CV_16UC3); 
cv::cvtColor(mat16uc1_bayer, mat16uc3_rgb, cv::COLOR_BayerGR2RGB); 

// Convert the 16-bit per channel RGB image to 8-bit per channel 
cv::Mat mat8uc3_rgb(width, height, CV_8UC3); 
mat16uc3_rgb.convertTo(mat8uc3_rgb, CV_8UC3, 1.0/256); //this could be perhaps done more effectively by cropping bits 
14

ero in grado di convertire i miei dati a 8-bit RGB utilizzando il seguente codice:

// Copy the data into an OpenCV Mat structure 
cv::Mat bayer16BitMat(height, width, CV_16UC1, inputBuffer); 

// Convert the Bayer data from 16-bit to to 8-bit 
cv::Mat bayer8BitMat = bayer16BitMat.clone(); 
// The 3rd parameter here scales the data by 1/16 so that it fits in 8 bits. 
// Without it, convertTo() just seems to chop off the high order bits. 
bayer8BitMat.convertTo(bayer8BitMat, CV_8UC1, 0.0625); 

// Convert the Bayer data to 8-bit RGB 
cv::Mat rgb8BitMat(height, width, CV_8UC3); 
cv::cvtColor(bayer8Bit, rgb8BitMat, CV_BayerGR2RGB); 

avevo erroneamente supposto che i dati a 12 bit mi è stato sempre dalla fotocamera era fitto, in modo che due valori a 12 bit sono contenuti in 3 byte. Si scopre che ogni valore era contenuto in 2 byte, quindi non ho dovuto eseguire alcun disimballaggio per ottenere i miei dati in un array a 16 bit supportato da OpenCV.

Modifica: Vedere la risposta migliorata di Petr che converte in RGB prima di convertirla in 8 bit per evitare di perdere le informazioni sul colore durante la conversione.

+0

Sto facendo lo stesso come qui ma le mie immagini sembrano avere un filtro verde ontop dell'immagine. non so perché –

+0

@pksorensen: se hai un problema correlato, basta chiedere in una nuova domanda e link a questo. In questo modo puoi aggiungere ulteriori dettagli sul tuo particolare problema. – Gillfish

+0

Alla fine ho intrapreso un percorso diverso e ho utilizzato l'SDK Nikon per eseguire il de-bayer in quanto ho dovuto affrontare alcuni problemi nel tentativo di farlo con libraw e opencv. L'utilizzo di nikon SDK mi ha dato risultati migliori e ho scoperto perché gli stessi risultati non potevano essere ottenuti con la libraw e l'opencv deve attendere. Grazie comunque. –

Problemi correlati