OpenCL 图像处理函数、图像放缩和插值

1.OpenCL提供了大量可以在内核中运行的图像处理函数,它们大致可以分为以下三类:

1)Read functiongs--返回给定坐标上的颜色取值;
(2)write functiongs-- 设定给定坐标上的颜色取值;
(3)Information functions-- 提供关于图像对象的信息,例如图像的维度以及像素属性;

图像读取函数是从图像对象中读取向量,他们各自的参数基本一样。唯一的区别是函数返回的是浮点数向量还是整数向量,读取的是二维图像对象还是三维图像对象。
读取图像数据的内核函数:

1.float4 read_imagef(image2d_t img,sampler_t sampler, int2/float2 coord)--以float4型向量的形式读取二维图像在coord位置的颜色数据;
2.int4 read_imagei(image2d_t img,sampler_t sampler, int2/float2 coord)--以int4型向量的形式读取二维图像在coord位置的颜色数据;
3.uint4 read_imagui(image2d_t img,sampler_t sampler, int2/float2 coord)--以uint4型向量的形式读取二维图像在coord位置的颜色数据;
4.float4 read_imagef(image3d_t img,sampler_t sampler, int4/float4 coord)--以float4型向量的形式读取三维图像在coord位置的颜色数据;
5.int4 read_imagei(image3d_t img,sampler_t sampler, int4/float4 coord)--以int4型向量的形式读取三维图像在coord位置的颜色数据;
6.uint4 read_imagui(image3d_t img,sampler_t sampler, int4/float4 coord)--以uint4型向量的形式读取三维图像在coord位置的颜色数据;

如果图像对象是一个image2d_t类型,坐标的格式就必须是int2型或float2型。
如果图像对象是一个image3d_t类型,坐标的格式就必须是int4型或float4型。
你想从名为image的二维图像对象中读取坐标为(3,4)的颜色数据。如果希望颜色取值是float4型向量,函数调用为:
float4 color = read_imagef(image, sampler, (int2)(3,4));
read_imagef函数的返回值范围由image格式来确定。如果像素是无符号归一化格式(CL_UNORM_INT8,CL_UNORM_INT16,CL_UNORM_INT101010,CLUNORM_SHORT565,或CL_UNORM_SHORT555),函数的返回值就必须在0.0和1.0之间。如果像素是有符号归一化格式(CL_SNORM_INT8或CL_SNORM_INT16),read_imagef函数的返回值就必须在-0.5和0.5之间。如果像素的格式是CL_HALF_FLOAT或CL_FLOAT,函数的返回值将是正常的浮点数。
read_image函数返回的颜色向量:(通道顺序 向量存储(整数))

CL_R,CL_Rx --(R, 0, 0, 1)
CL_A--(0, 0, 0, A)
CL_RG,CL_RGx--(R, G, 0 ,1)
CL_RA--(R, 0, 0, A)
CL_RGB, CL_RGBx--(R, G, B, 1)
CL_RGBA,CL_BGRA, CL_ARGB--(R,G,B,A)
CL_INTENSITY--(I, I, I, I)
CL_LUMINANCE--(L, L, L, 1)

表中的数字全部都是整数,但如果向量是read_imagef函数的返回值,它的分量就是浮点数。如果,图像对象的像素都是CL_RG格式,read_imagef函数所返回的向量将是[R, G, 0.0, 1.0],其中R和G分别表示的是像素的红色和绿色分量。
将数据写入图像对象的内核函数:

1.void write_imagef(image2d_t img, int2 coord, float4 color)--将float4型颜色数据写到二维图像中coord所指定的位置。
2.void write_imagei(image2d_t img, int2 coord, int4 color)--将int4型颜色数据写到二维图像中coord所指定的位置。
3.void write_imageui(image2d_t img, int2 coord, uint4 color)--将uint4型颜色数据写到二维图像中coord所指定的位置。
4.void write_imagef(image3d_t img, int4 coord, float4 color)--将float4型颜色数据写到三维图像中coord所指定的位置。
5.void write_imagei(image3d_t img, int4 coord, int4 color)--将int4型颜色数据写到三维图像中coord所指定的位置。
6.void write_imageui(image3d_t img, int4 coord,uint4 color)--将uint4型颜色数据写到三维图像中coord所指定的位置。

默认情况下,并不支持将数据写入到三维图像对象中。这个功能需要通过cl_khr_3d_image_writes扩展来实现,因此,如果想要修改image3d_t对象中的数据,需要在内核中加入下面一行代码,确认是否能有这个扩展:
#pragma OPENCL EXTENSION cl_khr_3d_image_writes: enable
为了设定代写的颜色数据。例如,如果像素的RGB分量 是[132,15,44], 你可以将像素数据写到CL_RGB型图像对象img中:
write_imageui(img, coord, (uint4)(132,15,44,0));
图像信息函数
获取推向信息的内核函数:

(1)int get_image_width(image2d_t/image3d_t image)--返回图像的宽度;
(2)int get_image_height(image2d_t/image3d_t image)--返回图像的高度;
(3)int get_image_depth(image3d_t image)--返回图像的深度;
(4)int2 get_image_dim(image2d_t image)--以int2型向量的形式,返回二维图像的宽度和高度;
(5)int4 get_image_dim(image3d_t image)--以int4型向量的形式,返回三维图像的宽度、高度和深度;
(6)int get_image_channel_data_type(mage2d_t/image3d_t image)--返回图像的通道数据类型(CLK_UNORM_INT8,CLK_SIGNED_INT32.等)
(7)int get_image_channel_order(image2d_t/image3d_t image)--返回图像的通道(CLK_A,CLK_RGB,CLK_INTENSITY等)

注意内核并不接受采样器作为它的参数。所以,程序在内核函数之前,创建了以一个sampler_t型的sampler对象。

图像放缩和插值:
图像的放大是很重要的问题,因为涉及到的是增加像素信息,而不是溢出已有的像素。如果NN的像素放大k倍,得到的图像是kNkN大小的图像。现在重要的问题是:如何获取放大后的图像中那(k的平方减一)N的平方个像素的颜色取值。
一种方法是重复原始图像中的某些像素。称为最近邻插值法。但是如果需要绘制穿过像素中心点的直线,并用这些直线来近似已知像素点之间的各点,这种方法也被称为双线插值法,这种方法所需的工作量大,但相应的,产生的结果也更好。如果配置正确,采样器可以告诉内核自动选择最近邻插值法(CL_FILTER_NEAREST),还是双线性插值法(CLK_FILTER_LINEAR).
注意:像素插值法只有在图像的坐标是浮点数的前提下才能完成,如果图像的坐标是整数,得到的插值法结果将完全和其中某个像素的颜色一样。

最近邻插值(CL_FILTER_NEAREST):
如果相对于其他的像素点,待处理的点更靠近像素A,那么,那个点上的采样颜色就会被设为像素A的颜色。这种方法可以用来放大图像,处理得到的图像只包含原来图像的颜色。如果图像被放大k倍,图像上的每个点都会重复k次。
最近邻插值法的运行速度很快,因为它并不需要任何的数学计算。但如果用它来放大图像,得到的结果会看起来粒状化和像素点化(grainy和pixelated).放大后的图像有一个问题,就是像素点取址之间的突变。即使是灰度图像,也能明显地看到汽车像素点之间颜色的非连续变化。

双线性插值法CLK_FILTER_LINEAR):
如果一个点是在矩形图像的两个已有像素之间时,它采样的颜色将被设为两个像素颜色的线性组合:

1)使用CLK_FILTER_LINEAR的前提是坐标必须是浮点数;
(2)只有read_imagef函数有这个选项。如果将采样器设为CLK_FILTER_LINEAR,调用read_imageuior read_imagei函数,结果将是未定义的。
(3)有些OpenCL兼容设备并不支持双线性插值。如果是那样的话,就需要通过硬件模拟的方式来插值。

小结:
OpenCL标准定义了大量和图像相关的数据类型和函数。如果一个内核处理图像,它会将图像数据作为图像对象(image2d_t型对象或image3d_t型对象)来读入。为了从图像对象中读取数据,内核需要一个sampler_t型对象。这个对象可以用来控制内核读取坐标,插值运算的方式。
OpenCL的图像处理函数可以分为三类:从图像对象中读取数据的函数,将数据写入到图像对象的函数,以及访问和图像有关的信息(例如图像的大小,以及像素属性)的函数。读函数需要采样器对象,而坐标可以按整数或浮点数的形式给出。然而,写函数却要求的是整数坐标。此外,三维图像不能直接写入到图像对象中,除非设备支持cl_khr_3d_image_writer扩展。
可以对采样器进行配置,设置相邻像素之间颜色数据的插值方式,这也让采样器在图像处理中扮演了一个颇为重要的角色。OpenCL提供了两种插值方法:最近邻插值法CLK_FILTER_NEAREST以及双线性插值法CLK_FILTER_LINEAR.当用最邻近插值法来放缩图像时,它会在原始图像中重复像素信息。这种方法的又是是运行速度快,但如果采用双线性插值法,能取得更好的插值效果。双线性插值法通过使用直线连接两个像素的中心,然后来计算相邻像素之间的颜色取值。但是,这种插值方法只适用于坐标和颜色取值都是浮点数的情况。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
图像的灰度化、二值化、滤波、边缘检测、直方图,视频的边缘检测和跟踪 OpenCV(Open Source Computer Vision Library)是一款开源的计算机视觉库,专门为图像和视频处理任务设计,广泛应用于学术研究、工业应用以及个人项目中。以下是关于OpenCV的详细介绍: 历史与发展 起源:OpenCV于1999年由英特尔公司发起,旨在促进计算机视觉技术的普及和商业化应用。该项目旨在创建一个易于使用、高效且跨平台的库,为开发者提供实现计算机视觉算法所需的基础工具。 社区与支持:随着时间的推移,OpenCV吸引了全球众多开发者和研究人员的参与,形成了活跃的社区。目前,OpenCV由非盈利组织OpenCV.org维护,并得到了全球开发者、研究机构以及企业的持续贡献和支持。 主要特点 跨平台:OpenCV支持多种操作系统,包括但不限于Windows、Linux、macOS、Android和iOS,确保代码能够在不同平台上无缝运行。 丰富的功能:库中包含了数千个优化过的函数,涵盖了计算机视觉领域的诸多方面,如图像处理(滤波、形态学操作、色彩空间转换等)、特征检测与描述(如SIFT、SURF、ORB等)、物体识别与检测(如Haar级联分类器、HOG、DNN等)、视频分析、相机校正、立体视觉、机器学习(SVM、KNN、决策树等)、深度学习(基于TensorFlow、PyTorch后端的模型加载与部署)等。 高效性能:OpenCV代码经过高度优化,能够利用多核CPU、GPU以及特定硬件加速(如Intel IPP、OpenCL等),实现高速图像处理和实时计算机视觉应用。 多语言支持:尽管OpenCV主要使用C++编写,但它提供了丰富的API绑定,支持包括C、Python、Java、MATLAB、JavaScript等多种编程语言,方便不同领域的开发者使用。 开源与免费:OpenCV遵循BSD开源许可证发布,用户可以免费下载、使用、修改和分发库及其源代码,无需担心版权问题。 架构与核心模块 OpenCV的架构围绕核心模块构建,这些模块提供了不同层次的功能: Core:包含基本的数据结构(如cv::Mat用于图像存储和操作)、基本的图像和矩阵操作、数学函数、文件I/O等底层功能。 ImgProc:提供图像预处理、滤波、几何变换、形态学操作、直方图计算、轮廓发现与分析等图像处理功能。 HighGui:提供图形用户界面(GUI)支持,如图像和视频的显示、用户交互(如鼠标事件处理)以及简单的窗口管理。 VideoIO:负责视频的读写操作,支持多种视频格式和捕获设备。 Objdetect:包含预训练的对象检测模型(如Haar级联分类器用于人脸检测)。 Features2D:提供特征点检测(如SIFT、ORB)与描述符计算、特征匹配与对应关系估计等功能。 Calib3d:用于相机标定、立体视觉、多视图几何等问题。 ML:包含传统机器学习算法,如支持向量机(SVM)、K近邻(KNN)、决策树等。 DNN:深度神经网络模块,支持导入和运行预训练的深度学习模型,如卷积神经网络(CNN)。
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编程技术才能实现高质量的应用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值