我正在研究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作为测试,边缘的白度在浮动版本中明显被清除。似乎无法弄清楚为什么。
答案 0 :(得分:0)
有几件事: 1)您正在使用CLK_FILTER_LINEAR,但OpenCL规范说“采用整数坐标的read_imagef调用必须使用过滤器模式设置为CLK_FILTER_NEAREST的采样器”。 2)你正在使用read_imagef期望0-255,但它返回normalize 0.0-1.0值。