FPGA学习-图像处理基础实现缓存卷积窗口

像素行与像素窗口

  一幅图像是由一个个像素点构成的,对于一幅480*272大小的图片来说,其宽度是480,高度是272。在使用FPGA进行图像处理时,最关键的就是使用FPGA内部的存储资源对像素行进行缓存与变换。由于在图像处理过程中,经常会使用到卷积,因此需要对图像进行开窗,然后将开窗得到的局部图像与卷积核进行卷积,从而完成处理。

  图像数据一般按照一定的格式和时序进行传输,在我进行实验的时候,处理图像时,让其以VGA的时序来进行工作,这样能够为我处理行缓存提供便利。

基于FIFO的行缓存结构

d7e7bc2617e1af1dd9c9a9e0ca2bb482.png

  在FPGA中对图像的一行数据进行缓存时,可以采用FIFO这一结构,如上图所示,新一行图像数据流入到FIFO1中,FIFO1中会对图像数据进行缓存,当FIFO1中缓存有一行图像数据时,在下一行图像数据来临的时候,将FIFO1中缓存的图像数据读出,并传递给下一个FIFO,于此同时,将新一行的图像数据缓存到FIFO1中,这样就能完成多行图像的缓存。

  若要缓存多行图像,下面的菊花链式的结果更能够直观地表现图像数据地流向。

d95383f8908c88f340e22f3e87945b46.png

  新输入地图像缓存到FIFO1当中,当FIFO中缓存有一行数据的时候,下一个输入像素来临的时候,会将数据从本FIFO中读出,并给到下一个FIFO,来形成类似于一个流水线的结构。

  上面的图中,就是实现一个5X5大小的窗口的一个结构图。

代码设计

  实现一个可以生成任意尺寸大小的开窗的模块,需要注意参数的使用,可以通过调节KSZ来调整窗口的大小。最终将窗口中的图像像素,转换成一个一维的数据输出给到下一个模块。

  在设计的时候,对于FIFO要选择精准计数模式,这样才能让流水正常工作起来。

  在代码中通过generate语句来实现多个line_buffer的例化,line buffer的个数可以根据卷积窗口的大小来选择,例如3X3大小的卷积窗口需要缓存两行,5X5大小的卷积窗口需要缓存4行,可以通过设置参数来选择要例化多少个line_buffer。

3d3cc7fbb8cbe7e459efe97c2d0b4b52.png

时序设计

ae0843d86e1f5083731f94fc63bbd8a1.png

  在设计FIFO的菊花链结构时,需要根据当前FIFO中存储的数据个数来判断,这时候使用到精准计数模式,可以反应FIFO中的存储的数据。当FIFO中存储有一行数据的时候,使能pop_en信号,表示当前可以将数据从FIFO中读出。

  在将数据写入到FIFO中的时候,需要对数据进行扩充,也即需要对输入的图像的边界补充数据,因为进行卷积之后的图像将会比原始图像数据尺寸减少,因此在形成卷积窗口时,将图像扩充,能够让图像处理完成之后,保持原来的尺寸,只是会在边界出现黑边。

  win_buf这个模块的最终输出,就是一个矩阵内的所有像素,组成一个信号输出到外部,供进行卷积的处理。

8c0bf7b93327f2e7c668e66f0cf1c357.png

d0c1b182512304099868b97af1d17c7d.png

8363e091344ed884556356a45bb21f8c.png

a1f501186c4bd6a9756b64d67fb4a13f.png

c794b56d152af95bba10d9173d7c2bf3.png

755e821512e15d7c10ce96e6341571c5.png

fa5e462565b42a9db37d6c8acdef3d1e.png

4fa6a6912e93e8e1f8edf25c4ebaedc8.png

f190fa2bd7f3a1b922a1f26cceef7209.png

5fe309050f3ea5d3f5bf90a2e017c85e.png

667acdc201d731936b9f4f4c2cb18353.png

a0a9f5a0b2e879ff1964fc9927480b73.png

a09032dff8f8b072669c644b86b2b199.png

d0550ef0ee534f436123f1a6e96e9bf5.png

仿真验证

bbf00d77a907512faa1099200ae606cf.png

输入的第三行数据的前三个数据是:0x00,0x78,0x7c

输入的第二行数据的前三个数据是:0x00,0x7d,0x7d

输入的第一行数据的前三个数据是:0x00,0x7e,0x7f

输出的第一个矩阵的值是:0x0078_7c00_7d7d_007e_7f

输入行数据第一个数据是0x00这是因为扩充了边界的原因。

  可以看到,设置KSZ为3,可以得到一个位宽为72bit的输出数据,该数据包含了一个窗口中的9个数据。

5X5开窗

739bad8891fe1fa7cb6f09b9713cee13.png

  设置开窗大小为5x5之后,也可以看到输出信号的位宽变为了8*25=200bit,也就是一个5X5大小的矩阵中的数据。

输入的第5行数据的前5个数据是:0x00,0x00,0x7e,0x7c,0x7f

输入的第4行数据的前5个数据是:0x00,0x00,0x7e,0x7e,0x7e,

输入的第3行数据的前5个数据是:0x00,0x00,0x78,0x7c,0x7c

输入的第2行数据的前5个数据是:0x00,0x00,0x7d,0x7d,0x7a

输入的第1行数据的前5个数据是:0x00,0x00,0x7e,0x7f,0x7d

从输出结果看,输出的矩阵数据,刚好是这5行的前5数据,并且前两个数据是0x00,这是因为在每一行前面补充了两个0的原因。

  经过测试,这种开窗算子是能够完成任意此村的开窗的。

实际应用

  在实际应用中,我也将这个模块正确地使用上了,完成了一个3x3的sobel算子和5x5的均值滤波。

原始图像

19085c4a3eb884de6fdf54e1c51a24ed.png

3x3 Sobel

19621b4f5cdd80f34420f43bf1f31342.png

a006a5fc241ca0b6d47831639e07ecab.png

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值