Convert 12-bit Bayer image to 8-bit RGB using OpenCV

image, opencv, rgb

Solution

The Gillfish's answer technically works but during the conversion it uses smaller data structure (CV_8UC1) than the input (which is CV_16UC1) and loses some color information.

I would suggest first to decode the Bayer encoding but stay in 16-bits per channel (from CV_16UC1 to CV_16UC3) and later convert to CV_8UC3.

The modified Gillfish's code (assuming the camera gives image in 16bit Bayer encoding):

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

Problem

I am trying to use OpenCV 2.3.1 to convert a 12-bit Bayer image to an 8-bit RGB image. This seems like it should be fairly straightforward using the cvCvtColor function, but the function throws an exception when I call it with this code: ``` 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); ``` I thought that I was running past the end of sourceBuffer, since the input data is 12-bit, and I had to pass in a 16-bit type because OpenCV doesn't have a 12-bit type. So I divided the width and height by 2, but cvCvtColor still threw an exception that didn't have any helpful information in it (the error message was "Unknown exception"). There was a similar question posted a few months ago that was never answered, but since my question deals more specifically with 12-bit Bayer data, I thought it was sufficiently distinct to merit a new question. Thanks in advance. Edit: I must be missing something, because I can't even get the cvCvtColor function to work on 8-bit data: ``` 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); ```

Original source