首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pyopencl内核输出黑色图像

pyopencl内核输出黑色图像
EN

Stack Overflow用户
提问于 2022-02-19 01:02:19
回答 1查看 66关注 0票数 1

为什么图像保存后会变成黑色?我才刚开始学习opencl。在没有opencl的情况下,在纯CPU上,循环遍历矩阵并使用rgb2gray平均值公式将值存储在灰色数组中。使用windows和python 3.8

代码语言:javascript
复制
import pyopencl
import numpy as np
import imread
import matplotlib.pyplot as plt

ocl_platforms = (platform.name for platform in pyopencl.get_platforms())
print("\n".join(ocl_platforms))
# select platform
platform = pyopencl.get_platforms()[0]
# select device
device = platform.get_devices()[0]

# create context
ctx = pyopencl.Context(devices=[device])

img = imread.imread('gigapixel.jpg')

r = np.array(img[:, :, 0], dtype=np.float32)

g = np.array(img[:, :, 1], dtype=np.float32)

b = np.array(img[:, :, 2], dtype=np.float32)
gray = np.empty_like(r)
# without gpu
for i in range(r.shape[0]):
    for j in range(r.shape[1]):
        gray[i, j] = (r[i, j] + g[i, j] + b[i, j]) / 3
plt.imshow(gray)
plt.show()
# convert to uint8
gray = np.uint8(gray)
# save image
imread.imsave('gray_cpu.jpg', gray)

对于GPU,剩下的代码是

代码语言:javascript
复制
gray = np.empty_like(r)
program_source = """
__kernel void rgb2gray(__global float *r, __global float *g, __global float *b, __global 
float *gray) {
int i = get_global_id(0);
int j = get_global_id(1);
gray[i, j] = (r[i, j] + g[i, j] + b[i, j])/ 3;
}
"""
gpu_program_source = pyopencl.Program(ctx, program_source)
gpu_program = gpu_program_source.build()
program_kernel_names = gpu_program.get_info(pyopencl.program_info.KERNEL_NAMES)
print(program_kernel_names)

queue = pyopencl.CommandQueue(ctx)

r_buf = pyopencl.Buffer(ctx, pyopencl.mem_flags.READ_ONLY |             
pyopencl.mem_flags.COPY_HOST_PTR, hostbuf=r)
g_buf = pyopencl.Buffer(ctx, pyopencl.mem_flags.READ_ONLY | 
pyopencl.mem_flags.COPY_HOST_PTR, hostbuf=g)
b_buf = pyopencl.Buffer(ctx, pyopencl.mem_flags.READ_ONLY |     
pyopencl.mem_flags.COPY_HOST_PTR, hostbuf=b)
gray_buf = pyopencl.Buffer(ctx, pyopencl.mem_flags.WRITE_ONLY, r.nbytes)

gpu_program.rgb2gray(queue, r.shape, None, r_buf, g_buf, b_buf, gray_buf)

pyopencl.enqueue_copy(queue, gray, gray_buf)


plt.imshow(gray)
plt.show()

gray = np.uint8(gray)

imread.imsave('gigapixel_gray.jpg', gray)
EN

回答 1

Stack Overflow用户

发布于 2022-02-19 08:32:53

如果您需要保留array[x,y]表示法,那么尝试Numba而不是PyOpenCL。Numba将Python函数的字节码转换为OpenCL内核。

PyOpenCL只是OpenCL API上的一个包装器,因此它直接编译C语言或C++语言的给定内核代码。所以你需要像这样索引:

代码语言:javascript
复制
int i = get_global_id(0);
int j = get_global_id(1);
gray[i][j] = (r[i][j] + g[i][j] + b[i][j])/ 3;

如果希望看到在任何阶段产生的错误(内核编译、缓冲区复制等),则需要捕获PyOpenCL的异常,因为将OpenCL-错误绑定到Python。你应该这样检查他们:

代码语言:javascript
复制
try:
  your_opencl_accelerated_function()
except:
  print("Something didn't work") 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71181493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档