OpenCL 图像对象和采样器

内存对象可以用来对主机和设备之间所要传输的数据进行包装。内存对象可以分为两种类型:缓存对象和图像对象。缓存对象用来传输通用数据。理论上讲:可以将图像对象保存在缓存对象中,将它的像素作为一般的缓存数据来访问。但选择图像对象有如下四个重要的理由:

1)在GPU上,图像数据是保存在特殊的全局内存中,这个内存被称为纹理内存,和一般的全局内存不同,纹理内存是被缓存,用于高速访问处理。
(2)用来读写图像数据的函数可以在不卡吕图像数据格式的前提下,被调用,前提条件是数据格式要为OpenCL所支持。
(3)被称为采样器的特殊数据格式可以用来配置读取图像中呀白色信息的方式。
(4)OpenCL提供了这样的函数,用来返回和图像相关的信息,例如图像的大小,像素格式以及位深度。

为了在主机端检查设备是否支持图像处理,可以设置CL_DEVICE_IMAGE_SUPPORT选项,调用clGetDeviceInfo函数。如果返回值为CL_FALSE,表示设备并不支持图像处理。在内核中,如果设备能够支持图像数据的话,_IMAGE_SUPPORT_将会被设为1.如果不支持,这个宏将是未定义的。

(1)图像对象和采样器:图下对象用来保存主机应用程序和设备之间的像素数据。而在设备接受图像数据时,采样器会说明如何读取这些颜色取值。OpenCL会根据这些结构是在主机,还是在设备上的不同,而给予不同的名字。
如果是在主机上,图像对象就用cl_mem结构来表示,采样器就用cl_sampler结构来表示。而如果是在设备上,图像对象就是image2d_t或者image3d_t结构,而采样器就是sampler_t结构。

(2)主机上的图像对象:Cl_MEM:
所有的内存对象都用cl_mem数据类型来表示,没有其他的类型来区分缓存对象和图像对象。创建一个缓存对象,则需要调用clCreateBuffer函数或clCreateSubBuffer函数;而创建一个图像对象,则需要调用clCreateImage2d函数或clCreateImage3d函数。下面创建的是一个cl_image_format结构,然后用它来创建得到一个二维图像对象。图像中的每个像素点都是32位:红、蓝、绿以及alpha四个通道各占8位:

cl_image_format format;
format.image_channel_order = CL_RGBA;
format.image_channel_data_type = CL_UNSIGNED_INT8;
image = clCreateImage2D(context,CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,&format, width, height, 0, (void*)data,&err);

在创建完一个图像对象后之后,就可以将它作为内核函数的参数发送到设备上。操作过程和缓存对象一样。如果将cl_mem对象设为参数,调用clSetKernel函数,这个内核函数便可以将图像对象作为正常的参数来访问。例如,下面几行代码就将前面的图像对象声明为image_knl内核的一个参数:
clSetKernelArg(image_knl,0, sizeof(cl_mem),&image);
当不再需要图像对象之后,就会调用clReleaseMenObject函数来释放他的内存。图像对象是通过调用clReleaseMemObject(image)的方式来释放。

(3)主机上的采样器:cl_sampler:
在内核读取图像数据之前,它需要知道某些信息,例如坐标格式以及如何解释图像大小之外的坐标。它还需要知道应该如何对像素点之间的颜色进行插值处理。所有这些信息都是保存在一个名为采样器(sampler)的数据结构中。
采样器可以通过主机程序来创建,也可以在内核中创建。主机应用程序通过调用clCreateSampler函数,来创建cl_sampler对象,clCreateSampler的函数:

cl_sampler clCreateSampler(cl_context context,cl_bool normalized_coords,cl_addressing_mode addressing_mode, c_filter_mode filter_mode, cl_int*errcode_ret)

(1)normalized_cords–指明坐标是否要归一化(取值范围0.0~1.0);
(2)addressing_mode–指明内核对超出图像大小范围的坐标的处理方式;
(3)filter_mode–指明内核对像素之间颜色取值的插值处理方式。
如果在配置采样器时,属性设置出现错误,内核就会从图像中读入错误的颜色数据.

归一化的坐标和归一化的颜色:
一般而言,内核处理图像的步骤是,先从图像对象中读入颜色数据,对这些颜色取值进行操作,然后将处理结果写入到第二个颜色对象中。一个内核通过设定坐标的方式,读取给定点的颜色数据,然后按以下格式来提供这些坐标:

1)整数--坐标以整型向量的形式给出,各个维度上的索引值从0到MAX_DIM。如果图像的大小是121x81,图像中心的颜色取值所对应的坐标是(6040);
(2)浮点数--坐标以浮点型向量的形式给出,各个维度上的索引值从0.0到MAX_DIM。如果图像的大小是121x81,图像中心的颜色取值所对应的坐标是(60040.0);
(3)归一化的浮点数--坐标以float型向量形式给出,各个维度上的索引值从0.01.0.如果图像大小是121*81,图像中心的颜色取值所对应的坐标是(0.50.5),

为了将坐标读入的格式设定为归一化形式,应该将clCreateSampler函数的第二个参数设为CL_TRUE。否则,就将这个参数设为CL_FALSE。
强度是表示颜色亮度的术语,颜色的归一化不会改变颜色的显示效果。
如果像素是8位RGB分量,每个归一化的分量取值范围就是0~255.

寻址模式:
第三个参数clCreateSampler的数据类型是cl_addressing_mode.它表示的是内核读取超出图像大小之外的颜色取值的方式。例如,如果图像大小为60*80,他的像素坐标就是从(0,0)到(59,79).如果内核需要知道点(150,200)或点(-5,-10)上的颜色取值,就会需要用到寻址模式。如果寻址模式将颜色输出设为图像的边界取值,或默认边界颜色,我们就称它限制了输出颜色的范围。
cl_addressing_mode变量的五种取值如下:

1)CL_ADDRESS_NONE--超出图像范围的颜色取址未被定义。
(2)CL_ADDRESS_NONE--超出图像范围的颜色将被定义为边界颜色,默认取值为黑色;
(3)CL_ADDRESS_CLAMP_TO_EDGE--超出图像范围 的颜色将被设定为图像边界上像素的颜色;
(4)CL_ADDRESS_REPEAT--范围内的像素不断地重复,即如果一个矩阵的大小为N,超出范围的坐标X将被设为XmodN(只会出现在归一化坐标的情况下);
(5)CL_ADDRESS_MIRRORED_REPEAT--超出范围的坐标被设定为对应的范围内坐标的反射(只会出现在归一化坐标的情况下);

插值和过滤模式:
如果用整数来确定坐标,那么,你所得到的是对应某个像素点的颜色取值。如果坐标是以浮点值的格式给出,得到的就是插值后的结果。插值是计算两个已知数据点之间未知数据点的过程,这在放大和缩小图像时非常的有用。例如,用户需要放大图像,渲染器就需要知道原来图像各个像素之间的数据点信息。
OpenCL提供了两种图像插值的方法:最近邻插值法和双线插值法。clCreateSampler函数的参数filter_mode的就是用来设定需要使用的插值方法。如果将filter_mode参数设为CL_FILTER_NEAREST,采样器就会使用最近邻插值法来计算两个颜色数据之间的像素信息。如果将参数设为CL_FILTER_LINEAR,采样器会使用双线插值法来处理2D图像,用三线性插值来处理3D图像。

在主机创建完采样器后,可以调用clSetKernel函数,将这个采样器设为内核参数。他的操作过程和内存对象一样,只是最后一个指针参数指向的是cl_sampler对象,而非cl-mem对象。
和所有的clRealeaseXX函数一样,clReleaseSampler函数可以减小采样器对象的引用数。当引用数减小为0时,这个采样器对象会被释放。调用clRetainSampler函数,可以对cl_sampler进行增计数。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCL是一种基于开放标准的并行计算框架,它可以在CPU、GPU、FPGA等不同类型的处理器上运行并发程序,因此非常适合于图像处理应用。下面是一个可能的OpenCL图像处理项目实战: 1. 确定需求:首先需要明确你的图像处理需求,比如说你想实现什么样的滤镜、特效、色彩调整等等。这个需求决定了你需要实现的OpenCL内核函数。 2. 获取图像数据:从文件或者摄像头等输入设备中获取图像数据,这些数据可以是RGB格式、灰度图像格式等。 3. 创建并初始化OpenCL环境:使用OpenCL API创建并初始化OpenCL环境,包括创建OpenCL上下文、命令队列、内存对象等等。 4. 实现OpenCL内核函数:根据需求编写OpenCL内核函数,这些函数将在OpenCL设备上并行计算,通常包括对图像数据的遍历、像素值的计算等操作。 5. 将图像数据传输到OpenCL设备:将获取到的图像数据复制到OpenCL设备的内存中,以便内核函数能够访问。 6. 调用OpenCL内核函数:使用OpenCL API调用内核函数,将其提交到OpenCL设备上执行。 7. 获取计算结果:使用OpenCL API从设备内存中读取计算结果,通常是一个经过处理的图像数据。 8. 显示图像:将计算结果显示出来,可以是在窗口中显示、保存到文件中等方式。 这些步骤只是OpenCL图像处理项目实战的大致流程,具体实现还需要根据实际需求进行调整。同时,OpenCL图像处理也是一个非常庞大、复杂的领域,需要掌握一定的图像处理算法OpenCL编程技术才能实现高质量的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值