Numpy 图像的每个像素上的PyOpenCL精简内核作为数组,而不是每个字节(RGB模式,24位)

Numpy 图像的每个像素上的PyOpenCL精简内核作为数组,而不是每个字节(RGB模式,24位),numpy,pyopencl,Numpy,Pyopencl,我试图计算RGB图像的平均值。为此,我找到每个像素的亮度,即 L(r,g,b)=X*r+Y*g+Z*b(一些线性组合)。 然后将所有像素的亮度相加,除以宽度*高度,求出平均值。 为了加快速度,我使用 我传递给它的数组是一个一维Numpy数组,因此它的工作原理与给出的示例相同 import Image import numpy as np im = Image.open('image_00000001.bmp') data = np.asarray(im).reshape(-1) # so dat

我试图计算RGB图像的平均值。为此,我找到每个像素的亮度,即

L(r,g,b)=X*r+Y*g+Z*b(一些线性组合)。

然后将所有像素的亮度相加,除以宽度*高度,求出平均值。 为了加快速度,我使用

我传递给它的数组是一个一维Numpy数组,因此它的工作原理与给出的示例相同

import Image
import numpy as np
im = Image.open('image_00000001.bmp')
data = np.asarray(im).reshape(-1) # so data is a single dimension list
# data.dtype is uint8, data.shape is (w*h*3, )
我想将示例中的以下代码合并到其中。i、 我会对数据类型和我传递的数组类型进行更改。例如:

a = pyopencl.array.arange(queue, 400, dtype=numpy.float32)
b = pyopencl.array.arange(queue, 400, dtype=numpy.float32)

krnl = ReductionKernel(ctx, numpy.float32, neutral="0",
        reduce_expr="a+b", map_expr="x[i]*y[i]",
        arguments="__global float *x, __global float *y")

my_dot_prod = krnl(a, b).get()
除此之外,“我的贴图”expr将处理每个像素,并将每个像素转换为其亮度值。 而reduce expr保持不变

问题是,它作用于阵列中的每个元素,我需要它作用于每个像素,即一次3个连续元素(RGB)


一个解决方案是有三个不同的数组,一个用于R,一个用于G,一个用于B,这样可以工作,但是还有其他方法吗

编辑:我更改了程序以说明char4的用法,而不是float4:

import numpy as np
import pyopencl as cl
import pyopencl.array as cl_array


deviceID = 0
platformID = 0
workGroup=(1,1)

N = 10
testData = np.zeros(N, dtype=cl_array.vec.char4)

dev = cl.get_platforms()[platformID].get_devices()[deviceID]

ctx = cl.Context([dev])
queue = cl.CommandQueue(ctx)
mf = cl.mem_flags
Data_In = cl.Buffer(ctx, mf.READ_WRITE, testData.nbytes)


prg = cl.Program(ctx, """

__kernel void   Pack_Cmplx( __global char4* Data_In, int  N)
{
  int gid = get_global_id(0);

  //Data_In[gid] = 1; // This would change all components to one
  Data_In[gid].x = 1;  // changing single component
  Data_In[gid].y = 2;
  Data_In[gid].z = 3;
  Data_In[gid].w = 4;
}
 """).build()

prg.Pack_Cmplx(queue, (N,1), workGroup, Data_In, np.int32(N))
cl.enqueue_copy(queue, testData, Data_In)
print testData

我希望它能有所帮助。

您可以使用矢量浮点。但是,我认为您必须使用float4,而不是使用一个元素,这就是开销。我不是100%确定,但据我所知,在某些情况下,使用向量类型比使用标量()更好。如果你愿意,我可以举个例子。当然,你也可以用三个分量来定义你自己的向量。你能举个例子吗?我的意思是,它是否像将参数更改为u global float4*x那样简单?一次自动选择4个?如果这个一维数组必须一次取3个而不是4个,是否会出现对齐问题?我在OpenGL中遇到了一些打包和解包问题,可能与此无关,但可以肯定的是..谢谢@andi,不过有点不同。在我的例子中,测试数据是一个
np.asarray(Image.open('xyz.bmp'))。重塑(-1)
。所以它本质上是一个一维的uchar值数组。如果我必须一次获取4个uchar值,在ReductionKernel部分,我必须将参数更改为
\uu global uchar4*Data\u in
。对吗?我手头没有什么要测试的,但听起来不错。您可以查看OpenCL矢量数据类型,也可以查看第200页的OpenCL。