【问题标题】:Does OpenCL have any concept of a bitmap?OpenCL 有位图的概念吗?
【发布时间】:2013-08-08 07:32:06
【问题描述】:

我正在学习 OpenCL 中的内存缓冲区和图像。据我了解,OpenCL 中的图像只是一种抽象数据结构,与类似照片的图像(x、y、r、g、b 或 x、y、h、s、l、a , 或者...随便)。

在我正在阅读的这本书中,他们提供了一个function 从硬盘读取 .bmp 文件并将其转换为浮点数组

然后他们将浮点数组写入 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 的方式使用,您可以从许多不同的来源创建位图对象,然后一旦有了该对象,您就可以做任何您想做的事情有吗?

【问题讨论】:

    标签: opencl


    【解决方案1】:

    OpenCL 有位图的概念吗?

    当然; cl_image_desc 类型(连同它的cl_image_format)代表一个图像(或位图)。如果您将代码示例中设置的属性或字段与Bitmap 类的属性进行比较,您会发现它们几乎相同,可能只是命名略有不同:

    真正的区别在于 OpenCL 只关心内存中的图像,并快速有效地处理这些图像。 OpenCL 本身不关心 I/O、文件格式、编解码器等。

    那么这是否告诉 OpenCL 我们正在处理类似照片的图像,或者我们只是在定义一个数据结构?

    是的。 cl_image_desc 完整描述了如何解释内存中的图像数据。这对应于您的处理内核处理此数据的方式(例如灰度或单通道图像、RGBA 等)。您可以将类似照片的图像视为内存中的二进制数据块,其中包含所有这些额外的元数据,可以将其理解为类似照片的图像。所以它在某种意义上是一个简单缓冲区(或cl_buffer)的超集。

    OpenCL 是否只是将这些数据结构松散地用作类似照片的图像,还是以任何类似于 .NET 的方式使用,您可以从许多不同的来源创建位图对象,然后一旦有了该对象,您就可以做任何您想做的事情有吗?

    OpenCL 的范围是为跨平台 API 中的数据的高性能异构(即 CPU 和 GPU)处理提供框架。它并不是想成为一个像 .NET 那样的完整平台,它还提供文件 I/O、图形渲染等。 OpenCL 的想法是它适合您已经使用的任何平台代码。您使用您的平台代码(.NET、Cocoa、libjpeg 或其他)将文件加载到内存中,从您碰巧使用的任何磁盘表示和编解码器进行解码。然后你可以把这些数据传递给OpenCL,通过这些结构来描述,进行处理。

    一旦它们在内存中,您就可以从任何这些相同的源中有效地创建 OpenCL 图像。运行完处理内核后,您可以从 OpenCL 结构中取出数据并将结果传递给其余代码,并使用平台 API 将结果呈现给屏幕或将它们保存为编码文件。

    【讨论】:

      【解决方案2】:

      是与否:

      OpenCL 有位图的概念吗?

      不,作为实际的位图 (c)(R)(tm) 图像文件格式,但它具有内存中位图(图像)的一般抽象/概念。后者与前者不一样!文件格式是一个简单的RIFF资源容器,而后者是一个笼统的概念。

      它是否与 .NET 类似,您可以从许多不同的来源创建位图对象

      没有。您不能简单地读取或写入各种文件格式。

      OpenCL 是否只是松散地将这些数据结构用作类似照片的图像

      是的(有点,多一点)。

      OpenCL 确实知道内存中的 RAW 图像格式,但不支持 PNG、JPG 或其他实际文件格式。 OpenCL 没有像 .NET Class Library 那样全面覆盖图像文件格式支持。 (但这是正确的,因为这根本不是OpenCL 的目标或角色。OpenCL.NET 在这方面没有可比性,它们是完全不同的动物。)

      .NET 可以读取和写入许多不同的文件格式。 OpenCL 可以处理各种 RAW 格式(不同的 RGB 顺序和位深度),一旦它们在内存中。但您的任务是找到如何从/向实际文件读取/写入 RAW 数据的方法:OpenCL 不支持 JPG、PNG、GIF 或其他开箱即用的压缩和文件格式。例如,如果你想读/写JPEG,那么你可以使用libjpeg,类似地libpngPNG,等等。这些库都是开源的,这就是整个生态系统的结合方式。

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

      【讨论】:

      • 感谢两位的帮助(对不起,我只能标记一个作为答案)。最后一件事。这个说法正确吗? inputImage(在这种情况下,灰度图像变成了一个浮点数组,因此每个像素 1 个浮点数)可能看起来像 {255、255、250、248、250...等}。我使用 CL_R 格式使用 clEnqueueWriteImage 将其写入 cl_mem。然后我用 read_imagef 读取内核上的像素,它返回一个 float4(4 元素向量)。因为这是一个单通道图像,所以存储的像素值存储在 x 坐标中(由 read_imagef 返回的 float4)。
      • @user1873073 你是对的。如果是CL_R,请参阅khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/…(r, 0.0, 0.0, 1.0)float4。
      猜你喜欢
      • 2015-01-04
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 2022-07-27
      • 2022-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多