随着科学技术的高速发展,FPGA在系统结构上为数字图像处理带来了新的契机。图像中的信息并行存在,因此可以并行对其施以相同的操作,使得图像处理的速度大大提高,这正好适合映射到FPGA架构中用硬件算法得以实现。
本篇阐述了基于FPGA设计一个能够实时采集、实时处理并实时显示的数字图像处理系统的设计思想和流程,分析了摄像头接口的时序;阐述了图像信息的捕获原理;详细介绍了图像边缘检测部分各模块的功能;重点介绍了具有去噪功能的中值滤波模块的设计;简单描述了边缘检测算子的选用;系统的介绍了SDRAM的工作原理以及控制方式;介绍了VGA时序;最后针对整个系统做了验证和总结,包括仿真波形的验证以及板级验证。
该系统基于实体FPGA开发板实现了图像数据的实时采集、实时边缘检测和实时显示,运行稳定,实时性能较高,从而也表明FPGA确实具有海量数据高速传输的能力。
本篇为本人当年的毕业设计部分整理,各位大侠可依据自己的需要进行阅读,参考学习。
第二篇内容摘要:本篇会介绍FPGA实现图像的边缘检测,包括图像数据预处理(彩色图像数据转灰度图像,中值滤波)、边缘检测。
还会介绍FPGA驱动VGA接口实现图像边缘信息的实时显示,包括图像数据的缓存(SDRAM的工作原理,SDRAM的上电刷新,SDRAM读写数据,图像数据缓存的FPGA实现) 、图像数据的实时显示(VGA时序分析,VGA接口的FPGA驱动)等相关内容。
为了实现图像的边缘检测,需要对捕获到的图像数据进行预处理操作:后续算法适用于灰度图像,因此首先需要将捕获到的彩色图像转换为保留有亮度信息的灰度图像;实时采集到的图像数据往往都会伴随着噪声,为了使图像处理的结果更加准确,我还采用了中值滤波算法对得到的灰度图像进行有效去噪。
本系统所采用的算法全部适用于8位灰度图像,因此在边缘检测和中值滤波之前需要将彩色图像转换成适于研究的8位灰度图像,将图像中的每个像素用下列公式(3-1)计算其灰度值,公式如下:
(3-1)
式中r、g、b分别为该像素对应的R、G、B颜色分量,然后用求得的灰度值代替原来该像素的R、G、B分量就行了。如图3-1所示,我在本系统设计中按照上述思路实现了从彩色图像往灰度文件的转换。
图3-1 彩色图像转灰度文件对应的RTL级视图
在图像处理中,为了保护边缘信息和平滑噪声,中值滤波被广泛应用。本系统设计的目的是对实时采集到的图像进行边缘检测,因此边缘信息检测的准确度在很大程度上决定了整个系统设计的性能,为了提高我所设计系统的性能,我采用了中值滤波。中值滤波是一种非线性信号处理技术,基于排序统计理论,可以有效抑制噪声,其基本原理是将数字图像或者数字序列中一点的值用该点所在邻域中各点值的中值代替,让周围的像素值尽可能的接近其真实值,从而能够有效地消除孤立的噪声点。分两步实现:1.采样取出奇数个数据进行排序;2.用排序后的中值代替所要处理的数据。
本设计选择3*3的窗口模板,调用FIFO来对图像数据进行缓存,然后并行输出3行数据,在进行数值比较之后顺序输出中值结果,有效提高了系统的处理速度。
图3-2 中值滤波模块框图
如图3-2所示为该系统中值滤波模块的框图,调用四个子模块:shift_temp模块、compara_fifo模块、zhongzhilvbo模块和midnum_mem模块。其中,shift_temp模块、compara_fifo模块和midnum_mem模块均为调用的IP核,其模块架构如图3-2所示。
图3-3 中值滤波模块架构图
shift_temp模块调用的IP核是一个移位寄存器,在写请求信号wrreq的控制下,将输入的8bit图像灰度信息移位寄存到24bit寄存器中并实时传送,接着在compara_fifo模块和midnum_mem模块中分别调用了一个FIFO,所谓FIFO就是先入先出存储器,这里用作数据缓存,有效地保证了中值滤波过程中所处理信息的流畅性和可靠性。中值滤波模块的核心运算在zhongzhilvbo模块中得以实现,该模块框图如图3-4所示。
图3-4 zhongzhilvbo模块框图
中值滤波及其子模块代码及说明见附录,编写测试文件仿真运行即可得到如图3-2所示的仿真波形。
图3-5 中值滤波模块的仿真波形
一幅图像中灰度变化比较剧烈的区域一般就是图像边缘,图像的边缘信息可以通过计算灰度图像中各区域的梯度幅值来判断。令图像的亮度为f(x,y),则其灰度可以用以下公式来定义:
(3-1)
幅值为:
(3-2)
方向为:
(3-3)
比较常用的边缘检测算子有Prewitt 边缘检测算子、Roberts 边缘检测算子、Laplacian 边缘检测算子、Sobel 边缘检测算子等。经典Sobel边缘检测算法便是基于梯度的检测,利用垂直梯度和水平梯度2个方向模板和图像进行邻域卷积完成。其中,垂直梯度方向模板和水平梯度方向模板分别用于检测水平边缘和垂直检测。其利用Sobel算子在3*3的图像邻域内和亮度数据作卷积运算,表达式如下:
(3-4)
(3-5)
我选用如图3-6所示的数据源,并分别采用上述几种算子实施检测,其算子和检测得到的结果分别如图3-7、图3-8、图3-9和图3-10所示。对比上述四幅检测结果图,我最终选用Sobel算子作为我的边缘检测算法。
图3-6 边缘检测数据
图3-7 Prewitt算子及边缘检测结果图
图3-8 Roberts算子及其边缘检测结果
图3-9 Laplacian算子及其边缘检测结果
图3-10 Sobel算子及其边缘检测结果
实现了图像数据的边缘检测,接着就需要将其实时显示,该系统设计最终基于VGA实现这一功能。这一功能说起来简单,实现起来却并不容易,由于Ov7725输出数据的时钟和VGA输入的时钟不同,导致无法将检测到的数据直接对接到VGA接口并输出。其解决方案是在VGA实时显示之前将检测到的图像数据先缓存起来,这里选用SDRAM作为图像数据的缓存器,从而解决了这一难题。
SDRAM(Synchronous Dynamic Random Access Memory)即同步动态随机存储器。同步是指其时钟频率与CPU前端总线的时钟频率相同;动态是指SDRAM位电容阵列,需要定期不断的充放电来保证数据不丢失;随机是指不是线性一次存储数据,而是可以进行随机地址的读写操作。该系统设计选用了海力士公司生产的HY57V641620ETP-7,其存储大小约为4Banks x 1Mbits x 16 = 64Mbits,最高频率可达143Mhz,在实际设计中选定SDRAM的驱动频率为100Mhz。
SDRAM存储器框图如图4-1所示,其主要功能是实现数据的高速读写操作,内部模块包括逻辑控制单元、地址寄存器和数据寄存器。在众多的SDRAM控制器中,厂家往往会指定相关操作对应的命令,因此在SDRAM内部还有一个命令解码器。SDRAM的上电刷新、读数据和写数据、预充电、刷新等操作实际上就是对每一个命令的操作,SDRAM的基本操作命令如图4-2所示。
图4-1 SDRAM存储器框图
图4-2 SDRAM控制命令表
1)SDRAM初始化流程
在正式使用SDRAM之前,有一个非常关键的步骤——SDRAM的初始化,其主要功能是稳定电路和完成SDRAM的配置,从而保证SDRAM能够按照我们预期的工作模式来工作。SDRAM初始化的流程,如图4-3所示。
图4-3 SDRAM初始化流程图
SDRAM初始化必须按照流程严格执行,否则就会导致SDRAM在读、写数据出现问题。例如初始化流程中100us的等待时间必须给足,不然就会导致整个上电刷新模块出现问题。SDRAM的Logicla Bank是电容结构,电容容易掉电使数据丢失,所以应该定时给SDRAM充电,手册中表示至少每64ms要对所有BANK进行一次刷新,确保数据正确。该系统设计所用SDRAM的刷新周期是 64ms/4096 = 15.625us。模式寄存器配置完成之后,输出一个标志信号作为外部模块读写SDRAM的握手信号,从而保证图像数据的正确读写。
2)模式寄存器设置
在进行SDRAM初始化的时候,必须对模式寄存器(Mode Register,MR)进行配置,模式寄存器的主要功能是配置SDRAM的读/写数据的突发长度(Burst Length)、突发类型(Burst Type)、潜伏期(CAS Latency)、写突发模式(Write Mode)等设置。如果模式寄存器没有设置好,那么SDRAM 就不会按照预先的模式工作;上电初期对模式寄存器所进行的设置,其信息将会持续保持直到下一次编程或者掉电为止,模式寄存器的地址总线及其意义如图4-4所示。
图4-4 SDRAM模式寄存器设置命令表
现对如图4-4所示表格中的相关信息做一下说明:
⑴A2A1A0所控制的是突发长度,SDRAM进行数据读写时以此为单位,突发长度有1、2、4、8、全页突发(full page)。全页突发是指每一个bank里面的一行中所有的数据,其大小取决于SDRAM的列数,本系统设计所选用的是64Mbits的SDRAM,其列数只有256个存储单位,这就意味着我们一页最多可读写256个数据。
⑵A3控制的是突发类型,分为连续发送和交替发送两种,面对大数据的传输时我们一般选择连续发送,这样能够保证相对较高的速度,本系统设计选择连续发送数据。
⑶A6A5A4控制的是读写数据的潜伏期,潜伏期有1、2、3拍三种;潜伏期越大,系统的运行速度就越高,本系统设计选择3拍潜伏期。
⑷其余地址可以忽略。
SDRAM读写数据的方式有多种,可以根据需求读取指定地址中的数据,也可以连续读写最多256个数据。本系统设计中,所要缓存的图像数据量比较大,因此选用突发读写整页数据的方式来实现,从而有效提高数据传输的带宽。
图4-5 SDRAM读数据时序
如图4-5所示为SDRAM读数据的时序图:在上电刷新时,需要在模式寄存器内设置好突发长度和潜伏期,上图中的潜伏期CL = 2,突发长度是4;分析上图不难发现,自发出第一次读命令后,读数据操作便会自动运行。
如果不想突发中断数据的读取,实现数据的连续读取,只需控制好两次发送读命令的间隔周期即可。在本系统设计中,需要处理的是边缘检测以后的视频流数据,因此设置为连续的突发读写模式,同时选择全页读写的方式进行数据的操作,从而达到更大的带宽、更高的效率,以实现更快的速度。这样做的前提是在每次SDRAM读数据或者写数据时,都必须要为其准备好至少256个数据缓冲器,以保证数据可以连续的读写,因此需要调用FIFO作为SDRAM的缓冲器。
基于是上述分析,我们就可以基于FPGA编写SDRAM的控制器代码,同时必须要调用两个FIFO分别用作SDRAM的读数据和写数据缓冲器,如图4-6即为工程编译成功以后图像数据缓存模块所对应的RTL级视图。
图4-6 图像数据缓存模块所对应的RTL级视图
VGA(Video Graphics Array,视频图形阵列)是一种电脑显示标准,对于现如今的个人电脑市场来说,这个标准已十分过时。然而,VGA却是众多显示设备制造商所共同支持的一个低标准,因此具有一定的通用性。因此,本系统设计就选择VGA作为图像缓存数据到显示器的桥梁,将边缘检测后的视频图像数据实时显示到相关的显示设备上。如图4-7所示,VGA接口与串口的硬件结构相类似,分为公头与母头(PC接口为母头)。
图4-7 VGA接口示意图
VGA接口使用15针的D型接口,拥有15根信号线,分成三组,每组5根信号线。接口编号顺序为:公头从左到右,依次递增;母头从右到左,一次递减,两者相互对应,各引脚功能描述见表4-1。
表4-1 VGA接口各引脚功能描述
广义的VGA为VGA显示器,狭义的VGA为VGA分辨率的时序。由IBM推出的采用RGB模拟信号的VGA视频标准,定义了具有60Hz刷新频率、可产生16万种色彩的640*480像素格式。VGA显示器扫描方式分为逐行扫描和隔行扫描:逐行扫描是从屏幕左上角第一个点开始,从左向右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,CRT 对电子束进行消隐,每行结束时,用行同步信号进行同步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧。隔行扫描是指电子束扫描时每隔一行扫一线,扫完一屏后再返回来扫描剩下的线,隔行扫描的显示器闪烁快速,可能会使使用者眼睛疲劳(本实验采用逐行扫描的方式)。扫描原理清楚以后,紧接着再来看看VGA的行、列同步时序。
1)VGA行列时序
VGA列同步时序如图4-8所示:
图4-8 VGA列同步时序图
VGA行同步时序如图4-9所示:
图4-9 VGA行同步时序图
VGA 中定义行时序和列时序都需要同步脉冲(a 段)、显示后沿(b 段)、显示时序段(c 段)和显示前沿(d 段)四部分。VGA 工业标准显示模式要求:行同步、列同步都为负极性,即同步脉冲要求是负脉冲。
由 VGA 行时序可知:每一行都有一个负极性行同步脉冲(a 段),是数据行的结束标志,同时也是下一行的开始标志。在同步脉冲之后为显示后沿(b段),在显示时序段(c 段)为显示器亮的过程,RGB 数据驱动一行上的每一个像素点,从而显示一行。在一行的最后为显示前沿(d 段)。在显示时间段之外没有图像投射到屏幕,而是插入消隐信号。同步脉冲、显示后沿和显示前沿都是在行消隐间隔内,当消隐有效时,RGB 信号无效,屏幕不显示数据。
2)VGA显示标准
“分辨率”是衡量物体精确程度的一个参数,对于显示器而言,分辨率越高,意味着显示图像的清晰度越高,包含跟过的信息,具有更多细节的画质,图像更加保真细致。由于人眼的视觉暂留特性,想要实现CRT显示器画面不闪烁,至少需要实现每秒至少25帧的画面更新。而显示器为了保证画面流畅,视觉效果更佳,通常一般的扫描帧速在每秒60帧以上。不同像素的行/列扫描刷新时序见表4-2。
表4-2 VGA标准显示表
以本设计的显示标准 64048060Hz 为例。(640 为列数,480 为行数,60Hz为刷新一屏的频率),时钟频率大约是 25.175Mhz。列时序:屏幕对应的行数为800(a+b+c+d=e 段),其中 640(c 段)为显示行;每行均有行同步信号(a 段),为96个行周期的低电平。行时序:每个显示行包括525列(a+b+c+d=e段),其中480(c段)为有效显示区,每列均有列同步信号(a段),为2个列周期的低电平。
3)VGA驱动电路设计
由于FPGA输出的是3.3V电平,而VGA要求0~0.714V的模拟信号,为了设计VGA的标准接口,完成电平的转换,需要设计DAC数模转换电路,来实现0~0.714V模拟视频信号的传输,针对RGB的分辨率高低,可以采用不同的数模实现方案,在VGA驱动电路设计中,我们最需要关心的几组信号见表4-3。
表4-3 VGA驱动电路信号表
HSYNC与VSYNC为3.3V数字信号,再设计中无须考虑电平转换,可以直接接与FPGA互联。而RGB为0~0.714V模拟信号,这是需要我们转换处理的部分,本设计采用专用的视频转换DAC芯片,其稳定的ASIC保证了视频传输的质量,具有很好的性价比。采用Analog Devices的视频转换芯片ADV7123,其参数如下:
⑴最大采样率是330Mhz;
⑵3路10位视频DAC转换器;
⑶兼容TTL电平输入;
⑷5V/3.3V单电源工作;
⑸输出电流达到2~26mA;
⑹低功耗。
ADV7123具体的硬件电路图如图4-10所示。
图4-10 ADV7123电路结构图
分析了VGA接口的时序,我们就可以按照时序基于FPGA编写相应的VGA驱动代码,如图4-11所示即为系统工程成功编译以后VGA驱动模块对应的RTL级视图。
图4-11 VGA驱动模块对应的RTL级视图