cudaMemcpy将rgb发布为灰度

  • 本文关键字:灰度 rgb cudaMemcpy cuda
  • 更新时间 :
  • 英文 :


尝试创建一个简单的RGB到灰度的项目。对不起,奇怪的图书馆,我的教授拒绝更新我们学校的服务器,我的家用电脑也没有英伟达卡。

#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;
}

所以我的输出是垃圾静态的。我相信我已经把这个问题归结为我如何来回传递数据。当我尝试使用cuda-memcheck进行故障排除时,我会两次出现以下错误。

程序命中cudaErrorInvalidValue(错误11(,原因是";无效参数";对cudaMemcpy的CUDA API调用。

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

我看不出我做错了什么。

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

由于";无效参数";对cudaMemcpy的CUDA API调用。

您已经为d_image:分配了colorbytes的大小

cudaMalloc((void**)&d_image,colorbytes);
^^^^^^^^^^

但您想从中转移colorbytes*channel的大小吗?

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

您已经为d_imagegray:分配了graybytes的大小

cudaMalloc((void**)&d_imagegray, graybytes);
^^^^^^^^^

但是你想从中转移graybytes*channel的大小吗?

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

这两个看起来都不对。

最新更新