2017-06-05 26 views
-1

我想要实现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); 
    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)); 
} 
+0

你真的应该使用内置的图像对象('image2d_t'想到的),没有这些结构在那里你每一个频道进行手动拆分成它自己的缓冲区。 – Xirema

+0

@Xirema有可能这是他的源数据的格式。 –

回答

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,这是非法的,或者你要尝试访问索引​​,这是会仍然非法。无论哪种方式,你都会得到不好的结果。

最简单的解决办法是改变你的内核参数global uchar *而不是global char *,然后确保任何和所有的算术向上强制转换为intlong确保溢出不会发生。

+0

感谢您answer.It部分提高了我的代码,并帮助我理解是什么话不对仍有一些像素的输出不见了,但我会解决它。 – Epidemic