2012-08-09 10 views
5

Chciałbym zaimplementować algorytm GPU Bayer do konwersji obrazu RGB i zastanawiałem się, jaki algorytm wykorzystuje funkcja OpenCV cvtColor. Patrząc na źródło, widzę, jak się wydaje zmienna liczba algorytmów gradientów i podstawowy algorytm, który może być interpolacją dwuliniową? Czy ktokolwiek ma z tym doświadczenie, które mógłby mi udostępnić, czy może zna kod GPU do konwersji z formatu Bayer na format BGR?Jakiego algorytmu używa OpenCV's Bayer?

Kod źródłowy znajduje się w imgproc/src/color.cpp. Szukam łącza do tego. Bayer2RGB_ i Bayer2RGB_VNG_8u są funkcjami, na które patrzę.

Edytuj: Oto link do źródła.

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

Ja już wdrożony algorytm interpolacji dwuliniowy, ale nie wydaje się działać bardzo dobrze dla moich celów. Obraz wygląda dobrze, ale chcę obliczyć cechy HOG i pod tym względem nie wydaje się być dobrze dopasowany.

+0

+1 za Twoje imię. Żartuję, dobre pytanie. :) –

Odpowiedz

8

Domyślne ustawienie to interpolacja liniowa 4-liniowa lub zmienna liczba gradientów, jeśli wybrano wersję VNG.

zobacz .. \ modules \ imgproc \ src \ color.cpp, aby uzyskać szczegółowe informacje.

Przesłałem proste liniowe CUDA Bayer-> RGB (A) do opencv, nie poszedłem, jeśli zostało zaakceptowane, ale powinno być w trackerze błędów. Jest oparty na kodzie w Cuda Bayer/CFA demosaicing example.

Oto przykład jak używać cv :: GPU we własnym kodzie.

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

Dziękuję, patrzę na to teraz. – Ian

1

Obecnie, według mojej wiedzy, najlepiej debayer tam jest DFPD (kierunkowe filtrowanie z decyzją posteriori), jak wyjaśniono w this paper. Dokument jest dość objaśniający i możesz łatwo prototypować to podejście na Matlabie. Oto blog post porównanie wyników DFPD z debayerem w oparciu o podejście liniowe. Widać wyraźnie poprawę artefaktów, kolorów i ostrości.

1

O ile mi wiadomo, w tym momencie wykorzystuje on adaptacyjne odwzorowywanie jednorodne. Wyjaśniono w artykule Hirakawy i wielu innych źródłach w Internecie.

Powiązane problemy