2012-11-18 23 views
0

我有這個簡單的OpenCL代碼塊,並且我得到了意想不到的結果。參數image是浮點數組,value是從-255到+255的數字。使用java我使用JSlider來更改value。默認值爲0,問題在於當我將滑塊移動超過0時,圖像變黑,如果將其移動到小於0,圖像變白,這種情況不應發生。這應該是單獨檢查每個像素並調整該像素。這似乎不是由於某種原因。OpenCL腳本給出意想不到的結果

這段代碼應該改變圖像的閾值。哪個是紅色綠色和藍色大於閾值的像素應該是白色的,否則應該是黑色的。

kernel void threshold(global float* image, const float value, const int max){ 
    int index = get_global_id(0); 
    if (index >= max){ 
     return; 
    } 

    int color = image[index]; 
    int red = color >> 16 & 0x0FF; 
    int green = color >> 8 & 0x0FF; 
    int blue = color & 0x0FF; 

    if(red > value && green > value && blue > value){ 
     red = 255; 
     green = 255; 
     blue = 255; 
    }else{ 
     red = 0; 
     green = 0; 
     blue = 0; 
    } 

    int rgba = 255; 
    rgba = (rgba << 8) + red; 
    rgba = (rgba << 8) + green; 
    rgba = (rgba << 8) + blue; 

    image[index] = rgba; 
} 

如果我用這個代替中間的if/else聲明:

red += value; 
if(red > 255){red = 255;} 
else if(red < 0){red = 0;} 

green += value; 
if(green > 255){green = 255;} 
else if(green < 0){green = 0;} 

blue += value; 
if(blue > 255){blue = 255;} 
else if(blue < 0){blue = 0;} 

我得到我期待的,對於操作,這本是調整圖像的亮度的結果。

我是否使用OpenCL錯?據我所知,kernel將被調用,直到返回被擊中。我使用JOCL在Java中做到這一點,這裏是我使用調用它的代碼:

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package pocketshop.graphics; 

import com.jogamp.common.nio.Buffers; 
import com.jogamp.opencl.CLBuffer; 
import com.jogamp.opencl.CLCommandQueue; 
import com.jogamp.opencl.CLContext; 
import com.jogamp.opencl.CLKernel; 
import com.jogamp.opencl.CLPlatform; 
import com.jogamp.opencl.CLProgram; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.io.InputStream; 
import java.nio.FloatBuffer; 
import pocketshop.Canvas; 
import pocketshop.dialogs.BrightnessContrastDialog; 

/** 
* 
* @author Ryan 
*/ 
public class CL { 

    protected static CLBuffer<FloatBuffer> buffer; 
    protected static float[] pixels; 

    public static CLBuffer<FloatBuffer> getBuffer() { 
     return buffer; 
    } 

    public static float[] getPixels() { 
     return pixels; 
    } 

    public static void start(String script, float val) { 

     CLPlatform platform = CLPlatform.getDefault(/*type(CPU)*/); 
     CLContext context = CLContext.create(platform.getMaxFlopsDevice()); 
     try { 
      CLProgram program = context.createProgram(getStreamFor("../scripts/" + script + ".cl")); 
      program.build(CLProgram.CompilerOptions.FAST_RELAXED_MATH); 
      assert program.isExecutable(); 

      BufferedImage image = Canvas.image; 
      assert image.getColorModel().getNumComponents() == 3; 

      pixels = image.getRaster().getPixels(0, 0, image.getWidth(), image.getHeight(), (float[]) null); 
      FloatBuffer fb = Buffers.newDirectFloatBuffer(pixels); 

      // allocate a OpenCL buffer using the direct fb as working copy 
      buffer = context.createBuffer(fb, CLBuffer.Mem.READ_WRITE); 

      // creade a command queue with benchmarking flag set 
      CLCommandQueue queue = context.getDevices()[0].createCommandQueue(CLCommandQueue.Mode.PROFILING_MODE); 

      int localWorkSize = queue.getDevice().getMaxWorkGroupSize(); // Local work size dimensions 
      int globalWorkSize = roundUp(localWorkSize, fb.capacity()); // rounded up to the nearest multiple of the localWorkSize 

      // create kernel and set function parameters 
      CLKernel kernel = program.createCLKernel(script.toLowerCase()); 
      //adjustment(val, queue, kernel, buffer, localWorkSize, globalWorkSize); 

      kernel.putArg(buffer).putArg((float) val).putArg(buffer.getNIOSize()).rewind(); 
      queue.putWriteBuffer(buffer, false); 
      queue.put1DRangeKernel(kernel, 0, globalWorkSize, localWorkSize); 
      queue.putReadBuffer(buffer, true); 

     } catch (IOException e) { 
     } 
     context.release(); 
    } 

    private static InputStream getStreamFor(String filename) { 
     return BrightnessContrastDialog.class.getResourceAsStream(filename); 
    } 

    private static int roundUp(int groupSize, int globalSize) { 
     int r = globalSize % groupSize; 
     if (r == 0) { 
      return globalSize; 
     } else { 
      return globalSize + groupSize - r; 
     } 
    } 
} 

回答

1

我發現經過多次試驗和錯誤的測試,即int color = image[index];實際上是紅,綠,或藍顏色不是的3

所以INT,

image[0] = Red; 
image[1] = Green; 
image[2] = Blue; 
image[3] = Red; 
image[4] = Green; 
image[5] = Blue; 

0

你確定你的形象是浮標陣列? 如果是的話,那麼你不應該對它進行整數操作

如果它是一個每個組件一個字節的rgba嘗試使用uchar4數據類型,也許這樣更合適,可以對所有4個組件並行執行矢量操作。

也嘗試使用opencl的鉗位功能強制執行範圍0..255

相關問題