我正在尝试解决我应该将彩色图像更改为灰度图像的问题。为此我使用CUDA并行方法。
我在GPU上调用的kerne代码如下。
__global__
void rgba_to_greyscale(const uchar4* const rgbaImage,
unsigned char* const greyImage,
int numRows, int numCols)
{
int absolute_image_position_x = blockIdx.x;
int absolute_image_position_y = blockIdx.y;
if ( absolute_image_position_x >= numCols ||
absolute_image_position_y >= numRows )
{
return;
}
uchar4 rgba = rgbaImage[absolute_image_position_x + absolute_image_position_y];
float channelSum = .299f * rgba.x + .587f * rgba.y + .114f * rgba.z;
greyImage[absolute_image_position_x + absolute_image_position_y] = channelSum;
}
void your_rgba_to_greyscale(const uchar4 * const h_rgbaImage,
uchar4 * const d_rgbaImage,
unsigned char* const d_greyImage,
size_t numRows,
size_t numCols)
{
//You must fill in the correct sizes for the blockSize and gridSize
//currently only one block with one thread is being launched
const dim3 blockSize(numCols/32, numCols/32 , 1); //TODO
const dim3 gridSize(numRows/12, numRows/12 , 1); //TODO
rgba_to_greyscale<<<gridSize, blockSize>>>(d_rgbaImage,
d_greyImage,
numRows,
numCols);
cudaDeviceSynchronize(); checkCudaErrors(cudaGetLastError());
}
我在第一个像素行中看到一行点。
我得到的错误是
libdc1394错误:无法初始化libdc1394
位置51的差异超过5的容差
参考:255
GPU:0
my input/output images
谁能帮我这个???提前谢谢。
答案 0 :(得分:5)
现在,因为我发布了这个问题,所以我一直在努力解决这个问题。为了使这个问题正确,我应该做一些改进,现在我意识到我的初步解决方案是错误的。 />要做的更改: -
1. absolute_position_x =(blockIdx.x * blockDim.x) + threadIdx.x;
2. absolute_position_y = (blockIdx.y * blockDim.y) + threadIdx.y;
其次,
1. const dim3 blockSize(24, 24, 1);
2. const dim3 gridSize((numCols/16), (numRows/16) , 1);
在解决方案中,我们使用的是numCols / 16 * numCols / 16的网格 和24 * 24的块大小
代码以0.040576 ms执行
@datenwolf:谢谢你回答上面的问题!!!
答案 1 :(得分:5)
我最近加入了这个课程并尝试了你的解决方案,但它不起作用,我尝试了自己的。你几乎是对的。正确的解决方案是:
__global__`
void rgba_to_greyscale(const uchar4* const rgbaImage,
unsigned char* const greyImage,
int numRows, int numCols)
{`
int pos_x = (blockIdx.x * blockDim.x) + threadIdx.x;
int pos_y = (blockIdx.y * blockDim.y) + threadIdx.y;
if(pos_x >= numCols || pos_y >= numRows)
return;
uchar4 rgba = rgbaImage[pos_x + pos_y * numCols];
greyImage[pos_x + pos_y * numCols] = (.299f * rgba.x + .587f * rgba.y + .114f * rgba.z);
}
其余部分与您的代码相同。
答案 2 :(得分:2)
由于您不了解图像尺寸。最好选择二维螺纹块的任何合理尺寸,然后检查两个条件。第一个是内核中的pos_x
和pos_y
索引不超过numRows
和numCols
。其次,网格大小应该高于所有块中的线程总数。
const dim3 blockSize(16, 16, 1);
const dim3 gridSize((numCols%16) ? numCols/16+1 : numCols/16,
(numRows%16) ? numRows/16+1 : numRows/16, 1);
答案 3 :(得分:1)
libdc1394错误:无法初始化libdc1394
我不认为这是一个CUDA问题。 libdc1394是一个用于访问IEEE1394又名FireWire又名iLink视频设备(DV摄像机,Apple iSight摄像机)的库。该库没有正确初始化,因此您没有获得有用的结果。基本上它是NINO:Nonsens In Nonsens Out。
答案 4 :(得分:1)
绝对x&amp;的计算y图像位置是完美的。 但是当你需要访问彩色图像中的特定像素时,你不应该使用下面的代码吗?
uchar4 rgba = rgbaImage[absolute_image_position_x + (absolute_image_position_y * numCols)];
我这么认为,将它与你编写的代码进行比较,以便在串行代码中执行相同的问题。 请让我知道:))
答案 5 :(得分:1)
您仍然应该遇到运行时问题 - 转换无法提供正确的结果。
行:
应更改为:
答案 6 :(得分:1)
__global__
void rgba_to_greyscale(const uchar4* const rgbaImage,
unsigned char* const greyImage,
int numRows, int numCols)
{
int rgba_x = blockIdx.x * blockDim.x + threadIdx.x;
int rgba_y = blockIdx.y * blockDim.y + threadIdx.y;
int pixel_pos = rgba_x+rgba_y*numCols;
uchar4 rgba = rgbaImage[pixel_pos];
unsigned char gray = (unsigned char)(0.299f * rgba.x + 0.587f * rgba.y + 0.114f * rgba.z);
greyImage[pixel_pos] = gray;
}
void your_rgba_to_greyscale(const uchar4 * const h_rgbaImage, uchar4 * const d_rgbaImage,
unsigned char* const d_greyImage, size_t numRows, size_t numCols)
{
//You must fill in the correct sizes for the blockSize and gridSize
//currently only one block with one thread is being launched
const dim3 blockSize(24, 24, 1); //TODO
const dim3 gridSize( numCols/24+1, numRows/24+1, 1); //TODO
rgba_to_greyscale<<<gridSize, blockSize>>>(d_rgbaImage, d_greyImage, numRows, numCols);
cudaDeviceSynchronize(); checkCudaErrors(cudaGetLastError());
}
答案 7 :(得分:1)
在这种情况下,libdc1394错误与firewire等无关 - 它是udacity用于比较程序创建的图像与参考图像的库。而且说的是,你的图像和参考图像之间的差异已超过特定阈值,即该位置即。像素。
答案 8 :(得分:0)
您正在运行以下数量的块和网格:
const dim3 blockSize(numCols/32, numCols/32 , 1); //TODO
const dim3 gridSize(numRows/12, numRows/12 , 1); //TODO
但你没有在你的内核代码中使用任何线程!
int absolute_image_position_x = blockIdx.x;
int absolute_image_position_y = blockIdx.y;
这样想,图像的宽度可以划分为列的absolute_image_position_x
部分,图像的高度可以划分为行的absolute_image_position_y
部分。现在,它创建的每个横截面的框都需要根据greyImage平行地更改/重绘所有像素。足够的作品扰乱:)
答案 9 :(得分:0)
能够处理非标准输入尺寸图像的相同代码
int idx=blockDim.x*blockIdx.x+threadIdx.x;
int idy=blockDim.y*blockIdx.y+threadIdx.y;
uchar4 rgbcell=rgbaImage[idx*numCols+idy];
greyImage[idx*numCols+idy]=0.299*rgbcell.x+0.587*rgbcell.y+0.114*rgbcell.z;
}
void your_rgba_to_greyscale(const uchar4 * const h_rgbaImage, uchar4 * const d_rgbaImage,
unsigned char* const d_greyImage, size_t numRows, size_t numCols)
{
//You must fill in the correct sizes for the blockSize and gridSize
//currently only one block with one thread is being launched
int totalpixels=numRows*numCols;
int factors[]={2,4,8,16,24,32};
vector<int> numbers(factors,factors+sizeof(factors)/sizeof(int));
int factor=1;
while(!numbers.empty())
{
if(totalpixels%numbers.back()==0)
{
factor=numbers.back();
break;
}
else
{
numbers.pop_back();
}
}
const dim3 blockSize(factor, factor, 1); //TODO
const dim3 gridSize(numRows/factor+1, numCols/factor+1,1); //TODO
rgba_to_greyscale<<<gridSize, blockSize>>>(d_rgbaImage, d_greyImage, numRows, numCols);
答案 10 :(得分:0)
1- int y = (blockIdx.y * blockDim.y) + threadIdx.y;
2- const dim3 blockSize(32, 32, 1);
以网格和块大小
1- const dim3 gridSize((numCols/32+1), (numRows/32+1) , 1);
2- Id Name Marks
1 A 34
2 b 35
代码以0.036992 ms执行。
答案 11 :(得分:0)
const dim3 blockSize(16, 16, 1); //TODO
const dim3 gridSize( (numRows+15)/16, (numCols+15)/16, 1); //TODO
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
uchar4 rgba = rgbaImage[y*numRows + x];
float channelSum = .299f * rgba.x + .587f * rgba.y + .114f * rgba.z;
greyImage[y*numRows + x] = channelSum;