与Int相比,Opencl Sobel滤波器实现在Float中被淘汰

时间:2015-05-10 21:02:59

标签: int opencl edges sobel

我正在研究3x3垂直索贝尔滤波器的两种实现方式。其中一种是浮点计算,另一种是长期计算。出于某种原因,浮动版本的边缘在输出中显示出明显的褪色。我知道会有一些精确的差异,但似乎是一个三角洲的方式。

这是长版:

__kernel void sobel(read_only image2d_t inputImage, write_only image2d_t outputImage)
{
    const sampler_t sampler=CLK_NORMALIZED_COORDS_FALSE|CLK_ADDRESS_CLAMP_TO_EDGE|CLK_FILTER_LINEAR;
    int i = get_global_id(0);
    int j = get_global_id(1);
    int accumWeights = 0;
    uint4 pixel_orig=read_imageui(inputImage,sampler,(int2)(i,j));
    long4 pixel_orig_long=convert_long4(pixel_orig);
    long4 pixel_new = (long4)(0, 0, 0, 255);
    long4 pixel0 = convert_long4(read_imageui(inputImage,sampler,(int2)(i+1,j+0)));
    long4 pixel1 = convert_long4(read_imageui(inputImage,sampler,(int2)(i+1,j+1)));
    long4 pixel2 = convert_long4(read_imageui(inputImage,sampler,(int2)(i+1,j-1)));
    long4 pixel3 = convert_long4(read_imageui(inputImage,sampler,(int2)(i-1,j+0)));
    long4 pixel4 = convert_long4(read_imageui(inputImage,sampler,(int2)(i-1,j+1)));
    long4 pixel5 = convert_long4(read_imageui(inputImage,sampler,(int2)(i-1,j-1)));
    pixel_new += (pixel0)*2; 
    pixel_new += (pixel1)*1; 
    pixel_new += (pixel2)*1; 
    pixel_new -= (pixel3)*2; 
    pixel_new -= (pixel4)*1; 
    pixel_new -= (pixel5)*1; 
    if (pixel_new.x<0) pixel_new.x = 0-pixel_new.x; ;
    if (pixel_new.y<0) pixel_new.y = 0-pixel_new.y; ;
    if (pixel_new.z<0) pixel_new.z = 0-pixel_new.z; ;
    pixel_new.w = 255;
    write_imageui(outputImage,(int2)(i,j), convert_uint4(pixel_new));
};

这是浮动版:

__kernel void sobel(read_only image2d_t inputImage, write_only image2d_t outputImage)
{
    const sampler_t sampler=CLK_NORMALIZED_COORDS_FALSE|CLK_ADDRESS_CLAMP_TO_EDGE|CLK_FILTER_LINEAR;
    int i = get_global_id(0);
    int j = get_global_id(1);
    float4 pixel_orig=read_imagef(inputImage,sampler,(int2)(i,j));
    float4 pixel_new = (float4)(0, 0, 0, 255);
    float4 pixel0 = read_imagef(inputImage,sampler,(int2)(i+1,j+0));
    float4 pixel1 = read_imagef(inputImage,sampler,(int2)(i+1,j+1));
    float4 pixel2 = read_imagef(inputImage,sampler,(int2)(i+1,j-1));
    float4 pixel3 = read_imagef(inputImage,sampler,(int2)(i-1,j+0));
    float4 pixel4 = read_imagef(inputImage,sampler,(int2)(i-1,j+1));
    float4 pixel5 = read_imagef(inputImage,sampler,(int2)(i-1,j-1));
    pixel_new += (pixel0)*2;
    pixel_new += (pixel1)*1;
    pixel_new += (pixel2)*1;
    pixel_new -= (pixel3)*2;
    pixel_new -= (pixel4)*1;
    pixel_new -= (pixel5)*1;
    pixel_new = fabs(pixel_new);
    pixel_new.w = 255;
    write_imagef(outputImage,(int2)(i,j), pixel_new);
};

没有足够的声誉来发布图像,但使用Lenna作为测试,边缘的白度在浮动版本中明显被清除。似乎无法弄清楚为什么。

1 个答案:

答案 0 :(得分:0)

有几件事: 1)您正在使用CLK_FILTER_LINEAR,但OpenCL规范说“采用整数坐标的read_imagef调用必须使用过滤器模式设置为CLK_FILTER_NEAREST的采样器”。 2)你正在使用read_imagef期望0-255,但它返回normalize 0.0-1.0值。