2012-11-18 5 views
0

이 간단한 블록 OpenCL 코드가 있는데 예상치 못한 결과가 나타납니다. 매개 변수 image은 부동 소수점 배열이고 value은 -255에서 +255 사이의 숫자입니다. 자바를 사용하여 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을 사용하고 있습니다 : int color = image[index]; 실제로 빨간색 녹색 또는 푸른 색이 아니라을이다

/* 
* 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
나는 많은 시행 착오 시험 후에 발견

, 그래서 3

의 INT,

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

0

확실 이미지가 수레의 배열입니다입니까? 그렇다면 integer 조작을하지 말아야합니다.

구성 요소 당 1 바이트의 rgba 인 경우 uchar4 데이터 형식을 사용하려고합니다. 더 적합 할 수도 있습니다. 병렬로 4 개 구성 요소 모두에 대해 벡터 연산을 수행 할 수 있습니다 .

또한 범위를 시행하기 위해 opencl의 클램프 기능을 사용하려고 시도합니다. 0..255

관련 문제