Cuda проблема при преобразовании изображения в оттенки серого

У меня проблема со следующим кодом. Следующий код берет входное изображение и должно сохранить его в градациях серого. К сожалению, кажется, что он выполняет ожидаемое поведение, но обрабатывает только часть изображения, а не целое. Кажется, что проблема возникает в cudamemcpy от устройства к хосту.

Я полагаю, что, вероятно, у меня возникли проблемы, когда я выделяю память в Cuda.

__global__ void rgb2grayCudaKernel(unsigned char *inputImage, unsigned char *grayImage, const int width, const int height) 
{


    int ty = (blockIdx.x * blockDim.x) + threadIdx.x;
    //int tx = (blockIdx.x * blockDim.x) + threadIdx.x;
    int tx = (blockIdx.y * blockDim.y) + threadIdx.y;

    if( (ty < height && tx<width) ) 
    {

            float grayPix = 0.0f;
            float r = static_cast< float >(inputImage[(ty * width) + tx]);          
            float g = static_cast< float >(inputImage[(width * height) + (ty * width) + tx]);
            float b = static_cast< float >(inputImage[(2 * width * height) + (ty * width) + tx]);

            grayPix = (0.3f * r) + (0.59f * g) + (0.11f * b); 

            grayImage[(ty * width) + tx] = static_cast< unsigned char >(grayPix);   

    }   
}

//***************************************rgb2gray function, call of kernel in here *************************************
void rgb2grayCuda(unsigned char *inputImage, unsigned char *grayImage, const int width, const int height)
{
    unsigned char *inputImage_c, *grayImage_c;
    const int sizee= (width*height);    

// **********memory allocation for pointers and cuda******************


    cudaMalloc((void **) &inputImage_c, sizee);
    checkCudaError("im not alloc!");
    cudaMalloc((void **) &grayImage_c, sizee);
    checkCudaError("gray not alloc !");

//***********copy to device*************************
    cudaMemcpy(inputImage_c, inputImage, sizee*sizeof(unsigned char), cudaMemcpyHostToDevice);
    checkCudaError("im not send !");
    cudaMemcpy(grayImage_c, grayImage, sizee*sizeof(unsigned char), cudaMemcpyHostToDevice);
    checkCudaError("gray not send !");
    dim3 thrb(32,32);
    dim3 numb (ceil(width*height/1024));
//**************Execute Kernel (Timer in here)**************************
    NSTimer kernelTime = NSTimer("kernelTime", false, false);
    kernelTime.start();

    rgb2grayCudaKernel<<<numb,1024>>> (inputImage_c, grayImage_c, width, height);
    checkCudaError("kernel!");
    kernelTime.stop();
//**************copy back to host*************************
    printf("/c");
    cudaMemcpy(grayImage, grayImage_c, sizee*sizeof(unsigned char), cudaMemcpyDeviceToHost);
    checkCudaError("Receiving data from CPU failed!");

//*********************free memory***************************
    cudaFree(inputImage_c);
    cudaFree(grayImage_c);


//**********************print time****************  
cout << fixed << setprecision(6);
cout << "rgb2gray (cpu): \t\t" << kernelTime.getElapsed() << " seconds." << endl;

}

1 ответ

const int sizee= (width*height); 

должно быть:

const int sizee= (width*height*3); 

для данных RGB (1 байт на канал).

Я верю в растровые изображения, цвета должны чередоваться как в:

rgb of pixel1, rgb of pixel 2 ... rgb of pixel width*height

Поэтому ваше ядро ​​должно быть:

__global__ void rgb2grayCudaKernel(unsigned char *inputImage, unsigned char *grayImage, const int width, const int height) 
{


    int tx = (blockIdx.y * blockDim.y) + threadIdx.y;
    int ty = (blockIdx.x * blockDim.x) + threadIdx.x;

    if( (ty < height && tx<width) ) 
    {
            unsigned int pixel = ty*width+tx;
            float grayPix = 0.0f;
            float r = static_cast< float >(inputImage[pixel*3]);          
            float g = static_cast< float >(inputImage[pixel*3+1]);
            float b = static_cast< float >(inputImage[pixel*3+2]);

            grayPix = (0.3f * r) + (0.59f * g) + (0.11f * b); 

            grayImage[pixel] = static_cast< unsigned char >(grayPix);   

    }   
}

Также из того, что я видел, светимость рассчитывается как 0,21 R + 0,72 G + 0,07 B.

Другие вопросы по тегам