图像高斯滤波的FPGA实现--实时高速

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011964923/article/details/50972403

由于摄像头采集图像过程中,会产生高斯噪声,所以在进行数字图像处理之前,进行去噪是十分有必要的。


高斯滤波器的滤波器模板其实很简单,一般而言,可以根据杨辉三角的第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] 就是经高斯滤波只有的像素值


附上效果图:前一张是未经高斯滤波的边缘提取,后一张是经过高斯滤波的边缘提取。 可以明显看出,滤波去噪后的边缘提取图干净了许多!


                上图是我可爱的舍友的侧面图!

猜你喜欢

转载自blog.csdn.net/u011964923/article/details/50972403
今日推荐