在CUDA中倾斜图像

时间:2012-03-27 07:21:00

标签: c image cuda

我正在尝试将图像倾斜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)。任何帮助将不胜感激

3 个答案:

答案 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.fcostheta=1.f调用内核即可。

答案 2 :(得分:0)

如果您只是想将图像倾斜90度,那么您将不需要任何三角函数,因为您可以在通过像素交互时简单地交换x和y轴:

Destination[x+y*width]=tex2D(Source_texture, tx+0.5f,ty+0.5f); 

应该这样做。