2013-04-12 27 views
3

我遇到OpenCL圖像過濾器的問題我一直在努力工作。 我已經寫了很多這樣的(Sobel邊緣檢測,自動分割,而這樣)之前,所以我以爲我知道如何做到這一點,但下面的代碼是給我一些很奇怪的輸出:OpenCL創建錯誤的顏色

//NoRedPixels.cl 

__kernel void NoRedPixels(
    __read_only image2d_t srcImg, 
    __write_only image2d_t dstImg, 
    sampler_t sampler, 
    int width, int height, 
    int threshold, 
    int colour, 
    int fill) 
{ 
    int2 imageCoordinate = (int2)(get_global_id(0), get_global_id(1)); 

    if (imageCoordinate.x < width && imageCoordinate.y < height) 
    { 

     float4 pixel = read_imagef(srcImg, sampler, imageCoordinate); 
     float4 blue = (float4)(0.0f,0.0f,1.0f,1.0f); 

     if (1.0f - pixel.x <= 0.1f) 
      write_imagef(dstImg, imageCoordinate, blue); 
     else 
      write_imagef(dstImg, imageCoordinate, pixel); 
    } 
} 

因此,爲了測試,我想要做的是用藍色取代紅色像素,但是這個代碼將用白色取代所有匹配的像素。 據我所知,我的藍色格式是正確的RGBA格式用於創建純藍色(我之前沒有問題完成此操作)。

我使用PyOpenCL作爲我的框架,並且我已經確保將源圖像和目標圖像的圖像通道順序設置爲RGBA。另外,如果在運行內核之前還沒有使用該格式,我還一定要將源圖像轉換爲RGBA格式(使用Python Imaging Library)。

我回頭看看我編寫的其他內核,格式是相同的。我在這裏錯過什麼會導致它寫出白色像素而不是藍色像素?

+0

如果您只是讀取一個像素,將其分解爲其組件,將其重構爲float4,然後寫入它,圖像是否保持不變?如果使用(1.0f,0.0f,0.0f,1.0f)或(0.0f,1.0f,0.0f,1.0f)作爲替換像素,那麼該怎麼辦?這些行爲是否像預期的那樣? – int3h

+0

我玩弄了藍色float4的所有值,沒有任何效果。無論出於何種原因,它都不會將float4應該表示的顏色應用於目標圖像。 我試過用write_imagei代替float4和write_imagef來使用int4,它也沒有效果。 – Switch

+0

對不起,我沒有回答你問題的第一部分。我沒有嘗試手動將每個值分配給不同的float4(比如item.x = 255,item.y = 0等)。 – Switch

回答

4

好吧,所以我想我已經明白了。出於某種原因,OpenCL不那麼熱衷於讓我們按照自己的方式編輯頻道。我最終通過簡單地添加或減去等價的float4向量來獲得我想要的結果向量來解決它。所以

__kernel void NoRedPixels(__read_only image2d_t srcImg, __write_only image2d_t dstImg, 
sampler_t sampler, int width, int height, int threshold, int colour, int fill) 
{ 
    int2 imageCoordinate = (int2) (get_global_id(0), get_global_id(1)); 
    if (imageCoordinate.x < width && imageCoordinate.y < height) 
    { 
     float4 pix = read_imagef(srcImg, sampler, (int2)(imageCoordinate.x, imageCoordinate.y)); 

     //Full red channel, subtract this from original to remove red! 
     float4 red = (float4)(1.0f, 0.0f, 0.0f, 0.0f); 
     float4 blue = (float4)(0.0f, 0.0f, 1.0f, 0.0f); 

    if (pix.x >= 0.9f && pix.y <= 0.1f && pix.z <= 0.1f) //If red, then replace with blue. 
    { 
     const float4 outColor = pix - red + blue; 
     write_imagef(dstImg, imageCoordinate, outColor); 
    } 
    else 
     write_imagef(dstImg, imageCoordinate, pix); 

    } 
} 

在這種情況下,通過創建矢量來表示藍色和紅色(不透明度)中減去紅色,再加入藍,我獲得所得載體我想要的。就我個人而言,我不知道爲什麼我必須這樣做,但我很高興我知道OpenCL期望我現在做什麼。希望如果別人有這個問題,他們會在這裏找到它。