Shift register——3*3矩阵均值滤波在fpga上的实现

     先简单介绍一下基本的图像处理算法,比如均值滤波,中值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标像素为中心的周围8哥像素 ,构成一个滤波模板,即去掉目标像素本身),再利用模板中的全体像素的平均值来代替原来像素值。
      
      中值滤波算法可以形象的用上述表格来描述,即对于每个3*3的阵列而言,中间像素的值,等于边缘8个像素的平均值,算法的理论很简单,对于C语言或者matlab而言,一副640*480图像的均值滤波,可以很方便的通过数组获得3*3的阵列,但对于Verilog而言,确实不是一件容易的事儿,想不明白呀,硬件和软件确实不是一个思路。
      知名FPGAer Crazybingo 老湿,在他的VIP_mini_board配套教程里面提到了三种方法,但是最被认可接受且最方便的就是shift_ram,用他的话来说就是shift_ram就是为实现3*3矩阵而生的。
        首先介绍一下Shift_ram,宏定义模块如下图所示:
Shift_ram可以定义输入输出数据宽度,每行的宽度, 移位的行数,这里我们需要8bit的数据位宽,每行的宽度640,移位2行即可,(原因稍后分析,其实很简单,画个图很容易理解)。下面的示意图有助于更好的理解Shift_ram。
      每个时钟周期输入一个移位数据shift_in_data,同时输出一个数据shift_out_data,而存储器内部是每个clk周期移位一次,每个tap的输出直接移位到下一个tap的输入,每个tap的最后一个w位宽的数据都能出现在对外接口中供用户逻辑使用(通过.taps0x( ),.taps1x( )输出)。

      Shift_ram中存2行数据,同时与当前输入行的数据组成3行的阵列,实现8bit宽度的3*3像素阵列功能,具体的实现步骤如下:
在我看来首先应当明确3*3矩阵生成器的输入:
对于来自sensor的图像数据,图像重构需要以下数据:
1 per_frame_vsync       //帧同步信号

2 per_frame_href         //行有效信号
3 per_frame_clken       // 这是移位寄存器存储数据的使能 时钟信号(数据在clk的监督下进来了,但是能不能存下来还要看
                                        per_frame_clken
4 clk                             //像素时钟
5 rst_n                         //全局复位信号
6 img_Y                       //图像数据 

步骤:
1: 首先,将输入的信号用像素使能时钟(per_frame_clken)同步一拍,以保证数据与Shift_ram输出的数据保持同步,如下:

       
2:接着,例化并输入row3_data     

3:row_data读取信号的分析及生成

    这里有一个问题,就是数据进入shift_ram存储耗费了一个时钟,一次3*3阵列的读使能与时钟,需要进行一个clock的偏移,如下所示:
4:根据行同步信号read_frame_href 与read_frame_clken信号,直接读取3*3像素阵列,读取的verilog代码如下

matrix中的p11—p33即为得到的3*3像素阵列。
5.bingo老师把这一步放在了最后,看来基本理解到位了,哈哈哈。
搞定!

猜你喜欢

转载自blog.csdn.net/dongdongnihao_/article/details/80427763
今日推荐