cudaMemcpy将rgb发布到灰度

cudaMemcpy将rgb发布到灰度,cuda,Cuda,正在尝试创建一个简单的RGB到灰度项目。请原谅这个奇怪的图书馆,我的教授拒绝更新我们学校的服务器,我的家用电脑也没有Nvidia卡 #include <stdlib.h> #include <stdio.h> #include <cuda.h> #include <cuda_runtime.h> #include <math.h> #include <string.h> //Define and include suppor

正在尝试创建一个简单的RGB到灰度项目。请原谅这个奇怪的图书馆,我的教授拒绝更新我们学校的服务器,我的家用电脑也没有Nvidia卡

#include <stdlib.h>
#include <stdio.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <math.h>
#include <string.h>
//Define and include supporting documentation. 
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

#define BLOCK_SIZE 16



__global__ void ConvertToGrayScale(unsigned char *image,unsigned char *grayimage, int height,int width,int channel,int gray_channel){

    int col = threadIdx.x + blockIdx.x * blockDim.x;
    int row = threadIdx.y + blockIdx.y * blockDim.y;

    if(row >= height || col >= width) return;

    unsigned char red=0, green=0, blue=0;
    int imageposition = row*width + col;
    int grayimageposition = row*width + col;
    imageposition = imageposition*channel;
    
    //grayimageposition = imageposition*gray_channel;


    red = image[imageposition];
    green = image[imageposition+1];
    blue = image[imageposition+2];
    grayimage[grayimageposition] = (uint8_t)(red*0.3+green*0.59+blue*0.11);

    //leave the last channel of the image the same as the grey
    if(channel==4){
        grayimage[grayimageposition + 1] = image[imageposition + 3];
    }

    //grayimage = image;
}

int main(int argc, char *argv[]){
    

    // width height and nbr of channels for image
    int width, height, channel;
    //Handle Input Image
    if (argc != 2){
        printf("Usage: ./hw5 'image.jpg'\n");
        exit(1);
    }
    
    //Load our image into a 1D array which is a linearized 2D grid where each
    //position has a pixel RGB value. so (x,y).(R,G,B)
    unsigned char *image = stbi_load(argv[1] , &width, &height, &channel, 0);
    if (image == NULL){
        printf("Could not load image.\n");
        exit(1);
    }
    //If the jpeg image has a 4th channel due to formating create this channel
    //in the grey scale image also
    int gray_channel;
    if (channel == 4){
        gray_channel = 2;
    }else{
        gray_channel = 1;
    }
    

    //Define size of our image matrices
    int graybytes = width*height*gray_channel*sizeof(unsigned char);
    int colorbytes = width*height*channel*sizeof(unsigned char);
    
    unsigned char *imagegray;
    imagegray = (unsigned char*)malloc(graybytes*gray_channel);
    
    unsigned char* d_image;
    unsigned char* d_imagegray;
    
    cudaMalloc((void**)&d_image,colorbytes);
    cudaMalloc((void**)&d_imagegray, graybytes);
    cudaMemcpy(d_image, image, colorbytes, cudaMemcpyHostToDevice);
    
    cudaMemcpy(d_imagegray, imagegray, graybytes, cudaMemcpyHostToDevice);


    
    if(!imagegray){
        printf("Could not allocate memory for the Gray Scale Image.\n");
        exit(1);
    }

    if(!image){
        printf("Could not allocate memory for the Gray Scale Image.\n");
        exit(1);
    }
    
    dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
    dim3 dimGrid((width/dimBlock.x)+1, (height/dimBlock.y)+1);


    ConvertToGrayScale<<<dimGrid, dimBlock>>>(d_image,d_imagegray,height,width,channel,gray_channel);
    cudaMemcpy( image, d_image, colorbytes*channel, cudaMemcpyDeviceToHost);
    cudaMemcpy( imagegray, d_imagegray, graybytes*channel, cudaMemcpyDeviceToHost);
    cudaThreadSynchronize();
    cudaGetLastError();

    
    
    char grey_name[30] = "gray_scale_";
    // stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality)
    stbi_write_jpg(strcat(grey_name,argv[1]), width, height, gray_channel, imagegray, 100);

    char color_name[30] = "color_scale_";
    // stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality)
    stbi_write_jpg(strcat(color_name,argv[1]), width, height, channel, image, 100);

        free(imagegray);
    stbi_image_free(image);

    cudaFree(d_image);
    cudaFree(d_imagegray);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
//定义并包含支持文档。
#定义机顶盒映像的实现
#包括“stb_image.h”
#定义机顶盒映像写入实现
#包括“stb_image_write.h”
#定义块大小16
__全局无效转换灰度(无符号字符*图像、无符号字符*灰度图像、整数高度、整数宽度、整数通道、整数灰度通道){
int col=threadIdx.x+blockIdx.x*blockDim.x;
int row=threadIdx.y+blockIdx.y*blockDim.y;
如果(行>=高度|列>=宽度)返回;
无符号字符红色=0,绿色=0,蓝色=0;
int imageposition=行*宽+列;
int grayimageposition=行*宽+列;
imageposition=imageposition*通道;
//grayimageposition=图像位置*灰色通道;
红色=图像[图像位置];
绿色=图像[imageposition+1];
蓝色=图像[imageposition+2];
灰度图像[灰度图像位置]=(uint8_t)(红色*0.3+绿色*0.59+蓝色*0.11);
//保持图像的最后一个通道与灰色通道相同
如果(通道==4){
灰度图像[grayimageposition+1]=图像[imageposition+3];
}
//灰度图像=图像;
}
int main(int argc,char*argv[]){
//图像通道的宽度高度和nbr
int宽度、高度、通道;
//处理输入图像
如果(argc!=2){
printf(“用法:./hw5'image.jpg'\n”);
出口(1);
}
//将我们的图像加载到一个1D数组中,该数组是一个线性化的2D网格,其中
//位置有一个像素RGB值。所以(x,y)。(R,G,B)
无符号字符*图像=stbi_加载(argv[1]、&宽度、高度和通道,0);
if(image==NULL){
printf(“无法加载图像。\n”);
出口(1);
}
//如果由于格式化,jpeg图像有第四个通道,请创建此通道
//在灰度图像中也是如此
国际灰色通道;
如果(通道==4){
灰色通道=2;
}否则{
灰色通道=1;
}
//定义图像矩阵的大小
int graybytes=width*height*gray\u channel*sizeof(无符号字符);
int colorbytes=width*height*channel*sizeof(无符号字符);
无符号字符*imagegray;
imagegray=(无符号字符*)malloc(灰色字节*灰色通道);
无符号字符*d_图像;
无符号字符*d_图像灰色;
Cudamaloc((void**)和d_图像,彩色字节);
Cudamaloc((void**)和d_imagegray,灰色字节);
cudaMemcpy(d_图像、图像、彩色字节、cudamemcpyhostodevice);
cudaMemcpy(d_imagegray、imagegray、graybytes、cudaMemcpyHostToDevice);
如果(!imagegray){
printf(“无法为灰度图像分配内存。\n”);
出口(1);
}
如果(!图像){
printf(“无法为灰度图像分配内存。\n”);
出口(1);
}
dim3 dimBlock(块大小,块大小);
dim3 dimGrid((宽度/dimBlock.x)+1,(高度/dimBlock.y)+1);
转换灰度(d_图像、d_图像灰度、高度、宽度、通道、灰度通道);
cudaMemcpy(图像、d_图像、colorbytes*通道、cudaMemcpyDeviceToHost);
cudaMemcpy(imagegray,d_imagegray,graybytes*通道,cudaMemcpyDeviceToHost);
cudaThreadSynchronize();
cudaGetLastError();
字符灰度名称[30]=“灰度”;
//stbi_write_jpg(字符常量*文件名,整数w,整数h,整数comp,常量void*数据,整数质量)
stbi_write_jpg(strcat(灰色名称,argv[1]),宽度,高度,灰色通道,imagegray,100);
字符颜色\u名称[30]=“颜色\u比例”;
//stbi_write_jpg(字符常量*文件名,整数w,整数h,整数comp,常量void*数据,整数质量)
stbi_write_jpg(strcat(颜色名称,argv[1]),宽度、高度、通道、图像,100);
自由(图像灰色);
stbi_无图像(图像);
cudaFree(d_图像);
cudaFree(d_imagegray);
返回0;
}
所以我的输出是一个垃圾静态。我相信我已经把这个问题归结为我如何来回传递数据。当我尝试使用
cuda memcheck
进行故障排除时,我两次出现以下错误

由于CUDAAPI调用cudaMemcpy时出现“无效参数”,程序命中CUDAERRORINVILIDVALUE(错误11)

我看不出我在做什么。我还尝试使用cudaMallocManaged,而不是手动传递数据,这给了我一个黑色方块

我看不出我在做什么

当我尝试使用
cuda memcheck
进行故障排除时,我两次出现以下错误

由于CUDAAPI调用cudaMemcpy时出现“无效参数”,程序命中CUDAERRORINVILIDVALUE(错误11)

您已为
d_image
分配了大小为
colorbytes

cudaMalloc((void**)&d_image,colorbytes);
                            ^^^^^^^^^^
但是您想从它传输一个大小为
colorbytes*channel

cudaMemcpy( image, d_image, colorbytes*channel, cudaMemcpyDeviceToHost);
                            ^^^^^^^^^^^^^^^^^^
cudaMemcpy( imagegray, d_imagegray, graybytes*channel, cudaMemcpyDeviceToHost);
                                    ^^^^^^^^^^^^^^^^^
您已经为
d_imagegray
分配了大小为
graybytes

cudaMalloc((void**)&d_imagegray, graybytes);
                                 ^^^^^^^^^
但是您想从它传输一个大小为
graybytes*的通道

cudaMemcpy( image, d_image, colorbytes*channel, cudaMemcpyDeviceToHost);
                            ^^^^^^^^^^^^^^^^^^
cudaMemcpy( imagegray, d_imagegray, graybytes*channel, cudaMemcpyDeviceToHost);
                                    ^^^^^^^^^^^^^^^^^

这两个看起来都不对。

有四个cudaMemcpy呼叫。你不能至少找出是哪一个导致了错误吗?请参阅当您使用
cudaMemcpy
将数据从设备复制回主机时(顺便说一句,我不明白您为什么要将彩色图像复制回主机,因为它没有被内核修改)字节数参数太大(我让您弄清楚——灰色图像只有一个通道)。顺便说一句,为了获得良好的性能,通常最好使用
cudaMallocPitch
进行校准。这是完全正确的。我能弄明白。我真正需要的是睡眠。谢谢你抽出时间。