Demosaicing with opencv

3.6k views Asked by At

I am stuck trying to figure out how to use the opencv demosaicing function. I have OpenCV 4.4.0 installed with CUDA support compiled in, and so far what I think I need to do is:

  1. Read in the raw image data
  2. Load in raw image data to a Mat object
  3. Upload the Mat data to a GpuMat (host to device upload)
  4. Demosaic
  5. Download the GpuMat data (device to host download) to a Mat object
  6. Display or write out the result

Here is a snippet of the code I have.

ifstream ifs("image.raw", ios_base::binary);
ifs.read(buffer, length);
// snip ...buffer contains the entire file...

Mat src_host(6464, 4860, CV_16UC1, buffer);
GpuMat dst, src;
src.upload(src_host);

// Debayer here
cv::cuda::demosaicing(src, dst, COLOR_BayerRG2BGR);

// have a look
Mat result_host;
dst.download(result_host);

namedWindow("Debayered Image", WINDOW_KEEPRATIO);
resizeWindow("Debayered Image", 6464/5, 4860/5);
imshow("Debayered Image", result_host);
waitKey(0);

I have raw frames from cameras that have 12 bits per pixel, RGGB, dimensions 6464 x 4860. I'm uncertain of how to specify this for OpenCV in terms of width and height, what CV_TYPE to give it, whether I am reading in and uploading the data properly for demosaicing, what COLOR_code to give it for demosaicing, and how to download the result for display and saving to file (preferably a high level routine to write a png or similar).

Does anyone know whether I'm on the right track or not?

Thanks! James

1

There are 1 answers

0
javascripting.dev On

Yes, I'm on the right track. The rows and columns are accidentally swapped, so the corrected code is:

ifstream ifs("image.raw", ios_base::binary);
ifs.read(buffer, length);
// snip ...buffer contains the entire file...

Mat src_host(4860, 6464, CV_16UC1, buffer);
GpuMat dst, src;
src.upload(src_host);

// Debayer here
cv::cuda::demosaicing(src, dst, COLOR_BayerRG2BGR);

// have a look
Mat result_host;
dst.download(result_host);

namedWindow("Debayered Image", WINDOW_KEEPRATIO);
resizeWindow("Debayered Image", 4860/2, 6464/2);
imshow("Debayered Image", result_host);
waitKey(0);

While the sensor data is 12 bit, each 12 bits sits inside 16 bits, which makes it a lot easier to deal with.