OpenCL有任何位图概念吗?

时间:2013-08-07 21:35:25

标签: opencl

我正在学习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对象,然后一旦拥有该对象,就可以随心所欲地执行任何操作用它?

2 个答案:

答案 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,那么您可以使用libjpegPNG同样libpng,依此类推。这些库都是开源的,这就是整个生态系统的结合方式。

这也可能就是为什么本书提供了一个简单的例程来读写一小部分BMP原始格式的原因。 (位图可以有多种颜色深度,RLE压缩等)。所以请记住,书籍例程只能处理BMP的一个特定“子格式”。我在实际场景中建议PNG,因为RAW数据可能占用惊人的巨大空间,这会降低性能(当然,压缩运行时本身也需要权衡)。 关于本书例程的另一件事:它是根据OpenCL内核需求量身定制的,它提供了浮点数组,它只有一个通道(format.image_channel_order = CL_R;)。您通常会从图像库中收到整数RGB颜色通道组件。但将其转换为浮动并不重要(除非您有大量数据)。