What algorithm does OpenCV's Bayer conversion use?

14,302

Solution 1

Default is 4way linear interpolation or variable number of gradients if you specify the VNG version.

see ..\modules\imgproc\src\color.cpp for details.

I submitted a simple linear CUDA Bayer->RGB(A) to opencv, haven't followed if it's been accepted but it should be in the bugs tracker. It's based on the code in Cuda Bayer/CFA demosaicing example.

Here is a sample of howto use cv::GPU in your own code.

/*-------RG ccd  BGRA output ----------------------------*/
 __global__ void bayerRG(const cv::gpu::DevMem2Db in, cv::gpu::PtrStepb out)  
{ 
    // Note called for every pair, so x/y are for start of cell so need x+1,Y+1 for right/bottom pair
    // R G 
    // G B 

    // src
    int x = 2 * ((blockIdx.x*blockDim.x) + threadIdx.x);
    int y = 2 * ((blockIdx.y*blockDim.y) + threadIdx.y);

    uchar r,g,b;        

    // 'R'
    r = (in.ptr(y)[x]);
    g = (in.ptr(y)[x-1]+in.ptr(y)[x+1]+(in.ptr(y-1)[x]+in.ptr(y+1)[x]))/4;
    b = (in.ptr(y-1)[x-1]+in.ptr(y-1)[x+1]+(in.ptr(y+1)[x-1]+in.ptr(y+1)[x+1]))/4;  
    ((uchar4*)out.ptr(y))[x] = make_uchar4( b,g,r,0xff);

    // 'G' in R 
    r = (in.ptr(y)[x]+in.ptr(y)[x+2])/2;
    g = (in.ptr(y)[x+1]);
    b = (in.ptr(y-1)[x+1]+in.ptr(y+1)[x+1])/2;
    ((uchar4*)out.ptr(y))[x+1] = make_uchar4( b,g,r,0xff);

    // 'G' in B
    r = (in.ptr(y)[x]+in.ptr(y+2)[x])/2;
    g = (in.ptr(y+1)[x]);
    b = (in.ptr(y+1)[x-1]+in.ptr(y+1)[x+2])/2;
    ((uchar4*)out.ptr(y+1))[x] = make_uchar4( b,g,r,0xff);

    // 'B' 
    r = (in.ptr(y)[x]+in.ptr(y)[x+2]+in.ptr(y+2)[x]+in.ptr(y+2)[x+2])/4;;
    g = (in.ptr(y+1)[x]+in.ptr(y+1)[x+2]+in.ptr(y)[x+1]+in.ptr(y+2)[x+1])/4;
    b = (in.ptr(y+1)[x+1]);
    ((uchar4*)out.ptr(y+1))[x+1] = make_uchar4( b,g,r,0xff);    
} 


/* called from */
extern "C" void cuda_bayer(const cv::gpu::DevMem2Db& img, cv::gpu::PtrStepb out)
{
    dim3 threads(16,16);    
    dim3 grid((img.cols/2)/(threads.x), (img.rows/2)/(threads.y));  

    bayerGR2<<<grid,threads>>>(img,out);    
    cudaThreadSynchronize();
}

Solution 2

Currently, to my knowledge, the best debayer out there is DFPD (directional filtering with posteriori decision) as explained in this paper. The paper is quite explanatory and you can easily prototype this approach on Matlab. Here's a blog post comparing the results of DFPD to debayer based on linear approach. You can visibly see the improvement in artifacts, colors and sharpness.

Solution 3

As far as I know at this point it is using adaptive homogeneity directed demosaicing. Explained in a paper by Hirakawa and many other sources on the web.

Share:
14,302
Ian
Author by

Ian

Updated on June 12, 2022

Comments

  • Ian
    Ian almost 2 years

    I would like to implement a GPU Bayer to RGB image conversion algorithm, and I was wondering what algorithm the OpenCV cvtColor function uses. Looking at the source I see what appears to be a variable number of gradients algorithm and a basic algorithm that could maybe be bilinear interpolation? Does anyone have experience with this that they could share with me, or perhaps know of GPU code to convert from Bayer to BGR format?

    The source code is in imgproc/src/color.cpp. I'm looking for a link to it. Bayer2RGB_ and Bayer2RGB_VNG_8u are the functions I'm looking at.

    Edit: Here's a link to the source.

    http://code.opencv.org/projects/opencv/repository/revisions/master/entry/modules/imgproc/src/color.cpp

    I've already implemented a bilinear interpolation algorithm, but it doesn't seem to work very well for my purposes. The picture looks ok, but I want to compute HOG features from it and in that respect it doesn't seem like a good fit.