我正在学习OpenCL中的内存缓冲区和图像。根据我的理解,OpenCL中的图像只是一个抽象的数据结构,与照片般的图像没有任何关系(x,y,r,g,b或x,y,h,s,l,a或者......等等。
在本书中,我正在阅读他们提供function来读取硬盘上的.bmp文件并将其转换为浮点数组
然后他们将float数组写入cl_mem变量:
// GET THE .BMP AS A FLOAT[]
float* inputImage = readImage(inputFile, &imageWidth, &imageHeight);
// DEFINE THE IMAGE AND FORMAT
cl_image_desc desc;
desc.image_type = CL_MEM_OBJECT_IMAGE2D;
desc.image_width = imageWidth;
desc.image_height = imageHeight;
desc.image_depth = 0;
desc.image_array_size = 0;
desc.image_row_pitch = 0;
desc.image_slice_pitch = 0;
desc.num_mip_levels = 0;
desc.num_samples = 0;
desc.buffer = NULL;
cl_image_format format;
format.image_channel_order = CL_R;
format.image_channel_data_type = CL_FLOAT;
// DEFINE AND WRITE THE IMAGE
cl_mem d_inputImage = clCreateImage(context, CL_MEM_READ_ONLY, &format, &desc, NULL, NULL);
ize_t origin[3] = { 0, 0, 0 };
size_t region[3] = { imageWidth, imageHeight, 1 };
clEnqueueWriteImage(queue, d_inputImage, CL_FALSE, origin, region, 0, 0, inputImage, 0, NULL, NULL);
那么是否告诉OpenCL我们正在处理类似照片的图像,或者我们只是定义数据结构?在本书的内核中,他们使用:
// sourceImage is d_inputImage from the previous block of code. its type is image2d_t
float4 pixel;
pixel = read_imagef(sourceImage, sampler, coords);
sum.x += pixel.x * filter[filterIdx++];
OpenCL是否只是松散地将这些数据结构用作类似照片的图像,或者它是否与.NET类似,您可以从许多不同的源创建一个Bitmap对象,然后一旦拥有该对象,就可以随心所欲地执行任何操作用它?
答案 0 :(得分:2)
OpenCL是否有任何位图概念?
当然; cl_image_desc
类型(及其cl_image_format
)表示图像(或位图)。如果将代码示例中设置的属性或字段与Bitmap
类的属性进行比较,您会发现它们几乎相同,可能只有轻微的命名差异:
真正的区别在于OpenCL只关注内存中的图像,并快速有效地处理这些图像。 OpenCL不关心I / O,文件格式,编解码器等。
那么是否告诉OpenCL我们正在处理类似照片的图像,或者我们只是定义数据结构?
是。 cl_image_desc
完整地描述了如何解释内存中的图像数据。这对应于处理内核处理此数据的方式(例如,灰度或单通道图像,RGBA等)。您可以将类似照片的图像视为内存中的二进制数据blob,它具有所有这些额外的元数据,可以将其视为类似照片的图像。所以它在某种意义上是一个简单缓冲区(或cl_buffer
)的超集。
OpenCL是否只是松散地将这些数据结构用作类似照片的图像,或者它是否与.NET类似,您可以从许多不同的源创建一个Bitmap对象,然后一旦拥有该对象,就可以随心所欲地执行任何操作用它?
OpenCL的范围是为跨平台API中的高性能异构(即CPU和GPU)数据处理提供框架。它不是试图成为像.NET这样的整个平台,它还提供文件I / O,图形渲染等等。 OpenCL的想法是它适合您已经使用的任何平台代码。您可以使用平台代码(.NET,Cocoa,libjpeg或其他)将文件加载到内存中,从您正在使用的磁盘表示和编解码器进行解码。然后,您可以将此数据传递给OpenCL,通过这些结构对其进行描述,以进行处理。
如此有效地,一旦它们在内存中,您就可以从这些相同的源中创建OpenCL图像。运行完处理内核后,可以将数据从OpenCL结构中取出,并将结果传递给其余代码,并使用平台API将结果呈现为屏幕或将其保存为编码文件。 / p>
答案 1 :(得分:1)
是和否:
OpenCL是否有任何位图概念?
不,作为实际的位图(c)(R)(tm)图像文件格式,但它在内存中具有位图(图像)的一般抽象/概念。后者与前者不一样!文件格式是一个简单的RIFF资源容器,而后者是一般概念。
它是否与.NET类似,您可以从许多不同的源创建一个Bitmap对象
没有。您不能简单地读取或写入各种文件格式。
OpenCL是否只是松散地将这些数据结构用作类似照片的图像
是的(有点,多一点)。
OpenCL
确实了解内存中的RAW图像格式,但支持不包括PNG,JPG或其他实际文件格式。 OpenCL
并未将图像文件格式的全部内容支持为.NET Class Library
。 (但这是正确的,因为它根本不是OpenCL
的目标或角色。OpenCL
和.NET
在这方面无法比较,它们是完全不同的动物。)
.NET可以读写许多不同的文件格式。 OpenCL
一旦在内存中,就可以处理各种 RAW格式(不同的RGB顺序和位深度)。但是,您的任务是找到如何从/向实际文件读取/写入RAW数据的方式:OpenCL不支持JPG,PNG,GIF或其他压缩文件格式。例如,如果您想要读/写JPEG
,那么您可以使用libjpeg,PNG
同样libpng,依此类推。这些库都是开源的,这就是整个生态系统的结合方式。
这也可能就是为什么本书提供了一个简单的例程来读写一小部分BMP
原始格式的原因。 (位图可以有多种颜色深度,RLE
压缩等)。所以请记住,书籍例程只能处理BMP
的一个特定“子格式”。我在实际场景中建议PNG
,因为RAW数据可能占用惊人的巨大空间,这会降低性能(当然,压缩运行时本身也需要权衡)。
关于本书例程的另一件事:它是根据OpenCL
内核需求量身定制的,它提供了浮点数组,它只有一个通道(format.image_channel_order = CL_R;
)。您通常会从图像库中收到整数RGB
颜色通道组件。但将其转换为浮动并不重要(除非您有大量数据)。