应用
我们所看到的屏幕上显示的文字,其实是Window调度“画”字程序,从硬盘里读出字体,然后画到屏幕上来,这就显示出了我们看到的文字。无加速时期,绘图工作全部由CPU完成。CPU在完成图形的生产、变换、着色等操作后,将处理后的图形数据从存储设备中一行一行地复制到显示终端控制器,由显示终端控制其显示。由于进行图形处理的数据量较大,需要占用CPU的大部分性能去处理这些图形,因此造成PC机系统性能的低下。
图像硬件加速是指将计算量较大的图像处理工作分配给专门的硬件外设来处理,减轻CPU的计算量,以此提高图像绘制的性能。
当前项目的具体应用与需求是?
演变历史
图形加速分几个阶段:2D图像加速,Windows加速和3D图像加速。
常用的加速方法:图形2d,3d加速简介 - ArcherDev - 博客园 (cnblogs.com)
2D加速,CPU工作流程:1、找到窗口在显存中的地址;2、给显卡发送“copy这一行到目的地”;3、重复2直到copy完所有的行。其中第二步就是2D加速的工作。
硬件3D加速,3D渲染将会使用显卡上的图形处理器来进行,而不会占用宝贵的CPU资源来绘制3D图像。在没有硬件3D加速的情况下,CPU自身会被强制使用Mesa软件渲染函数库来进行贴图处理,这会用相当多的CPU资源。3D硬件加速在游戏、3D CAD/CAM、影视动画制作和建模等需要渲染3D对象的场合下非常有价值。
2D硬件加速feature
2D图形加速引擎:
2D图形加速引擎(GE2D)_2d加速_Wayne-Woo的博客-CSDN博客
- 支持RAW/RGB/YUV?
- 支持移动/绘制
- 支持剪切
- 支持图像缩放(缩放范围?)
- 支持X/Y轴镜像
- 支持不同程度旋转
原理
- 图像平移
- 镜像算子
- X轴(水平)镜像
需要将一块内存中的像素,水平镜像写入另一块内存
例如:图像高度H和宽度W,假设A像素坐标为(src_x0,src_y0),对应src内存中的地址为:
src_addr = src_y0 * W + src_x0
分析前后的坐标变化规律:dst_X = src_x0;dst_Y = (H-1) - src_y0; 对应dst内存中地址为:
dst_addr = dst_Y * W + dst_X
- Y轴(垂直)镜像
需要将一块内存中的像素,垂直镜像写入另一块内存
例如:图像高度H和宽度W,假设A像素坐标为(src_x0,src_y0),对应src内存中的地址为:
src_addr = src_y0 * W + src_x0
分析前后的坐标变化规律:dst_X = (W - 1)- src_x0;dst_Y = src_y0; 对应dst内存中地址为:
dst_addr = dst_Y * W + dst_X
- 旋转算子
- 旋转90度
- 顺时针旋转
- 旋转90度
需要将一块内存中的像素,旋转90度写入另一块内存
例如:图像高度H和宽度W,假设A像素坐标为(src_x0,src_y0),对应src内存中的地址为:
src_addr = src_y0 * W + src_x0
顺时针旋转90度,分析前后的坐标变化规律:dst_X = (H - 1)- src_y0;dst_Y = src_x0; 对应dst内存中地址为:
dst_addr = dst_Y * H + dst_X
- 逆时针旋转/旋转270度
需要将一块内存中的像素,旋转90度写入另一块内存
例如:图像高度H和宽度W,假设A像素坐标为(src_x0,src_y0),对应src内存中的地址为:
src_addr = src_y0 * W + src_x0
逆时针旋转90度,分析前后的坐标变化规律:dst_X = src_y0;dst_Y = (W - 1) - src_x0; 对应dst内存中地址为:
dst_addr = dst_Y * H + dst_X
- 旋转180度
需要将一块内存中的像素,旋转180度写入另一块内存
例如:图像高度H和宽度W,假设A像素坐标为(src_x0,src_y0),对应src内存中的地址为:
src_addr = src_y0 * W + src_x0
旋转180度,分析前后的坐标变化规律:dst_X = (W - 1)- src_x0;dst_Y = (H - 1) - src_y0; 对应dst内存中地址为:
dst_addr = dst_Y * W + dst_X
- 图像转置
图像的转置可以通过水平镜像,在逆时针旋转90度来实现。
- 插值
- 最近邻法(Nearest Interpolation)
“近邻”,顾名思义从图像矩阵中找到与它(目标图像的像素点)距离最近的点,然后将最近点的像素值赋给目标像素值。
(1)
src_x: 原图像中像素点x坐标
src_y: 原图像中像素点y坐标
des_x: 目标图像中像素点x坐标
des_y: 目标图像中像素点y坐标
src_w: 原图像宽度(width)
src_h: 原图像高度(height)
des_w: 目标图像宽度(width)
des_h: 目标图像高度(height)
分析:最近邻插值算法,只在原图像中找离它最近的像素点,可能会造成插值生产的灰度上的不连续,在灰度变化的位置处,可能会产生明显的锯齿现象。
单线性插值
单线性插值需要找到周围最近的两个点进行插值运算。
图3 单线性插值
如图3所示:已知点(x0,y0),(x1,y1), 要得到区间(x,y)中某一位置x在直线上的y值,可以得到:
(2)
整理得到:
(3)
由上式可以看出,分子可以看成x分别到x1和x2的距离。把整个公式分别看成y0与y1的加权系数。(离哪个点近,权重就高)
根据实际的目的,y0与y1分别代表原图像中的像素值,上式可以写成如下形式:
(4)
由于在图像中,故公式(4)亦可表示为:
(5)
故可基于公式(1)以及原图像坐标,求得目的图像坐标,并带入公式(5)以求得目的图像pix值。
运用公式(1)和(5)对3x3的原图像坐标求得4x4目标图像坐标及目标像素值:
单线性插值: | |||
(desx,desy) | (srcx,srcy) | y坐标四舍五入 | 目标图像pix |
0,0 | 0,0 | 0,0 | 18 |
1,0 | 0.75,0 | 0.75,0 | 24 |
2,0 | 1.5,0 | 1.5,0 | 46 |
3,0 | 2.25,0 | 2.25,0 | 66 |
0,1 | 0,0.75 | 0,1 | 22 |
1,1 | 0.75,0.75 | 0.75,1 | 22.75 |
2,1 | 1.5,0.75 | 1.5,1 | 44 |
3,1 | 2.25,0.75 | 2.25,1 | 65 |
0,2 | 0,1.5 | 0,2 | 23 |
1,2 | 0.75,1.5 | 0.75,2 | 52.75 |
2,2 | 1.5,1.5 | 1.5,2 | 40 |
3,2 | 2.25,1.5 | 2.25,2 | 25 |
0,3 | 0,2.25 | 0,2 | 46 |
1,3 | 0.75,2.25 | 0.75,2 | 52.75 |
2,3 | 1.5,2.25 | 1.5,2 | 40 |
3,3 | 2.25,2.25 | 2.25,2 | 25 |
图 Src_Img
图 Obj_Img
双线性插值(Bilinear Interpolation)
双线性插值中的”双“,指的是对x方向与y方向分别进行插值,其实共进行三次单线性插值,所以这个”双“应该理解成两个方向的插值,而不是插值的次数。
图5 双线性插值
双线性插值:影响目标点的周围四个点。
已知,未知点.函数为点的像素值,如分别为的像素值。求?
1.利用单线性插值在x方向求:
(6)
2.利用单线性插值在x方向求:
(7)
3.利用单线性插值在y方向求:
(8)
联合(6)、(7)、(8)三式,可求得:
在图像中,,故上式可简化为:
观察一下,发现每个点的权重与待求点与每个点的距离有关。
双线性插值的优化
双线性插值: | 3x3 -> 4x4 | 双线性插值: | 3x3 -> 5x5 | |
(desx,desy) | (srcx,srcy) | (desx,desy) | (srcx,srcy) | |
0,0 | 0,0 | 0,0 | 0,0 | |
1,0 | 0.75,0 | 1,0 | 0.6,0 | |
2,0 | 1.5,0 | 2,0 | 1.2,0 | |
3,0 | 2.25,0 | 3,0 | 1.8,0 | |
4,0 | 2,0 | |||
0,1 | 0,0.75 | |||
1,1 | 0.75,0.75 | 0,1 | 0,0.6 | |
2,1 | 1.5,0.75 | 1,1 | 0.6,0.6 | |
3,1 | 2.25,0.75 | 2,1 | 1.2,0.6 | |
3,1 | 1.8,0.6 | |||
0,2 | 0,1.5 | 4,1 | 2,0.6 | |
1,2 | 0.75,1.5 | |||
2,2 | 1.5,1.5 | 0,2 | 0,1.2 | |
3,2 | 2.25,1.5 | 1,2 | 0.6,1.2 | |
2,2 | 1.2,1.2 | |||
0,3 | 0,2.25 | 3,2 | 1.8,1.2 | |
1,3 | 0.75,2.25 | 4,2 | 2,1.2 | |
2,3 | 1.5,2.25 | |||
3,3 | 2.25,2.25 | 0,3 | 0,1.8 | |
1,3 | 0.6,1.8 | |||
2,3 | 1.2,1.8 | |||
3,3 | 1.8,1.8 | |||
4,3 | 2,1.8 | |||
0,4 | 0,2 | |||
1,4 | 0.6,2 | |||
2,4 | 1.2,2 | |||
3,4 | 1.8,2 | |||
4,4 | 2,2 |
双线性插值: | 9x9 -> 3x3 | 双线性插值: | 5x5 -> 3x3 | |
(desx,desy) | (srcx,srcy) | (desx,desy) | (srcx,srcy) | |
0,0 | 0,0 | 0,0 | 0,0 | |
1,0 | 3,0 | 1,0 | 1.67,0 | |
2,0 | 6,0 | 2,0 | 3.33,0 | |
0,1 | 0,3 | 0,1 | 0,1.67 | |
1,1 | 3,3 | 1,1 | 1.67,1.67 | |
2,1 | 6,3 | 2,1 | 3.33,1.67 | |
0,2 | 0,6 | 0,2 | 0,3.33 | |
1,2 | 3,6 | 1,2 | 1.67,3.33 | |
2,2 | 6,6 | 2,2 | 3.33,3.33 |
从上述数据与pixel单元格可以看出,不管是放大还是缩小。使用公式(1)来求目标图像坐标都会引起原图像的有些点没有参与运算。
为了让原图像和目标图像的中心点对齐,我们规定另一种变换方式:
放大图像时,,就加了一个负数,相当于向左上移动了;
缩小图像时,,就加了一个正数,相当于向右下移动了。
这种变换下,原图像与目标图像的几何中心重合,能充分利用原图像的点,并且目标图像的每个像素点之间都是等间隔的,也都和两边有一定的边距(如下图9x9 -> 3x3)。
reference:
平移、镜像、转置、缩放、旋转的算法实现:图像算法二:【图像几何变换】平移、镜像、转置、缩放、旋转、插值_nearest,crop_一颗橙子℃的博客-CSDN博客
缩放、旋转、位移的基础变换矩阵:计算机图形学一:基础变换矩阵总结(缩放,旋转,位移) - 知乎 (zhihu.com)
插值算法:来聊聊图像插值算法(线性插值与非线性插值) - 知乎 (zhihu.com)
小结
为了提高插值后图像的平滑度,应尽可能使用双线性插值,对x方向和y方向分别进行三次插值,使得插值pixel尽可能来自较多周围pixel点的运算结果。