OpenCL油画

OpenCL油画,opencl,Opencl,我想在OpenCL中实现油画过滤器,但是输出图像总是黑色的,我不知道为什么。 以下是内核代码: __kernel void oil_painting(__global const char* R,__global const char* G,__global const char* B, __global char* r,__global char* g,__global char* b) { int i=get_global_id(0); in

我想在OpenCL中实现油画过滤器,但是输出图像总是黑色的,我不知道为什么。 以下是内核代码:

__kernel void oil_painting(__global const char* R,__global const char* G,__global const char* B,
                 __global char* r,__global char* g,__global char* b)
{
    int i=get_global_id(0);
    int j=get_global_id(1);
    int i1,j1,k;

    int avgR[256],avgG[256],avgB[256],intensity_count[256];
    int max_pixels=0,max_intensity=0,current_intensity;

    for (i1=0;i1<4;i1++) {
        for (j1=0;j1<4;j1++) {
            current_intensity=(((R[(i+i1)*512+j+j1]+
                                 G[(i+i1)*512+j+j1]+
                                 B[(i+i1)*512+j+j1])/3)*70)/255;
            intensity_count[current_intensity]++;

            if (intensity_count[current_intensity]>max_pixels) {
                max_pixels=intensity_count[current_intensity];
                max_intensity=current_intensity;
            }

            avgR[current_intensity]+=R[(i+i1)*512+j+j1];
            avgG[current_intensity]+=G[(i+i1)*512+j+j1];
            avgB[current_intensity]+=B[(i+i1)*512+j+j1];
        }
    }

    r[i*512+j]=min(255,max(0,avgR[max_intensity]/max_pixels));
    g[i*512+j]=min(255,max(0,avgG[max_intensity]/max_pixels));
    b[i*512+j]=min(255,max(0,avgB[max_intensity]/max_pixels));
}

下面这样的代码片段会给您带来很多麻烦:

current_intensity=(((R[(i+i1)*512+j+j1]+
                     G[(i+i1)*512+j+j1]+
                     B[(i+i1)*512+j+j1])/3)*70)/255;
考虑以下像素的情况:

因此,强度u计数只会增加其第0个索引,而不会增加其他任何内容

将所有内容强制转换为int可能会解决此问题

current_intensity=((((int)R[(i+i1)*512+j+j1]+
                     (int)G[(i+i1)*512+j+j1]+
                     (int)B[(i+i1)*512+j+j1])/3)*70)/255;
新产出:

127 + 127 + 127 = 381
381 / 3 = 127
127 * 70 = 8890
8890 / 255 = 34
但现在有一个新问题:如果值高于127怎么办?假设我们将其改为使用

现在你的程序崩溃了,因为要么你试图访问索引-15,这是非法的,要么你试图访问索引2^64-15-1,这仍然是非法的。不管怎样,你都会得到糟糕的结果


最简单的解决方案是将内核参数改为全局uchar*,而不是全局char*,然后确保所有算法都向上转换为int或long,以确保不会发生溢出。

您应该真正使用内置的图像对象image2d\t,不是您手动将每个通道拆分为其自己的缓冲区的这些构造。@Xirema可能是他的源数据的格式。谢谢您的回答。它部分改进了我的代码并帮助我理解了错误所在。输出中仍然缺少一些像素,但我会修复它。
127 + 127 + 127 = 381
381 / 3 = 127
127 * 70 = 8890
8890 / 255 = 34
-56 + -56 + -56 = -168 (`char` only has a range in [-128, 127]! You're overflowing!)
-168 / 3 = -56
-56 * 70 = -3920
-3920 / 255 = -15