我遇到了OpenCL图像过滤器的问题,我一直在努力工作。 我以前写了很多这些(Sobel边缘检测,自动分割等),所以我想到我知道怎么做,但是下面的代码给了我一些非常奇怪的输出:< / p>
//NoRedPixels.cl
__kernel void NoRedPixels(
__read_only image2d_t srcImg,
__write_only image2d_t dstImg,
sampler_t sampler,
int width, int height,
int threshold,
int colour,
int fill)
{
int2 imageCoordinate = (int2)(get_global_id(0), get_global_id(1));
if (imageCoordinate.x < width && imageCoordinate.y < height)
{
float4 pixel = read_imagef(srcImg, sampler, imageCoordinate);
float4 blue = (float4)(0.0f,0.0f,1.0f,1.0f);
if (1.0f - pixel.x <= 0.1f)
write_imagef(dstImg, imageCoordinate, blue);
else
write_imagef(dstImg, imageCoordinate, pixel);
}
}
因此,对于测试,我想要做的就是用蓝色像素替换红色像素,但是此代码将用白色像素替换所有匹配的像素。 据我所知,我的蓝色格式是正确的RGBA格式,用于创建纯蓝色(我以前做过这个没有问题)。
我正在使用PyOpenCL作为我的框架,我确保将源图像和目标图像的图像通道顺序设置为RGBA。此外,我还确保将源图像转换为RGBA格式(使用Python Imaging Library),如果它在运行内核之前尚未采用该格式。
我已经回去看了我写过的其他内核,格式是一样的。我在这里错过了什么会导致它写出白色像素而不是蓝色像素?
答案 0 :(得分:4)
好的,所以我想我已经弄明白了。出于某种原因,OpenCL不太热衷于让你按照我想要的方式编辑频道。我最后通过简单地添加或减去等效的float4向量来解决它,以获得我想要的结果向量。
__kernel void NoRedPixels(__read_only image2d_t srcImg, __write_only image2d_t dstImg,
sampler_t sampler, int width, int height, int threshold, int colour, int fill)
{
int2 imageCoordinate = (int2) (get_global_id(0), get_global_id(1));
if (imageCoordinate.x < width && imageCoordinate.y < height)
{
float4 pix = read_imagef(srcImg, sampler, (int2)(imageCoordinate.x, imageCoordinate.y));
//Full red channel, subtract this from original to remove red!
float4 red = (float4)(1.0f, 0.0f, 0.0f, 0.0f);
float4 blue = (float4)(0.0f, 0.0f, 1.0f, 0.0f);
if (pix.x >= 0.9f && pix.y <= 0.1f && pix.z <= 0.1f) //If red, then replace with blue.
{
const float4 outColor = pix - red + blue;
write_imagef(dstImg, imageCoordinate, outColor);
}
else
write_imagef(dstImg, imageCoordinate, pix);
}
}
所以在这种情况下,通过创建表示蓝色和红色(没有透明度)的矢量减去红色,然后添加蓝色,我获得了我想要的结果矢量。就个人而言,我不确定为什么我必须这样做,但我很高兴我知道OpenCL希望我做什么,现在。希望如果其他人遇到这个问题,他们会在这里找到。