基于FPGA的图像双边滤波实现,包括tb测试文件和MATLAB辅助验证

118 阅读4分钟

1.算法运行效果图预览

8abd5d2f345a5c34aaa48570fae2502d_82780907_202402262326110277120168_Expires=1708961771&Signature=L5Ou9%2BI3Fxx%2BrI%2FbJt0GcMLeRIQ%3D&domain=8.jpeg  

将FPGA数据导入到matlab对比测试:

3667ce7cc968110e7fd5780ed5f7a340_82780907_202402262326000761774150_Expires=1708961760&Signature=cWw1QXegVXq%2FJXeJ35C8SK1oIgQ%3D&domain=8.jpeg

2.算法运行软件版本

vivado2019.2

 

matlab2022a

 

3.算法理论概述

          双边滤波是一种非线性滤波方法,它能够在平滑图像的同时保持边缘的锐度。这一特性使得双边滤波在图像处理领域具有广泛的应用,如噪声去除、细节增强等。随着硬件技术的发展,现场可编程门阵列(FPGA)因其并行处理能力和可配置性,成为实现图像处理算法的理想平台。本文将详细介绍基于FPGA的图像双边滤波实现原理,包括双边滤波的数学模型、FPGA实现架构以及优化策略。

 

3.1 双边滤波数学模型

        双边滤波的输出像素值是由输入图像中对应像素及其邻域像素的加权平均得到的。每个像素的权重由两个高斯核的乘积决定:一个是空间高斯核,另一个是灰度值高斯核(或称为范围高斯核)。设输入图像为 (I),输出图像为 (O),对于任意像素 (p),其坐标为 ((x, y)),双边滤波后的值 (O_p) 可表示为:

7764b83454e07af3c7eddf6d7f3042e7_82780907_202402262325120463792621_Expires=1708961712&Signature=NtCd5FdTe2uoZ7Z1EEzRcYcLVOo%3D&domain=8.png

3.2 双边滤波的特性

边缘保持:双边滤波最显著的特点是能够在平滑图像的同时保持边缘的清晰度。这是由于灰度值高斯核的引入,使得在边缘区域,灰度值差异较大的像素获得较小的权重,从而保护了边缘信息。

 

参数敏感性:双边滤波的效果受到参数 (\sigma_s) 和 (\sigma_r) 的影响较大。增大 (\sigma_s) 会增加平滑程度,但可能导致边缘模糊;增大 (\sigma_r) 会提高对灰度值差异的敏感度,从而增强边缘保持效果,但也可能引入噪声。

 

计算复杂性:双边滤波的计算复杂度较高,因为它需要对每个像素的邻域内的所有像素进行权重计算和加权平均。这导致双边滤波在处理大图像时可能比较耗时。

 

噪声去除与细节保留:双边滤波在去除噪声的同时,能够保留图像的细节信息,如纹理和边缘。这使得它在许多图像处理应用中具有优势。

 

3.3 FPGA实现架构

基于FPGA的双边滤波实现主要包括以下几个模块:

 

图像缓存模块:用于存储输入图像数据,以便后续处理。

 

邻域像素获取模块:对于每个像素,计算其邻域像素的位置,并从图像缓存中读取对应像素的值。

 

高斯核计算模块:根据像素间的空间距离和灰度值差,计算空间高斯核和灰度值高斯核的值。

 

滤波计算模块:根据双边滤波的数学模型,计算每个像素的滤波输出值。

 

输出模块:将滤波后的图像数据输出到外部设备。

 

       在FPGA上实现双边滤波时,需要充分利用FPGA的并行处理能力。例如,可以采用流水线设计,使得每个像素的处理可以并行进行。此外,还可以通过优化存储访问模式,减少数据读取和写入的延迟。

 

        双边滤波作为一种非线性滤波方法,在图像处理领域具有广泛的应用前景。它通过结合空间高斯核和灰度值高斯核,实现了平滑图像和保持边缘的平衡。尽管双边滤波的计算复杂度较高,但其优异的边缘保持能力和细节保留特性使得它在许多应用中成为首选的滤波方法。随着计算机视觉和图像处理技术的不断发展,双边滤波将继续发挥重要作用,并在更多领域得到应用。

 

 

 

 

4.部分核心程序 ``timescale 1ns / 1ps

 

module test_image;

 

reg i_clk;

reg i_rst;

reg [7:0] image_buff [0:100000];

reg [7:0] II0;

wire [7:0] o_Ifilter;

 

integer fids,jj=0,dat;

 

//D:\FPGA_Proj\FPGAtest\codepz

 

initial

begin

        fids = $fopen("D:\FPGA_Proj\FPGAtest\codepz\data.bmp","rb");

        dat  = $fread(image_buff,fids);

        $fclose(fids);

end

 

initial

begin

i_clk=1;

i_rst=1;

#2000;

i_rst=0;

end

 

always #10  i_clk=~i_clk;

 

always@(posedge i_clk)

begin

        II0<=image_buff[jj];

        jj<=jj+1;

end

 

 

tops tops_u(

.i_clk              (i_clk),

.i_rst              (i_rst),

.i_I0               (II0),

.o_Ifilter          (o_Ifilter)

);

 

integer fout1;

initial begin

  fout1 = $fopen("o_Ifilter.txt","w");

end

 

always @ (posedge i_clk)

 begin

    if(jj<=66617)

        $fwrite(fout1,"%d\n",o_Ifilter);

        else

        $fwrite(fout1,"%d\n",0);

end

 

endmodule`