内容简介:虽然对于图像也可以把它的像素数据当做一般的缓存数据来处理,但是如果把它当做图像来处理有如下好处:图像相关应用主要涉及两个数据类型,即cl_mem clCreateImage2D()
使用图像对象的理由
虽然对于图像也可以把它的像素数据当做一般的缓存数据来处理,但是如果把它当做图像来处理有如下好处:
- 在GPU中,图像数据是保存在特殊的全局内存中,即 纹理内存 ,它和一般的全局内存不相同,它是被缓存的,用于高速访问处理。GPU中有专门 支持图像读写的硬件,使用内置读写函数可以充分发挥这个优势 。
- 只要OpenCL支持该图像格式,那么就可以不用考虑图像格式的前提下使用读写图像数据的函数
- 可以使用 采样器 来配置读取图像中数据的的方式
- OpenCL提供函数来获取图像相关信息,比如宽度等
主机与内核的命名
图像相关应用主要涉及两个数据类型,即 图像对象 和 采样器 。图像对线用来保存主机和设备上的图像对象,而采样器则在设备接收数据时,说明如何读取这些颜色值
图像对象 | 采样器 | |
---|---|---|
主机 | cl_mem (和一般缓存对象一样) | cl_sampler |
设备 | image2d_t或者image3d_t | sampler_t |
主机编程的主要接口
创建图像对象
cl_mem clCreateImage2D()
cl_mem clCreateImage3D()
图像格式
cl_image_format
创建采样器
cl_sampler clCreateSampler()
设备上的接口
图像数据
由于很多设备都是将图像对象保存在特定的内存中,因此image2d_t以及image3d_t数据的前面通常会有read_only或者write_only等修饰符。 图像不能即可写又可读 。
图像数据作为内核的参数时,和普通的缓存对象不同,它不是指针参数,因为图像数据并不希望直接通过内存操作来访问数据。
采样器
根据khronos官网的说明,采样器其实就是一个uint类型(可以直接给内置cl读写函数传递标识位的组合来替代sampler_t,例如: float4 clr = read_imagef(img, CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, (float2)(x, y));
),通过bit-mode来说明 坐标模式,超出边界的处理模式以及插值模式
。在官方的sample中采用的是constant申明的模式,虽然也说了可以采用global声明,但这也许说明constant更好。
可以通过设置参数 clSetKernelArg
的方式来给内核传递采样器。但是 更为方便
的方式是在cl文件中,在内核函数之前创建一个sampler_t对象,如下case:
__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE |
CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;
__kernel void simple_image(read_only image2d_t src_image,
write_only image2d_t dst_image) {
/* Compute value to be subtracted from each pixel */
uint offset = get_global_id(1) * 0x4000 + get_global_id(0) * 0x1000;
/* Read pixel value */
int2 coord = (int2)(get_global_id(0), get_global_id(1));
uint4 pixel = read_imageui(src_image, sampler, coord);
/* Subtract offset from pixel */
pixel.x -= offset;
/* Write new pixel value to output */
write_imageui(dst_image, coord, pixel);
}
内置图像函数
OpenCL的内置图像相关的函数主要包括三类:read_imageT读取类,write_imageT写入类以及get_image_X读取图像信息类。其中T表示数据类型,比如f,i,ui等,而X表示width,dim等图像信息
read_image
- read_image函数返回的都是四分量的数据,如果实际图片没有四个通道的数据,那么那些不含有的的通道对应的分量会被置为0,具体请看 官网
-
很多时候都会看到代码中用
float4 read_imagef()
去读图像数据为int或者uint类型的image,可能你会困惑 为什么整形要用float去读 ?这是因为,这些图片在创建的时候就是以正则NORM化的数据类型,这个类型在cl_image_format
的image_channel_data_type
中指定。以int8为例,image_channel_data_type
可取的值如下表: 参考
image_channel_data_type 参数 | 含义 | read_image |
---|---|---|
CL_SNORM_INT8 | 每个通道都是 正则化 的 有 符号8位整数 | 使用read_imagef读取,返回的float4的每个分量的取值范围为[ 0.0 , 1.0] |
CL_UNORM_INT8 | 每个通道都是 正则化 的 无 符号8位整数 | 使用read_imagef读取,返回的float4的每个分量的取值范围为[ -1.0 , 1.0] |
CL_SIGNED_INT8 | 每个通道都是8位 有符号 的整数 | 使用read_imagei读取,返回int4 |
CL_USIGNED_INT8 | 每个通道都是8位 无符号 的整数 | 使用read_imageui读取,返回unsigned int4 |
- 使用 read_imagei 和 read_imageui 时,采样器的 filter_mode 必须设置为 CLK_FILTER_NEAREST
- 使用 read_imagef 时,如果坐标是整数,那么 filte_mode 必须设置为 CLK_FILTER_NEAREST
- 使用 read_imageX 时, X 表示**,如果坐标是整数,那么采样器的坐标正则化必须设置为 CLK_NORMALIZED_COORDS_FALSE ,且 address mode 必须设置为 CLK_ADDRESS_CLAMP_TO_EDGE, CLK_ADDRESS_CLAMP 或者 CLK_ADDRESS_NONE
Linux公社的RSS地址: https://www.linuxidc.com/rssFeed.aspx
本文永久更新链接地址: https://www.linuxidc.com/Linux/2018-09/154274.htm
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Opencv图像处理系列(六)—— 图像梯度
- Opencv图像处理系列(九)—— 图像轮廓
- Python 图像处理 OpenCV (15):图像轮廓
- Opencv图像处理系列(三)——图像二值化
- Opencv图像处理系列(八)—— 图像金字塔
- Facebook 开源图像处理库 Spectrum,优化移动端图像生成
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
图论算法理论、实现及应用
王桂平//王衍//任嘉辰 / 北京大学 / 2011-1 / 54.00元
《图论算法理论、实现及应用》系统地介绍了图论算法理论,并选取经典的ACM/ICPC竞赛题目为例题阐述图论算法思想,侧重于图论算法的程序实现及应用。《图论算法理论、实现及应用》第1章介绍图的基本概念和图的两种存储表示方法:邻接矩阵和邻接表,第2~9章分别讨论图的遍历与活动网络问题,树与图的生成树,最短路径问题,可行遍性问题,网络流问题,支配集、覆盖集、独立集与匹配,图的连通性问题,平面图及图的着色问......一起来看看 《图论算法理论、实现及应用》 这本书的介绍吧!