2012-05-01 28 views
10

Estoy tratando de usar OpenCV 2.3.1 para convertir una imagen Bayer de 12 bits en una imagen RGB de 8 bits. Esta parece que debería ser bastante sencillo de utilizar la función cvCvtColor, pero la función lanza una excepción cuando la llamo con este código:Convertir imagen Bayer de 12 bits a RGB de 8 bits usando 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); 

pensé que estaba corriendo más allá del final de sourceBuffer, ya que los datos de entrada es de 12 bits, y tuve que pasar en un tipo de 16 bits porque OpenCV no tiene un tipo de 12 bits. Así que dividí el ancho y alto por 2, pero cvCvtColor arrojó una excepción que no tenía información útil (el mensaje de error fue "Excepción desconocida").

Hubo un similar question publicado hace unos meses que nunca fue respondido, pero dado que mi pregunta se refiere más específicamente a los datos de Bayer de 12 bits, pensé que era lo suficientemente distinto como para merecer una nueva pregunta.

Gracias de antemano.

Editar: Debo estar perdiendo algo, porque no puedo incluso conseguir la función cvCvtColor trabajar con los datos de 8 bits:

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

Así resulta que I * * fue perdiendo algo. Mi colega señaló que estaba mezclando llamadas C y C++. Cambiar la última línea a cv :: cvtColor (srcMat, destMat, CV_RGB2BGR); hizo que todo funcionara como un amuleto. Todavía estoy trabajando en el problema original de convertir los datos de Bayer de 16 bits en datos RGB de 8 bits, por lo que publicaré una actualización si encuentro la respuesta a eso. – Gillfish

+2

'cvCvtColor' pertenece a la antigua C OpenCV API, pero' cv :: Mat' es una clase de C++ API. Mezclarlos no es una buena idea y será mejor que uses solo una versión de API. 'cv :: cvtColor (srcMat, dstMat, COLOR_RGB2BGR)' debería funcionar para usted. –

+0

La "apariencia del filtro verde" probablemente significa que ha especificado un patrón Bayer incorrecto. Pruébalos todos. – user3443369

Respuesta

3

La respuesta de Gillfish funciona técnicamente pero durante la conversión utiliza una estructura de datos más pequeña (CV_8UC1) que la entrada (que es CV_16UC1) y pierde algo de información de color.

Sugeriría primero decodificar la codificación de Bayer, pero permanecer en 16 bits por canal (de CV_16UC1 a CV_16UC3) y luego convertir a CV_8UC3.

El código de Gillfish modificado (suponiendo que la cámara da la imagen de 16 bits de codificación de 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

yo era capaz de convertir mis datos a 8 bits RGB usando el siguiente código:

// 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); 

que había asumido erróneamente que los datos de 12 bits que estaba recibiendo de la cámara estaba apretujada, de manera que dos valores de 12 bits estaban contenidas en 3 bytes. Resultó que cada valor estaba contenido en 2 bytes, por lo que no tuve que desempaquetar para obtener mis datos en una matriz de 16 bits compatible con OpenCV.

Editar: Vea la respuesta mejorada de @ petr que convierte a RGB antes de convertir a 8 bits para evitar perder cualquier información de color durante la conversión.

+0

Estoy haciendo lo mismo que aquí, pero mis imágenes parecen tener un filtro verde en la parte superior de la imagen. no estoy seguro de por qué –

+0

@pksorensen: si tiene un problema relacionado, simplemente pídalo en una nueva pregunta y vuelva a vincular con este. De esta forma, puede agregar más detalles sobre su problema particular. – Gillfish

+0

Terminé tomando una ruta diferente y usando el SDK de Nikon para hacer el desentrelazado, ya que me enfrenté a algunos problemas al tratar de hacerlo con libraw y opencv. El uso de Nikon SDK me dio mejores resultados y descubrí por qué no se podían lograr los mismos resultados con libraw y opencv debe esperar. Gracias de cualquier manera. –

Cuestiones relacionadas