我正在使用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时,它只返回边缘值。
有人可以解释一下吗?感谢。
答案 0 :(得分: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)
开始