2017-06-05 22 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