我正在尝试将图像倾斜90度,目前我正在按照此处介绍的方法进行操作: http://www.scribd.com/doc/66589491/Image-Rotation-Using-CUDA
我目前的内核代码是:
__global__ void kernCuda(float *Source,float * Destination, int width)
{
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
int i = abs(x*cosf(theta)-y*sinf(theta));
int j = abs(x*sinf(theta)+y*cosf(theta));
if(x<width && y<width){
Destination[j*width+i]=Source[y*width+x];
}
}
图像稍微倾斜,但看起来不正确,有些像素的颜色现在是黑色(0)。任何帮助将不胜感激
答案 0 :(得分:2)
我假设theta是一个浮点数。所以你要混合浮点和整数变量。我建议你使用适当的演员表来使它工作并寻找四舍五入的问题。
其次,为了查看您的计划是否有效,您可以将cosf(theta)
替换为0,将sinf(theta)
替换为1.
我可以看到的第三个问题是你只使用一个x,y值而不是通过使用while循环来循环它们。因此,如果您的图像尺寸大于您使用的内核,则无法获得所有像素。
编辑:我只是简要介绍了一下这个报告。这真的不是很好。如果你想了解CUDA我建议你得到一本名为“CUDA by example”的书。
答案 1 :(得分:1)
明显的问题是整数截断/插值问题。
一种方法是将源图像绑定到纹理,然后使用计算的实值坐标从纹理中读取。 CUDA纹理为您提供“免费”,基于硬件的插值/过滤。纹理的主要缺点是插值仅限于8位内部精度,因此在某些情况下可能不够准确。但作为第一次尝试,尝试类似:
__global__ void kernCuda(float * Destination, const float sintheta, const float costheta,
const int width)
{
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
float tx = float(x)*costheta-float(y)*sintheta;
float ty = float(x)*sintheta+float(y)*costheta;
if(x<width && y<width){
Destination[x*width+y]=tex2D(Source_texture, tx+0.5f,ty+0.5f);
}
}
(注意未经测试,从未接近编译器,使用风险自负)。
此处Source_texture
是您将源数据绑定到的纹理。您可以在纹理设置中设置旋转的边缘行为,具体取决于您希望如何处理它。如何在CUDA 4.1编程指南的第3.2.10.1节中设置和绑定纹理。
另请注意,旋转矩阵中的余弦和正弦对于给定的θ值是常量,因此将它们作为参数传递给内核会更有效,而不是让每个线程计算相同的值。对于您所询问的90度旋转,只需使用sintheta=0.f
和costheta=1.f
调用内核即可。
答案 2 :(得分:0)
如果您只是想将图像倾斜90度,那么您将不需要任何三角函数,因为您可以在通过像素交互时简单地交换x和y轴:
Destination[x+y*width]=tex2D(Source_texture, tx+0.5f,ty+0.5f);
应该这样做。