2017-04-18 12 views
-1

RGB2GRAY 이미지 처리 알고리즘이 필요합니다. 전역 함수를 완료하는 데 도움이 필요하거나 * d_src 포인터에 액세스 할 수있는 방법이 필요합니다. 이것은 내 코드입니다, 당신의 도움을 크게 주시면 감사하겠습니다. 당신의 dst 개체가 unsigned char로 구성되어 있기 때문에 다음과 같이CUDA 및 CImg 라이브러리가있는 RGB2GRAY

#include "cuda_runtime.h" 
#include "device_launch_parameters.h" 

#include "CImg.h" 
#include <iostream> 

using namespace std; 
using namespace cimg_library; 

__global__ void rgb2gray(unsigned char * d_src, unsigned char * d_dst, int width, int height){ 

    int pos_x = blockIdx.x * blockDim.x + threadIdx.x; 
    int pos_y = blockIdx.y * blockDim.y + threadIdx.y; 

    if (pos_x >= width || pos_y >= height) 
     return; 

} 


int main(){ 
    //Load image 
    CImg<unsigned char> src("lena.jpg"); 
    int width = src.width(); 
    int height = src.height(); 
    unsigned long sizee = src.size(); 

    int sze = width * height; 

    cout << sze << endl; 

    //create pointer to image 
    unsigned char *h_src = src.data(); 

    CImg<unsigned char> dst(width, height, 1, 1); 
    unsigned char *h_dst = dst.data(); 

    unsigned char *d_src; 
    unsigned char *d_dst; 

    cout << sizee << endl; 

    cudaMalloc((void**)&d_src, sizee); 
    cudaMalloc((void**)&d_dst, width*height*sizeof(int)); 

    cudaMemcpy(d_src, h_src, sizee, cudaMemcpyHostToDevice); 

    //launch the kernel 
    rgb2gray << <(width/16,height/16,1), (16, 16, 1) >> >(d_src, d_dst, width, height); 

    //force the printf()s to flush 
    cudaDeviceSynchronize(); 
    // copy back the result array to the CPU 
    cudaMemcpy(h_dst, d_dst, width*height, cudaMemcpyDeviceToHost); 

    cudaFree(d_src); 
    cudaFree(d_dst); 


    CImgDisplay main_disp(dst, "After Processing"); 
    while (!main_disp.is_closed()) 
     main_disp.wait(); 


    return 0; 
} 

답변

1

첫째, d_dst을 할당; width 또는 height16의 배수가 아닌 경우

cudaMalloc((void**)&d_dst, width*height*sizeof(unsigned char)); 

다음 격자의 경우를 고려하여, 각 픽셀을 커버한다. 다음 커널 구성으로 커널을 시작하십시오.

dim3 blkDim (16, 16, 1); 
dim3 grdDim ((width + 15)/16, (height + 15)/16, 1); 
rgb2gray<<<grdDim, blkDim>>>(d_src, d_dst, width, height); 

마지막으로, 커널은 다음과 같아야합니다. RGB 채널은 d_src으로 분할됩니다.

int pos_x = blockIdx.x * blockDim.x + threadIdx.x; 
int pos_y = blockIdx.y * blockDim.y + threadIdx.y; 

if (pos_x >= width || pos_y >= height) 
    return; 

unsigned char r = d_src[pos_y * width + pos_x]; 
unsigned char g = d_src[(height + pos_y) * width + pos_x]; 
unsigned char b = d_src[(height * 2 + pos_y) * width + pos_x]; 

unsigned int _gray = (unsigned int)((float)(r + g + b)/3.0f + 0.5); 
unsigned char gray = _gray > 255 ? 255 : _gray; 

d_dst[pos_y * width + pos_x] = gray; 

전체 코드 here을 볼 수 있습니다.

+0

설명을 듣고 주셔서 대단히 감사드립니다. 채널이 어떻게 분할되었는지 잘 모르겠습니다. – JA7

+0

@ JA7 "픽셀 데이터가 CImg과 함께 저장되는 방법"에 대한 자세한 내용은 [this] (http://cimg.eu/reference/group__cimg__storage.html)을 참조하십시오. – nglee