如何使用OpenCL C 1.2读取图像的特定区域?
如何用OpenCL 1.2读取图像的特定区域
嘿,其实你已经用对了工具——clEnqueueReadImage本身就支持精准读取图像的指定区域,核心就是调整你代码里的origin和region这两个参数,不用大改现有逻辑!
先给你拆解下这两个参数的作用:
origin:是你要读取区域的起始坐标,数组的三个元素对应(x, y, z)。对于2D图像来说,z分量保持0或者1就可以(因为单图层图像的z维度只有1层)。你之前写的{0,0,0}就是从图像左上角开始读。region:是你要读取区域的尺寸,三个元素对应(宽度, 高度, 层数)。你之前的{width, height, 1}就是读整个图像的所有像素。
举个实际例子
假设你想读取图像中从(x=10, y=20)这个点开始,宽度50、高度30的一块区域,只需要修改这两个数组,再调整主机端buffer的大小就行:
// 1. 定义读取区域的起始坐标和尺寸 size_t origin[3] = {10, 20, 0}; // 起始点:x=10,y=20,z=0 size_t region[3] = {50, 30, 1}; // 读取区域:宽50,高30,1层 // 2. 分配足够的主机端缓冲区:你的图像是4通道char,所以每个像素占4字节 // 注意:别像你原来代码那样用sizeof(char*),那是指针的大小,会导致缓冲区分配错误! char *buffer = malloc(50 * 30 * 4 * sizeof(char)); if (!buffer) { // 记得处理内存分配失败的情况 perror("malloc failed"); return; } // 3. 调用clEnqueueReadImage,参数基本和你原来的一致 errNum = clEnqueueReadImage(commandQueue, imageObjects[1], CL_TRUE, origin, region, 0, 0, buffer, 0, NULL, NULL);
几个需要注意的细节
- 边界检查:一定要确保
origin[0] + region[0]不超过图像实际宽度,origin[1] + region[1]不超过图像实际高度,不然OpenCL会返回CL_INVALID_VALUE错误。 - 缓冲区大小:根据你读取的区域尺寸和图像的通道数、数据类型来计算,比如你的4通道char图像,就是
区域宽 × 区域高 × 4 × sizeof(char)。 - 行间距(Pitch):如果你的图像在设备端是非连续存储的(比如设置了自定义行间距),那需要把
clEnqueueReadImage的第6个参数(row_pitch)设置为设备端图像的行字节数;如果是连续存储,传0就可以,OpenCL会自动计算。
内容的提问来源于stack exchange,提问作者Bill Kavvas
相关产品推荐
相关产品推荐

