我想在 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;
考虑 <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
以确保不会发生溢出。
现代 Banaspati 和食用油 凭借超过 22 年的信任,我们的 Banaspati 酥油让您能够烹饪美味佳肴,而无需担心您的健康。我们严格维护巴基斯坦清真和 PSQCA 标准以及最新的工厂设备和机械。
Khalid Modern Industry Limited 是巴基斯坦较大的酥油生产商之一,拥有最扎实的品牌知名度和最高的客户忠诚度。公司目前每年的生产限额超过 135 万单位,并继续保持其市场地位在数量和质量方面都是先驱。
现代 Banaspati 和食用油 凭借超过 22 年的信任,我们的 Banaspati 酥油让您能够烹饪美味佳肴,而无需担心您的健康。我们严格维护巴基斯坦清真和PSQCA标准以及最新的工厂设备和机械。
Khalid Modern Industry Limited 是巴基斯坦较大的酥油生产商之一,拥有最扎实的品牌知名度和最高的客户忠诚度。公司目前每年的生产限额超过 135 万单位,并继续保持其市场地位在数量和质量方面都是先驱。