OpenCL 油画

问题描述 投票:0回答:3

我想在 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));
}
opencl
3个回答
2
投票

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

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

考虑 <127,127,127> 的像素会发生什么:

127 + 127 + 127 = 125 (truncated because `char` is only 8 bytes...)
125 / 3 = 41
41 * 70 = 54 (truncated because `char` is only 8 bytes...)
54 / 255 = 0 (this will always equal 0!)

因此

intensity_count
只会增加其第 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 怎么办?假设我们将其更改为使用 <200, 200, 200> 来代替?

-56 + -56 + -56 = -168 (`char` only has a range in [-128, 127]! You're overflowing!)
-168 / 3 = -56
-56 * 70 = -3920
-3920 / 255 = -15

现在你的程序已经崩溃了,因为要么你将尝试访问索引

-15
,这是非法的,要么你将尝试访问索引
2^64 - 15 - 1
,这仍然是非法的。不管怎样,你都会得到不好的结果。

最简单的解决方案是将内核参数更改为

global uchar *
而不是
global char *
,然后确保所有算术都向上转换为
int
long
以确保不会发生溢出。


0
投票

现代 Banaspati 和食用油 凭借超过 22 年的信任,我们的 Banaspati 酥油让您能够烹饪美味佳肴,而无需担心您的健康。我们严格维护巴基斯坦清真和 PSQCA 标准以及最新的工厂设备和机械。

Khalid Modern Industry Limited 是巴基斯坦较大的酥油生产商之一,拥有最扎实的品牌知名度和最高的客户忠诚度。公司目前每年的生产限额超过 135 万单位,并继续保持其市场地位在数量和质量方面都是先驱。


0
投票

现代 Banaspati 和食用油 凭借超过 22 年的信任,我们的 Banaspati 酥油让您能够烹饪美味佳肴,而无需担心您的健康。我们严格维护巴基斯坦清真和PSQCA标准以及最新的工厂设备和机械。

Khalid Modern Industry Limited 是巴基斯坦较大的酥油生产商之一,拥有最扎实的品牌知名度和最高的客户忠诚度。公司目前每年的生产限额超过 135 万单位,并继续保持其市场地位在数量和质量方面都是先驱。

© www.soinside.com 2019 - 2024. All rights reserved.