【FPGA/图像处理】几何变换-缩放

少女dtysky

世界Skill

时刻2015.05.29

缩放同样是仿射变换的一种特例,它接受水平和垂直两个方向的缩放值,将图像进行伸缩,缩放用前向映射实现会出现一个问题,就是在缩放值大于1的时候可能会出现空隙[3]。这是由于在前向映射下,并非原图像的每一个像素都可以映射为目标图像的像素,在软件上这可以通过一些插值方法来实现,但对于FPGA而言同样的实现需要用更为复杂的逻辑,故此处暂且采用逆向映射,这实际上采用了最近邻插值算法。本节将会说明如何用FPGA实现缩放的模块。
这个IP核的资源在这里:
Scale


3 算法实现

明确了设计和架构,便可以进行算法的实现。本章将会说明如何实现图像处理的算法,以及如何运用它们。

3.19 几何变换-缩放

缩放同样是仿射变换的一种特例,它接受水平和垂直两个方向的缩放值,将图像进行伸缩,缩放用前向映射实现会出现一个问题,就是在缩放值大于1的时候可能会出现空隙[3]。这是由于在前向映射下,并非原图像的每一个像素都可以映射为目标图像的像素,在软件上这可以通过一些插值方法来实现,但对于FPGA而言同样的实现需要用更为复杂的逻辑,故此处暂且采用逆向映射,这实际上采用了最近邻插值算法。本节将会说明如何用FPGA实现缩放的模块。

3.19.1 原理

缩放变换的基本原理如式3-19-1,Q为输出,I为输入,x和y为输入像素坐标,xtx_tyty_t为输出像素坐标,xscale和yscale分别为两个方向的缩放比例,w和h为图像的宽和高,这是前向映射的一般定义,但对于逆向映射而言,应该对此式进行调整,变换为3-19-2的形式,xtx_tyty_t称为自己变换的输出坐标,x和y则通过xtx_tyty_t除以各自缩放比例得出,随后根据x和y得到需要输出的原图像像素,进行输出。

{Q[xt,yt]=I[x,y]xt=xxscalex[0,w)yt=yyscaley[0,h) .        (3191)\begin{cases}Q[x_t,y_t] = I[x,y] \\x_t = x * xscale && x \in[0, w)\\ y_t = y * yscale && y \in[0, h)\ \end{cases}.\ \ \ \ \ \ \ \ (3-19-1)

{I[x,y]=Q[xt,yt]x=xt/xscalext[0,w)y=yt/yscaleyt[0,h) .        (3192)\begin{cases}I[x,y] = Q[x_t,y_t] \\x = x_t / xscale && x_t \in[0, w)\\ y = y_t / yscale && y_t \in[0, h)\ \end{cases}.\ \ \ \ \ \ \ \ (3-19-2)

可见,这实际上是先得出需要输出的像素坐标,然后反向映射到原图像的像素坐标,最后查找到原图像的像素值进行输出。所以前面章节的方式不再适用,必须采用新的设计。考虑到输出坐标的生成依赖于外界没有意义,所以选用内部的计数器进行目标图像坐标的生成。最终采用的方案为,首先将原图像存入帧缓存,根据计数器生成的坐标进行两次并行乘法得到原图像对应的坐标,并联合3.15中的帧控制器,查找得到需要输出的像素值,同时进行边界判定,当求得的原图像的坐标超出了图像的范围,则输出为背景像素,算法如式3-19-3。

Q[xt,yt]={I[x,y](x,y)I0(x,y)I .        (3193)Q[x_t,y_t] = \begin{cases}I[x,y] && (x,y)\in I \\0 && (x,y) \notin I\ \end{cases}.\ \ \ \ \ \ \ \ (3-19-3)

由于本库采用的是定点数乘法,所以需要一个确定的小数位来保证精度,经过实验和DSP资源的考虑(一个DSP48最多实现12x25的乘法),最终采用拥有6位整数和18位小数的定点数,即缩放比例的范围为[0, 64)。同时由于涉及小数乘法,所以需要选择一个舍入方式,几何变换对于舍入方式是敏感的,为了符合最邻近插值的定义,几何变换中所有模块的舍入方式均为就近舍入,故需要一个舍入核来完成舍入操作,考虑到缩放变换中的乘法为无符号乘法,故舍入核设计比较简单,例如对于一个12bits.12bits的定点数,舍入原理如式3-19-4,其中Q为输出,IrI_r为输入的整数部分,Id1I_{d1}为输入的小数部分第一位,第一位为1,则I的小数部分必然大于0.5,否则小于。

Q={IrId1=0Ir+1Id1=1 .        (3194)Q = \begin{cases}I_r && I_{d1} = 0 \\I_r + 1 && I_{d1} = 1\ \end{cases}.\ \ \ \ \ \ \ \ (3-19-4)

3.19.2 设计

根据原理可知,Scale核(以下简称SCL核)需要两次乘法,两次舍入操作,并且需要和基于行列计数的帧控制器进行合作。故其需要的配置参数与端口如表3-19-1和表3-19-2。

名字 类型 范围 默认值 说明
work_mode 无符号 0为流水线模式,1为请求响应模式 0 模块的工作模式。
data_width 无符号 1 - 12 8 数据位宽。
im_width 无符号 1 - 4096 320 图像宽度。
im_height 无符号 1 - 4096 240 图像高度。
im_width_bits 无符号 取决于图像宽度 9 图像宽度的位宽。
mul_delay 无符号 取决于乘法器配置,1-14 3 乘法器延迟。
ram_RL 无符号 取决于帧控制器 7 帧控制器输出延迟。
表3-19-1 配置参数


名字 端口 类型 范围 默认值 说明
clk 输入 无符号 Clock.
rst_n 输入 无符号 复位,低有效。
scale_x input 无符号 定点数,6bits.18bits 横向缩放比例,必须是正确缩放比例的倒数。
scale_y input 无符号 定点数,6bits.18bits 纵向缩放比例,必须是正确缩放比例的倒数。
in_enable 输入 无符号 输入数据使能,在流水线模式下,它是另一个复位信号,在请求响应模式下,只有在它有效的时候in_data才会被真正地改变。
frame_in_ready 输入 无符号 连接到帧控制器的out_ready。
frame_in_data 输入 无符号 data_width - 1 : 0 连接到帧控制器的out_data。
frame_enable output 无符号 连接到帧控制器的in_enable。
frame_out_count_x output 无符号 im_width_bits - 1 : 0 连接到帧控制器的in_count_x。
out_count_y output 无符号 im_width_bits - 1 : 0 连接到帧控制器的in_count_y。
out_ready output 无符号 输出数据有效,在两种模式下,这个信号都会在out_data可以被读取的时候有效。
out_data output 无符号 color_width - 1 : 0 输出数据,将会和out_ready同步输出。
表3-19-2 端口



名字 类型 说明
MulX Multiplier12x24SCL 12位无符号数和24位无符号数的乘法器,被用于定点数的乘法。你可以自己配置这个乘法器,然后更改"mul_delay",但所有的乘法器必须拥有相同的流水线级数,并且不能更改端口的配置!
MulY Multiplier12x24SCL 12位无符号数和24位无符号数的乘法器,被用于定点数的乘法。你可以自己配置这个乘法器,然后更改"mul_delay",但所有的乘法器必须拥有相同的流水线级数,并且不能更改端口的配置!
FRUX FixedRoundUnsigned 用于无符号浮点数的舍入。
FRUY FixedRoundUnsigned 用于无符号浮点数的舍入。
表3-3-3 子模块

3.19.3 实现

根据3.19.2的设计便可以实现一个SCL核,流水线模式和请求响应模式实现如下。

3.19.3.1 流水线模式

输入使能后首先计数器工作,随后计算原图像的坐标,随后根据算出的坐标得到边界,同时将坐标输出到帧控制器,在帧控制器的输出使能后1个周期第一个结果被输出,开始流水化工作,波形如图3-19-1。

图3-19-1 流水线模式时序
图3-19-1 流水线模式时序

3.19.3.2 请求响应模式读取

基本同3.19.3.1,但只有在in_enable上升沿时计数器才会加1才会被改变,波形如图3-19-2。

图3-19-1 流水线模式时序
图3-19-1 流水线模式时序

3.19.3.3 IP核GUI

完成功能后对SCL核进行了封装,封装如图3-19-3。

图3-19-3 SCL核的GUI
图3-19-3 SCL核的GUI

3.19.4 仿真

只对RGB图像和灰度图像进行测试,考虑到仿真设计模块比较多,出于仿真压力,我选择了一张图像的灰度模式进行三套参数的测试,原始图像如图3-19-4。

图3-19-4 仿真原始图像
图3-19-4 仿真原始图像

仿真参数如表3-16-4所示,选择原则是可以被二进制表示和不可以被表示的值都包含。

xscale yscale
1.97 0.213
0.391 2.17
0.4 0.4
表3-16-4 仿真参数

仿真并进行PSNR测试,仿真结果如图3-19-5所示。

图3-19-5 仿真结果
图3-19-5 仿真结果,左侧为流水线模式下的HDL功能仿真结果,中间为请求响应模式下的HDL功能仿真结果,右侧为软件仿真结果

3.19.5 资源和时序

最终实现与图像大小和数据位宽有关,这里只分析大小为512x512和数据位宽为8时的状况,根据Vivado生成的报表,主要资源耗费如表3-19-5。

Slice LUTs* Slice Registers DSP
77 69 2
表3-19-5 主要资源耗费

同时根据时序报告,最大的Data Path Delay(数据路径延迟)为3.372ns,即:

FMax = 296.55MHz

即说明,Scale核在流水线模式下,理论上在处理1080p全高清图像时可以达到143帧。
由于数据路径延迟和应用的最终约束设置强相关,所以仅供参考。

3.19.6 分析与结论

PSNR如表3-19-6。

1-0.391x2.17 1-0.4x0.4 1-1.97x0.213 Total
1000000.00 1000000.00 1000000.00 1000000.00
表3-19-6 PSNR

PSNR均值为最大值,可见在测试范围内,SCL核与软件等效,同时可以达到不错的FMax,设计成功。


参考文献

[3] Donald G.Bailey.基于FPGA的嵌入式图像处理系统设计[M].原魁,何文浩,肖晗译.北京:电子工业出版社,2013.


感谢

仿真图像来源:
あきのん-[C84]こもれび

如果不是自己的创作,少女是会标识出来的,所以要告诉别人是少女写的哦。