2014-04-06 2 views
2

저는 PyOpenCL을 사용하여 이미지 복사본을 만드는 데 문제가있었습니다. 나는 정말로 다른 처리를하고 싶지만, 모든 픽셀에 액세스하는이 기본적인 작업을 이해할 수 없기 때문에 복사를 시도하고 싶었습니다. 오류가 발생했는지 확인하여 문제가 해결되는지 확인해주세요. 여기 PyOpenCL을 사용하여 이미지 복사

프로그램

import pyopencl as cl 
import numpy 
import Image 
import sys 

img = Image.open(sys.argv[1]) 
img_arr = numpy.asarray(img).astype(numpy.uint8) 
dim = img_arr.shape 

host_arr = img_arr.reshape(-1) 

ctx = cl.create_some_context() 
queue = cl.CommandQueue(ctx) 
mf = cl.mem_flags 
a_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=host_arr) 
dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, host_arr.nbytes) 

kernel_code = """ 
    __kernel void copyImage(__global const uint8 *a, __global uint8 *c) 
    { 
     int rowid = get_global_id(0); 
     int colid = get_global_id(1); 

     int ncols = %d; 
     int npix = %d; //number of pixels, 3 for RGB 4 for RGBA 

     int index = rowid * ncols * npix + colid * npix; 
     c[index + 0] = a[index + 0]; 
     c[index + 1] = a[index + 1]; 
     c[index + 2] = a[index + 2]; 
    } 
    """ % (dim[1], dim[2]) 

prg = cl.Program(ctx, kernel_code).build() 

prg.copyImage(queue, (dim[0], dim[1]) , None, a_buf, dest_buf) 

result = numpy.empty_like(host_arr) 
cl.enqueue_copy(queue, result, dest_buf) 

result_reshaped = result.reshape(dim) 
img2 = Image.fromarray(result_reshaped, "RGB") 
img2.save("new_image_gpu.bmp") 

입력 enter image description here

그러나이었다로 내가 준 이미지를하고, 프로그램의 출력은 enter image description here

내가 이해 할 수 아니에요했다 왜 그 검은 선들이 나타나는지. 이 버그를 해결할 수 있도록 도와주세요.

고맙습니다.

OK! 그래서 해결책을 찾았습니다. 모든 uint8을 int로 변경했고 numpy 배열에서 "astype (numpy.uint8)"을 제거했습니다. 나는 이유를 알지 못한다. 나는 단지 이것을 시도했고 효과가 있었다. 왜 도움이 될지에 대한 설명. 또한 이것은 더 많은 메모리를 필요로 할 것인가? 작동하지만, 이제는 훨씬 더 많은 메모리가 필요하다고 생각합니다. uint8을 사용하는 모든 해결 방법이 도움이됩니다.

답변

4

파이썬과 OpenCL에서 사용하는 데이터 유형이 일치하지 않습니다. numpy에서 uint8은 8 비트 부호없는 정수입니다 (사용자가 생각한 것입니다). OpenCL에서 uint8은 32 비트 부호없는 정수의 8 요소 벡터입니다. OpenCL의 8 비트 부호없는 정수에 대한 올바른 데이터 유형은 uchar입니다. 그러므로 astype(numpy.uint8)은 괜찮지 만 OpenCL 커널에 __global const uchar*의 배열이 있어야합니다.

이미지를 다루는 경우 OpenCL의 전용 이미지 유형을 살펴 보는 것이 좋습니다.이 이미지 유형은 일부 하드웨어에서 사용할 수있는 이미지를 처리하는 기본 지원을 이용할 수 있습니다.

+0

감사합니다. 지금 uchar을 변경해 주셔서 감사합니다. 전용 이미지 유형을 사용해 보았습니다. [link] (http://code.google.com/p/opencl-book-samples/source/browse/trunk/src/Chapter_20/?r=17#Chapter_20% 2FPyImageFilter2D) 그러나 그것은 나에게 약간의 문제를주고 있었다. 그래서 대신 배열을 사용하기로 결정했습니다. – algrebe

+0

지금은 더 많은 공간이 있기 때문에 GPU와 CPU 간의 메모리 복사를 줄이기 위해 더 많은 이미지를 보내기로했습니다. 그러나 비슷한 문제에 직면 해 있다고 생각합니다. 내가 한 모든 것은'int imgid = get_global_id (0); 인덱스는 imgid * nrows * ncols * npix'로 시작해야합니다. 충분하지 않아야합니까? – algrebe

+0

파이썬에서 이미지를로드 할 때 동일한 메모리 레이아웃을 생성한다고 가정하면 대략적으로 들립니다. 이미지가 매우 작지 않은 한, 이미지를 이런 방식으로 패킹함으로써 성능이 크게 향상 될 것이라고 기대하지는 않습니다. 사실 이미지 처리 중에 프로세스를 파이프 라인 전송하고 이미지 'n + 1'을 전송하는 것이 가장 좋습니다. 'n'). – jprice

관련 문제