我在使用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")
我输入的图像是
然而,该计划的输出是
我无法理解为什么会出现这些黑线。 请帮我解决这个bug。
谢谢
好的!所以我找到了解决方案。我将所有uint8更改为int,并在numpy数组中删除了“astype(numpy.uint8)”。我不知道为什么,我只是尝试了这个并且它有效。解释为什么会有所帮助。此外,这是否意味着现在需要更多的内存? 它有效,但现在我认为它需要更多的内存。使用uint8的任何解决方法都会有所帮助。答案 0 :(得分:4)
您在Python和OpenCL中使用的数据类型之间存在不匹配。在numpy中,uint8
是一个8位无符号整数(我认为是你所追求的)。在OpenCL中,uint8
是一个32位无符号整数的8元素向量。 OpenCL中8位无符号整数的正确数据类型仅为uchar
。所以,你的astype(numpy.uint8)
很好,但是你的OpenCL内核中应该有__global const uchar*
的数组。
如果您正在处理图像,我还建议您查看OpenCL的专用图像类型,它们可以利用本机支持来处理某些硬件中可用的图像。