2012-08-09 38 views
5

Me gustaría implementar un algoritmo de conversión de imagen GPU Bayer a RGB, y me preguntaba qué algoritmo utiliza la función OpenCV cvtColor. Al observar la fuente, veo lo que parece ser un número variable de algoritmos de gradientes y un algoritmo básico que podría ser una interpolación bilineal. ¿Alguien tiene experiencia con esto que puedan compartir conmigo, o tal vez conozca el código GPU para convertir de Bayer a formato BGR?¿Qué algoritmo usa la conversión Bayer de OpenCV?

El código fuente está en imgproc/src/color.cpp. Estoy buscando un enlace para ello. Bayer2RGB_ y Bayer2RGB_VNG_8u son las funciones que estoy viendo.

Editar: Aquí hay un enlace a la fuente.

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

que ya haya implementado un algoritmo de interpolación bilineal, pero no parece funcionar muy bien para mis propósitos. La imagen se ve bien, pero quiero calcular las características de HOG a partir de ella y, a ese respecto, no parece una buena opción.

+0

+1 para su nombre. Es una broma, buena pregunta. :) –

Respuesta

8

El valor predeterminado es la interpolación lineal de 4 vías o el número variable de degradados si especifica la versión de VNG.

ver .. \ modules \ imgproc \ src \ color.cpp para más detalles.

Presenté un CUDA lineal simple Bayer-> RGB (A) a opencv, no he seguido si ha sido aceptado pero debe estar en el rastreador de errores. Se basa en el código en Cuda Bayer/CFA demosaicing example.

Aquí hay una muestra de cómo usar cv :: GPU en su propio código.

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

Gracias, estoy viendo eso ahora. – Ian

1

la actualidad, que yo sepa, el mejor debayer por ahí es DFPD (filtrado direccional con decisión a posteriori) como se explica en this paper. El documento es bastante explicativo y puede prototipar fácilmente este enfoque en Matlab. Aquí hay un blog post que compara los resultados de DFPD con el debate basado en el enfoque lineal. Puede ver de forma visible la mejora en artefactos, colores y nitidez.

1

Hasta donde yo sé, en este punto está usando el demosaicing dirigido a la homogeneidad adaptativa. Explicado en un documento de Hirakawa y muchas otras fuentes en la web.

Cuestiones relacionadas