图像高斯滤波的FPGA实现--实时高速
2016-03-24 16:39
232 查看
由于摄像头采集图像过程中,会产生高斯噪声,所以在进行数字图像处理之前,进行去噪是十分有必要的。
高斯滤波器的滤波器模板其实很简单,一般而言,可以根据杨辉三角的第N行作为模板系数。
本次实验,利用杨辉三角的第三行 [1 2 1]作为模板系数,所得到的3x3滤波器模板为:
1 1 1
1 2 1
1 1 1
模板中间点是当前像素点,系数(权值)为2,周围8点系数为1。 然后和3x3的像素值 “对应相乘相加,再除以系数和(10)”,得到的结果则作为滤波之后的像素值。
对于某像素而言,3x3模板的高斯滤波就相当于,2个”自己“和8个”邻居“ 求 平均值。
OK,下面来看一下如何在FPGA上实现:
先看一下 RTL Viewer
1) 第一步:搭建LineBuffer
LineBuffer顾名思义,就是行缓冲,它有三个输出,就像是3根管子: 每根管子里有800个像素点不停地右移。 也就是一帧图片上对应的三行像素!
如下图所示:是在Quartus II里面调用的IP核,设置像素宽度8位(其实只用了5位,存储灰度值),管子数taps = 3,每根管子的长度为 distance = 800
有读者会问:
1、为什么是3根管子?
答:因为高斯滤波模板是3行3列,仅需存储三行像素即可
2、管长为什么是800像素?
答:本实验摄像头输出的一帧图片是640*480像素,VGA分辨率也对应为640*480。但VGA的时序,还有SYNC,PORCH,BACK等信号,也要占用一定的时钟周期,根据协议,640*480@60Hz的VGA标准,行周期为800个像素点!
3、LineBuffer是如何实现像素换行的?
答:点击右上角的Documentation可以在Web上获取帮助文档,下图十分重要,由下图可以看出,当像素由移到一根管子的末尾处时,再来一个时钟,这个像素就会跑到下一根管子的开始处,仔细想一想,这不正好对应了摄像头的输出顺序和VGA的扫描顺序吗? 而且,LineBuffer输出的数据是3根管子末尾像素,这正好对应了一帧图像同一列的相邻三个像素, 当时钟来临的时候,三根管子都会右移一位,这样只需要三个时钟,LineBuffer就把高斯滤波模板对应的9个像素都输出来了!
2)第二步:同行相乘相加
调用ALTMULT_ADD的IP核,对同一行的3个像素(3 multipliers),根据滤波模板进行相乘相加,dataa是像素值,datab0~2是模板系数。因为3个像素是依次从LineBuffer输出的,所以这个IP和内部应该有3个触发器。注意设置输出总线的宽度,以免溢出。
3)第三步:三行结果求和再除以10
调用PARALLEL_ADD的IP核,并行加法器,很简单不用多说。
最终输出的oData[4:0] 就是经高斯滤波只有的像素值
附上效果图:前一张是未经高斯滤波的边缘提取,后一张是经过高斯滤波的边缘提取。 可以明显看出,滤波去噪后的边缘提取图干净了许多!
上图是我可爱的舍友的侧面图!
高斯滤波器的滤波器模板其实很简单,一般而言,可以根据杨辉三角的第N行作为模板系数。
本次实验,利用杨辉三角的第三行 [1 2 1]作为模板系数,所得到的3x3滤波器模板为:
1 1 1
1 2 1
1 1 1
模板中间点是当前像素点,系数(权值)为2,周围8点系数为1。 然后和3x3的像素值 “对应相乘相加,再除以系数和(10)”,得到的结果则作为滤波之后的像素值。
对于某像素而言,3x3模板的高斯滤波就相当于,2个”自己“和8个”邻居“ 求 平均值。
OK,下面来看一下如何在FPGA上实现:
先看一下 RTL Viewer
1) 第一步:搭建LineBuffer
LineBuffer顾名思义,就是行缓冲,它有三个输出,就像是3根管子: 每根管子里有800个像素点不停地右移。 也就是一帧图片上对应的三行像素!
如下图所示:是在Quartus II里面调用的IP核,设置像素宽度8位(其实只用了5位,存储灰度值),管子数taps = 3,每根管子的长度为 distance = 800
有读者会问:
1、为什么是3根管子?
答:因为高斯滤波模板是3行3列,仅需存储三行像素即可
2、管长为什么是800像素?
答:本实验摄像头输出的一帧图片是640*480像素,VGA分辨率也对应为640*480。但VGA的时序,还有SYNC,PORCH,BACK等信号,也要占用一定的时钟周期,根据协议,640*480@60Hz的VGA标准,行周期为800个像素点!
3、LineBuffer是如何实现像素换行的?
答:点击右上角的Documentation可以在Web上获取帮助文档,下图十分重要,由下图可以看出,当像素由移到一根管子的末尾处时,再来一个时钟,这个像素就会跑到下一根管子的开始处,仔细想一想,这不正好对应了摄像头的输出顺序和VGA的扫描顺序吗? 而且,LineBuffer输出的数据是3根管子末尾像素,这正好对应了一帧图像同一列的相邻三个像素, 当时钟来临的时候,三根管子都会右移一位,这样只需要三个时钟,LineBuffer就把高斯滤波模板对应的9个像素都输出来了!
2)第二步:同行相乘相加
调用ALTMULT_ADD的IP核,对同一行的3个像素(3 multipliers),根据滤波模板进行相乘相加,dataa是像素值,datab0~2是模板系数。因为3个像素是依次从LineBuffer输出的,所以这个IP和内部应该有3个触发器。注意设置输出总线的宽度,以免溢出。
3)第三步:三行结果求和再除以10
调用PARALLEL_ADD的IP核,并行加法器,很简单不用多说。
最终输出的oData[4:0] 就是经高斯滤波只有的像素值
附上效果图:前一张是未经高斯滤波的边缘提取,后一张是经过高斯滤波的边缘提取。 可以明显看出,滤波去噪后的边缘提取图干净了许多!
上图是我可爱的舍友的侧面图!
相关文章推荐
- PHP GD 图像处理组件的常用函数总结
- PHP图像处理之imagecreate、imagedestroy函数介绍
- jsvascript图像处理―(计算机视觉应用)图像金字塔
- Javascript图像处理思路及实现代码
- PHP图像处理之使用imagecolorallocate()函数设置颜色例子
- java数字图像处理基础使用imageio写图像文件示例
- 使用Java进行图像处理的一些基础操作
- javascript图像处理―边缘梯度计算函数
- Javascript图像处理―阈值函数实例应用
- Javascript图像处理―虚拟边缘介绍及使用方法
- PHP图像处理类库及演示分享
- php图像处理函数大全(推荐收藏)
- Javascript图像处理―图像形态学(膨胀与腐蚀)
- Javascript图像处理―平滑处理实现原理
- Swift图像处理之优化照片
- 在Ubuntu上安装OpenCV3.0和Python-openCV的经历
- 《FPGA嵌入式项目开发实战》
- VTK学习笔记之图像处理
- vtk 图像处理 多种 操作
- 05-VTK在图像处理中的应用(2)