3

我一直在尝试使用 OpenCL 图像过滤器时遇到问题。我以前写过很多这些(Sobel Edge Detection、Auto Segmentation 等),所以我以为我知道该怎么做,但是下面的代码给了我一些非常奇怪的输出:

//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 图像库),如果它在运行内核之前还不是那种格式的话。

我回去看了看我写的其他内核,格式是一样的。我在这里缺少什么会导致它写出白色像素而不是蓝色像素?

4

1 回答 1

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 期望我做什么。希望如果其他人遇到这个问题,他们会在这里找到这个。

于 2013-04-16T16:16:37.607 回答