OpenCV的拜耳转换使用什么算法?

时间:2012-08-09 19:53:06

标签: c++ c opencv cuda gpu

我想实现GPU Bayer到RGB图像转换算法,我想知道OpenCV cvtColor函数使用什么算法。看看源代码,我看到似乎是一个可变数量的渐变算法和一个可能是双线性插值的基本算法?有没有人有这方面的经验,他们可以与我分享,或者知道GPU代码从拜耳转换为BGR格式?

源代码位于imgproc/src/color.cpp。我正在寻找它的链接。 Bayer2RGB_Bayer2RGB_VNG_8u是我正在查看的功能。

编辑:这是源的链接。

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

我已经实现了双线性插值算法,但它似乎并不能很好地用于我的目的。图片看起来不错,但我想从中计算HOG功能,在这方面看起来不太合适。

3 个答案:

答案 0 :(得分:8)

如果指定VNG版本,则默认为4路线性插值或可变梯度数。

有关详细信息,请参阅.. \ modules \ imgproc \ src \ color.cpp。

我向opencv提交了一个简单的线性CUDA Bayer-> RGB(A),如果它被接受但没有跟踪,但它应该在bug跟踪器中。 它基于Cuda Bayer/CFA demosaicing example中的代码。

以下是如何在您自己的代码中使用cv :: GPU的示例。

/*-------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();
}

答案 1 :(得分:1)

目前,据我所知,最好的debayer有DFPD(后验决策的方向过滤),如this paper中所述。这篇论文很有说服力,你可以在Matlab上轻松地对这种方法进行原型设计。这是blog post根据线性方法比较DFPD与debayer的结果。您可以清楚地看到工件,颜色和清晰度的改进。

答案 2 :(得分:1)

据我所知,它正在使用自适应同质性定向去马赛克。平川和网上许多其他消息来源在一篇论文中进行了解释。