1

我正在使用 OpenCL 进行一些线性插值,但结果不如预期。于是我做了一个简单的测试,内核代码如下所示:

const sampler_t sampler = CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR | CLK_ADDRESS_CLAMP_TO_EDGE;
// Kernel block.
kernel void interpolate(
                   global float4*input,
                   image3d_t image,
                   global float4*output)
{
    size_t i = get_global_id(0);
    float4 coord = input[i];
    float4 tap = read_imagef(image, sampler, coord);
    output[i] = tap;
}

2x2x2 图像的像素(RGBA)如下:

cl_float4 image_data[8] = {
    {0, 0, 0, 0},
    {100, 0, 0, 0},
    {0, 100, 0, 0},
    {100, 100, 0, 0},
    {0, 0, 100, 0},
    {100, 0, 100, 0},
    {0, 100, 100, 0},
    {100, 100, 100, 0},
};

我使用 11 个坐标 ((0, 0, 0), (0.1, 0.1, 0.1)...(1, 1, 1), 从 0 到 1,步骤 0.1) 来读取图像,我希望结果是 (0, 0, 0), (10, 10, 10)...(100, 100, 100),但我得到:

coordinate:0.000000, result: 0.000000
coordinate:0.100000, result: 0.000000
coordinate:0.200000, result: 0.000000
coordinate:0.300000, result: 10.156250
coordinate:0.400000, result: 30.078125
coordinate:0.500000, result: 50.000000
coordinate:0.600000, result: 69.921875
coordinate:0.700000, result: 89.843750
coordinate:0.800000, result: 100.000000
coordinate:0.900000, result: 100.000000
coordinate:1.000000, result: 100.000000

它只在坐标小于 0.25 或大于 0.75 时返回边缘值。

任何人都可以解释这一点吗?谢谢。

4

1 回答 1

2

来自:http ://www.khronos.org/registry/cl/specs/opencl-1.x-latest.pdf#page=213

“如果上述等式中选择的任何 Tijk 或 Tij 指的是图像之外的位置,则边框颜色将用作 Tijk 或 Tij 的颜色值。”

在您的情况下,低于 0.25 和高于 0.75 是从图像外部的像素值执行插值,因此它将它们钳制到边缘。因此,所有值都只是边缘值。

为什么会这样?因为边缘像素的像素中心不位于 0,而是在您的情况下位于 0.25(0 是左边缘,0.5 是右边缘)。因此,在 0 和 0.25 之间采样的值会导致像素用自身进行插值。您只需要访问从 0.25 到 0.75 的数组就可以了。如果有更多像素,您只需要再次以不同的方式访问它。以 4 像素为例,您从 0.125 (1/4/2) 开始

于 2013-11-16T12:54:14.617 回答