我有下面的代码示例,我试图理解它:

    __global__ void
d_boxfilter_rgba_x(unsigned int *od, int w, int h, int r)
    {
    float scale = 1.0f / (float)((r << 1) + 1);
    unsigned int y = blockIdx.x*blockDim.x + threadIdx.x;

    if (y < h)
        {
        float4 t = make_float4(0.0f);

        for (int x = -r; x <= r; x++)
            {
            t += tex2D(rgbaTex, x, y);
            }

        od[y * w] = rgbaFloatToInt(t * scale);

        for (int x = 1; x < w; x++)
            {
            t += tex2D(rgbaTex, x + r, y);
            t -= tex2D(rgbaTex, x - r - 1, y);
            od[y * w + x] = rgbaFloatToInt(t * scale);
            }
        }
    }

__global__ void
d_boxfilter_rgba_y(unsigned int *id, unsigned int *od, int w, int h, int r)
    {
    unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
    id = &id[x];
    od = &od[x];

    float scale = 1.0f / (float)((r << 1) + 1);

    float4 t;
    // partea din stanga
    t = rgbaIntToFloat(id[0]) * r;

    for (int y = 0; y < (r + 1); y++)
        {
        t += rgbaIntToFloat(id[y*w]);
        }

    od[0] = rgbaFloatToInt(t * scale);

    for (int y = 1; y < (r + 1); y++)
        {
        t += rgbaIntToFloat(id[(y + r) * w]);
        t -= rgbaIntToFloat(id[0]);
        od[y * w] = rgbaFloatToInt(t * scale);
        }

    // main loop
    for (int y = (r + 1); y < (h - r); y++)
        {
        t += rgbaIntToFloat(id[(y + r) * w]);
        t -= rgbaIntToFloat(id[((y - r) * w) - w]);
        od[y * w] = rgbaFloatToInt(t * scale);
        }

    // right side
    for (int y = h - r; y < h; y++)
        {
        t += rgbaIntToFloat(id[(h - 1) * w]);
        t -= rgbaIntToFloat(id[((y - r) * w) - w]);
        od[y * w] = rgbaFloatToInt(t * scale);
        }
    }


这应该是带有CUDA的盒式过滤器。
从我所读的内容中可以得出给定半径的平均值。
但是在d_boxfilter_rgba_y中进行如下操作:

od[0] = rgbaFloatToInt(t * scale);


我不明白为什么要使用这种音阶,为什么当只有一个音阶时要进行所有循环。要计算从-r到+ r的值并将其除以多个像素。

有人可以帮我吗?

最佳答案

要计算半径为1(3个值)的盒子的平均值,请执行以下操作:

(box[0] + box[1] + box[2]) / 3 // which is equal to
(box[0] + box[1] + box[2] * 1/3 // which is equal to your scale factor


规模的计算是:

1.0f / (float)((r << 1) + 1); // equal to
1 / ((r * 2) + 1) // equal to
1 / (2r + 1) // 2r because you go to the left and right and +1 for the middle


使用两个for循环,因为使用了“滑动窗口”优化。首先计算第一个框:

for (int x = -r; x <= r; x++)
{
    t += tex2D(rgbaTex, x, y);
}


然后,对于右边的每个步骤,都将添加框右侧的值,并删除框最左侧的值。这样,您可以只用2个运算而不是2*r + 1个运算来计算框的总和。

for (int x = 1; x < w; x++)
{
    t += tex2D(rgbaTex, x + r, y);
    t -= tex2D(rgbaTex, x - r - 1, y);
    od[y * w + x] = rgbaFloatToInt(t * scale);
    }
}

关于c++ - CUDA盒式过滤器如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44926716/

10-11 19:03