Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ cuda将.png转换为灰度_C++_C_Cuda_Png_Grayscale - Fatal编程技术网

C++ cuda将.png转换为灰度

C++ cuda将.png转换为灰度,c++,c,cuda,png,grayscale,C++,C,Cuda,Png,Grayscale,我正在用c写一个可以将.png图像转换成灰度的应用程序。 我用的是c和cuda。我对cuda代码有问题,我不知道为什么。(我是cuda begginer) 我的转换函数看起来: __global__ void setPixelToGrayscale(unsigned char *image) { int i = threadIdx.x*4; float gray; float r, g, b; r = image[i + 0]; g = image[i +

我正在用c写一个可以将.png图像转换成灰度的应用程序。 我用的是c和cuda。我对cuda代码有问题,我不知道为什么。(我是cuda begginer)

我的转换函数看起来:

__global__
void setPixelToGrayscale(unsigned char *image)
{
    int i = threadIdx.x*4;
    float gray;
    float r, g, b;
    r = image[i + 0];
    g = image[i + 1];
    b = image[i + 2];
    gray = .299f*r + .587f*g + .114f*b;
    image[i + 0] = gray;
    image[i + 1] = gray;
    image[i + 2] = gray;
    image[i + 3] = 255;
}


void transformToGrayCuda(rgb_image *img)
{

    unsigned char* image = img->image;
    unsigned char* image_d;
    unsigned width = img->width;
    unsigned height = img->height;
    int N = (int)width * (int)height; 
    size_t size = N * sizeof(unsigned char);
    cudaMalloc((void **) image_d, size);
    cudaMemcpy(image_d, image,  size, cudaMemcpyHostToDevice);
    setPixelToGrayscale<<<1, N>>>(image_d);
    cudaMemcpy(image, image_d, size, cudaMemcpyDeviceToHost);
    cudaFree(image_d);

/* this works fine if cuda code is commented
int j=0;
for(j=0; j<N; j++)
{
    int i = j*4;
    float gray;
    float r, g, b;
    r = image[i + 0];
    g = image[i + 1];
    b = image[i + 2];
    gray = .299f*r + .587f*g + .114f*b;
    image[i + 0] = gray;
    image[i + 1] = gray;
    image[i + 2] = gray;
    image[i + 3] = 255;
}
*/

}
\u全局__
void setPixelToGrayscale(无符号字符*图像)
{
int i=threadIdx.x*4;
浮灰;
浮子r,g,b;
r=图像[i+0];
g=图像[i+1];
b=图像[i+2];
灰色=.299f*r+.587f*g+.114f*b;
图像[i+0]=灰色;
图像[i+1]=灰色;
图像[i+2]=灰色;
图像[i+3]=255;
}
void transformToGrayCuda(rgb_图像*img)
{
无符号字符*image=img->image;
无符号字符*图像\u d;
无符号宽度=img->width;
无符号高度=img->高度;
int N=(int)宽度*(int)高度;
size\u t size=N*sizeof(无符号字符);
Cudamaloc((空白**)图像尺寸);
cudaMemcpy(图像、图像、大小、cudaMemcpyHostToDevice);
setPixelToGrayscale(图像);
cudaMemcpy(图像、图像、大小、cudaMemcpyDeviceToHost);
cudaFree(图d);
/*如果对cuda代码进行了注释,则此功能可以正常工作
int j=0;

对于(j=0;j代码中的问题是:

cudaMalloc((void **) image_d, size);
您应该给指针一个指针,而不是将其转换为变量。 正确的代码是:

cudaMalloc(&image_d, size);

代码中的问题是:

cudaMalloc((void **) image_d, size);
您应该给指针一个指针,而不是将其转换为变量。 正确的代码是:

cudaMalloc(&image_d, size);

N的大小是多少?。您在一个块中运行所有N个线程。根据GPU的不同,每个块有512或1024个线程的限制。如果N>512,请更改块的数量。块的数量=1+N/512,每个块的线程数=512。在这里,如果threadid 此外,内核执行是异步的。因此,在内核调用之后需要调用cudadevicesynchronize()


如果您给出了确切的错误/问题,那么我可以提供更多帮助。

N的大小是多少?。您在一个块中运行所有N个线程。根据GPU的不同,每个块有512或1024个线程的限制。如果N>512,请更改块数。块数=1+N/512,每个块的线程数=512。她e、 如果threadid 此外,内核执行是异步的。因此,在内核调用之后需要调用cudadevicesynchronize()



如果你给出确切的错误/问题,那么我可以提供更多帮助。

不会改变任何东西加权平均值是正确的。OP使用的数字是NTSC权重。在sRGB中,权重是Y=0.2126*R+0.7152*G+0.0722*B。这两组权重说明人眼对绿色更敏感,对bl更不敏感ue.@GlennRanders Pehrson在第一版中说图片看起来不太合适。另一个WTF是:我投了反对票,认为答案是正确的。(用户在另一个答案的评论中写下了答案,并选择了另一个帖子作为正确答案)我投了反对票,因为有人建议使用未加权的颜色平均值。请看这解释了为什么这些值应该加权。关于加权的错误陈述已从答案中删除,因此+1。不会改变任何东西加权平均值是正确的。OP使用的数字是NTSC权重。在sRGB中,权重为Y=0.2126*R+0.7152*G+0.0722*B。这两组权重都说明了人眼对绿色更敏感,而对蓝色更不敏感。@GlennRanders Pehrson在第一次修订中说,这张图片看起来不太合适。另一个WTF是:我投了反对票,这是正确的答案。(用户将答案写在另一个答案的评论中,并选择另一个帖子作为正确答案)我投了反对票,因为有人建议使用未加权的颜色平均值。请看哪一个解释了为什么应该对值进行加权。关于加权的错误陈述已从答案中删除,因此+1.cudaMemcpy和cudaFree都是阻塞调用。在这种情况下,不需要显式同步调用。我更改了它,但仍然没有t将图像更改为灰度。我在评论中将我的代码上载到了主帖子,你能检查一下吗?你的代码中有一个竞态条件。第I个线程的图像[I+2]和(I+1)中的图像[I+1]线程可能同时在同一位置写入。争用条件会导致不可预测的结果。请为此重构代码。我相信这对代码的逻辑来说不会太困难。此外,检查大小变量是否在“int”范围内。有时,“int”范围可能无法适应,您需要在这种情况下使用“long”。不,(4+2)!=(8+1)。我发现了问题。在Cudamaloc((void**)image\u d,size);我必须使用指向图像的指针,而不是图像。你关于块的建议很有用。Thanksudamcpy和cudaFree都是阻塞调用。在这种情况下不需要显式同步调用。我更改了它,但它仍然不会将图像更改为灰度。我将我的代码在注释中上载到主帖子,你能检查一下吗?存在种族条件第i个线程的图像[i+2]和(i+1)中的图像[i+1]线程可能同时在同一位置写入。争用条件会导致不可预测的结果。请为此重构代码。我相信这对代码的逻辑来说不会太困难。此外,检查大小变量是否在“int”范围内。有时,“int”范围可能无法适应,您需要在这种情况下使用“long”。不,(4+2)!=(8+1)。我发现了问题。在Cudamaloc((void**)image\u d,size);我必须使用指向图像的指针,而不是图像。你关于块的建议是有用的。感谢你,如果没有其他人可以运行的完整示例,可以这么说。这是我的代码链接。LOL,我无意观看视频广告,只是为了看你的源代码。为什么不将其编辑到问题中?(或者至少使用pastebin.com或类似工具)无论如何,在你的任务中发布一个完整的代码