基于FPGA的中值滤波设计————(4)矩阵求取中值算法模块

这篇具有很好参考价值的文章主要介绍了基于FPGA的中值滤波设计————(4)矩阵求取中值算法模块。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、功能原理描述

        前面我们成功找到了3x3的矩阵模板c1~c9,在这一章我们接着需要实现的是midfilter模块,其功能就是通过比较的方式寻找矩阵的中值,用它来代替图像的每一个像素点。如何寻找矩阵的中值呢?分为三步:

        第一步:将矩阵的三行的每一行都按照{大、中、小}的位置顺序排序;

        第二步:比较矩阵第一列3个数的大小,取出最小值;比较第二列的大小取出中值,比较第三列的大小取出最大值;

        第三步:将第二步取出的大、中、小三个值作比较,比较出中值即为我们寻找的矩阵的中值。

二、端口描述和设计

        老规矩看图:

3*3矩阵怎么找中值,FPGA开发,中值滤波,fpga开发,矩阵,算法,图像处理

输入信号:输入的信号都比较熟悉了,c1~c9是矩阵数据,全局信号clk、rst_n,以及前一个模块的完成标志信号mid3x3_done

输出信号:输出的信号data_out[23:0]代表计算出的当前矩阵的中值,flag代表着矩阵的中值求取完成,通知前面的模块可以获取下一个矩阵了。

        通过Verilog设计的端口常量如下:

module midfilter#(

    parameter picture_size =71200,
               data_width   =24
)(
    input clk,rst_n,
    input mid3x3_done,   
    input [data_width-1:0] c1,c2,c3,c4,c5,c6,c7,c8,c9,模板矩阵
    
    output reg flag,
    output [data_width-1:0]data_out  ///滤波后输出数据
    );

三、逻辑功能设计

         在开始的时候,我们需要明确的是输入的矩阵数据位宽为24bit,表示了我们输入的其实是一个三层的3x3矩阵。逻辑功能设计可以分为三部分代码段:图层分离、中值求取、标志生成

        首先是图层分离,通过内部线型wire的定义如下:

    wire [7:0] A    [8:0];//第一图层矩阵
    wire [7:0] B    [8:0];//第二图层矩阵
    wire [7:0] C    [8:0];//第三图层矩阵
    
    wire [7:0] A_sort    [8:0];//大小排序后第一图层矩阵
    wire [7:0] B_sort    [8:0];//大小排序后第二图层矩阵
    wire [7:0] C_sort    [8:0];//大小排序后第三图层矩阵
    
    wire [7:0] A_min          ;//第一层模板第一列最小值
    wire [7:0] B_min          ;//第二层模板第一列最小值
    wire [7:0] C_min          ;//第三层模板第一列最小值
    
    wire [7:0] A_mid          ;//第一层模板第二列中间值
    wire [7:0] B_mid          ;//第二层模板第二列中间值
    wire [7:0] C_mid          ;//第三层模板第二列中间值
    
    wire [7:0] A_max          ;//第一层模板第三列最大值
    wire [7:0] B_max          ;//第二层模板第三列最大值
    wire [7:0] C_max          ;//第三层模板第三列最大值        
    
    wire [data_width-1:0]mid_data;//输出中间值
/*************************转换为矩阵*************************//   
assign A[0]= c1[7:0];   
assign A[1]= c2[7:0]; 
assign A[2]= c3[7:0]; 
assign A[3]= c4[7:0]; 
assign A[4]= c5[7:0]; 
assign A[5]= c6[7:0]; 
assign A[6]= c7[7:0]; 
assign A[7]= c8[7:0]; 
assign A[8]= c9[7:0];

assign B[0]= c1[15:8];   
assign B[1]= c2[15:8]; 
assign B[2]= c3[15:8]; 
assign B[3]= c4[15:8]; 
assign B[4]= c5[15:8]; 
assign B[5]= c6[15:8]; 
assign B[6]= c7[15:8]; 
assign B[7]= c8[15:8]; 
assign B[8]= c9[15:8]; 

assign C[0]= c1[23:16];   
assign C[1]= c2[23:16]; 
assign C[2]= c3[23:16]; 
assign C[3]= c4[23:16]; 
assign C[4]= c5[23:16]; 
assign C[5]= c6[23:16]; 
assign C[6]= c7[23:16]; 
assign C[7]= c8[23:16]; 
assign C[8]= c9[23:16]; 

        每个内部连线的定义后面都有注释就不做解释了,需要讲一下的是assign这里就是将我们的三层图层的矩阵分A、B、C存放,后面每一层的算法处理方式是一模一样的直接复用就行了。

        接下来就是中值求取:midfilter模块的核心:如何比较三个数的大小?当比较过后我们就能轻易的对这三个数据进行排序和找出后面需要的最大值、最小值、中值

        具体的比较模块的verilog实现程序如下:

module sort_data(
    input clk ,rst_n,
    
    input [7:0] a,b,c,
    output reg [23:0] data_out{大,中,小}
    );
   wire  A,B,C; 
   wire  [2:0] state;
    assign A=(a>b)?1:0;
    assign B=(b>c)?1:0;
    assign C=(c>a)?1:0;
    assign   state={A,B,C};
  
always@(posedge clk)
    if(!rst_n)
    begin
       data_out<=24'b0;
     end
       else case(state)
                3'b110:begin  data_out<={a,b,c};  end
                3'b100:begin  data_out<={a,c,b};  end   
                3'b010:begin  data_out<={b,a,c};  end
                3'b011:begin  data_out<={b,c,a};  end
                3'b101:begin  data_out<={c,a,b};  end
                3'b001:begin  data_out<={c,b,a};  end              
              default: begin data_out<={a,b,c}; end 
             endcase
endmodule

        这个例程十分的简单,直接根据组合逻辑将输入的三个数中的两个两两比较,然后映射成3bit数据的某一bit,再根据这个3bit数据的数值唯一性利用简单的状态机输出大小顺序。

        举个例子,如果输入的三个数:b>c>a,那么通过assign实现的三态门,计算出的state的二进制值就等于011,然后根据状态机3‘b011的输出data_out={b,c,a},默认顺序是大中小,结果表示没有问题。依次类推当我们要求取最大值时,只需要将这里的b值给到data_out,要求取中值时,只需要将这里的c值给到输出data_out,包括最小值的求取都可以这样操作。

        所以通过简单的修改例化,就可以完成我们第一节当中所说的求中值的三步:

/*************************处理第一图层*************************//
//模板每一行为单位排序 
   
genvar i;
generate
  for(i=0;i<=2;i=i+1)
    begin:Asort
        sort_data A_array(
        .clk(clk),
        .rst_n(rst_n),
        
        .a(A[0+i*3]),
        .b(A[1+i*3]),
        .c(A[2+i*3]),
        .data_out({A_sort[0+i*3],A_sort[1+i*3],A_sort[2+i*3]})/{大,中,小}
        ); 
    end
endgenerate
//排序后取第一列最小值   
min_data A1(
    .clk(clk),
    .rst_n(rst_n),
    
    .a(A_sort[0]),
    .b(A_sort[3]),
    .c(A_sort[6]),
    .data_out(A_min)
    ); 
 //排序后取第二列中间值   
mid_data A2(
    .clk(clk),
    .rst_n(rst_n),
    
    .a(A_sort[1]),
    .b(A_sort[4]),
    .c(A_sort[7]),
    .data_out(A_mid)
    );      
//排序后取第三列最大值   
max_data A3(
    .clk(clk),
    .rst_n(rst_n),
    
    .a(A_sort[2]),
    .b(A_sort[5]),
    .c(A_sort[8]),
    .data_out(A_max)
    );  
//排序后取中间值输出 
mid_data A4(
    .clk(clk),
    .rst_n(rst_n),
    
    .a(A_min),
    .b(A_mid),
    .c(A_max),
    .data_out(mid_data[7:0])
    ); 

        首先复用sort_data模块对第一个图层的A矩阵的三行进行排序,然后利用min_data、mid_data、max_data三个模块分别求取排序过后矩阵的第一列的最小值、第二列的中值、第三列的最大值,最后将求取三个值的中值。

        剩下的两个图层只需要将这里的A矩阵改成B、C矩阵复用操作即可。

        最后一部分程序就是标志生成:主要是通过计数的方式完成功能

 /*****************判定模板生成然后计数等待找中值完成********************  
  reg [1:0]cnt;   
 reg [2:0] state;
 reg [data_width-1:0]data_out_reg; 
always@(posedge clk)
begin
    if(!rst_n)
        begin
            flag<=0;
            cnt<=0;
            state<=0;
            data_out_reg<=0;
        end
       else case(state)
                0:begin 
                        flag<=0; 
                        if(mid3x3_done) begin state<=1;cnt<=0;end
                        else begin state<=0;  data_out_reg<=data_out_reg;end 
                  end
                1:begin  if(cnt==2)begin cnt<=0; state<=2;flag<=1; data_out_reg<=mid_data;end 
                         else begin cnt<=cnt+1; state<=1;end 
                  end
                2:begin
                    flag<=0; 
                    data_out_reg<=data_out_reg;
                    state<=0;
                   end            
                default: state<=0;
            endcase 
end

        实现的功能作用就是当mid3x3_done标志信号来之后开始对计数器cnt进行计数,计数到什么时候呢?需要计数到中值data_out求取完成,大概就是三个时钟周期也就是当cnt=2的时候产生一个中值完成标志,将flag拉高。

四、总结

        到这里基于FPGA的中值滤波的所有模块都设计实现完了,整体的难度都在中等偏下范围,但对于新入门的伙伴们来说应该还是十分的有用。整个的工程和所有的.v文件目前还没有找到较好的方式上传,大家如果需要的话可以留言。文章来源地址https://www.toymoban.com/news/detail-679770.html

到了这里,关于基于FPGA的中值滤波设计————(4)矩阵求取中值算法模块的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 中值滤波算法及例程

    中值滤波是一种常用的非线性图像滤波算法,它能够有效去除图像中的椒盐噪声(即孤立的亮或暗像素点),同时保持图像边缘和细节的清晰度。中值滤波的主要思想是使用一个滑动窗口,在窗口内对像素值进行排序,并将排序后的中间值作为中心像素的新值。 以下是中值滤

    2024年02月07日
    浏览(53)
  • 算法 | 数字图像处理之「中值滤波」

    中值滤波就是用一个奇数点的移动窗口(要求奇数主要是为了保证整个模板有唯一中心元素),将窗口中心点的值用窗口内各点的中值代替。假设窗口内有5点,其值为80、90、200、110和120,那么此窗口内各点的中值即为110。 设有一个一维序列 (f_1,f_2,...,f_n) ,取窗口长度(点

    2023年04月13日
    浏览(36)
  • 基于FPGA的FFT图像滤波设计

            FFT滤波就是通过傅里叶运算将图像转换到频域空间,然后在频域中对图像进行处理,最后将处理后的图像通过傅里叶逆运算将图像转会到时域空间。   在频域空间中,我们能够更好的对图像的噪声进行分析,然后找出相关规律将噪声信息去除。    本文重点讲解

    2024年04月17日
    浏览(47)
  • 图像处理:推导五种滤波算法(均值、中值、高斯、双边、引导)

    目录 概论 算法原理 1、均值滤波 2、中值滤波 3、高斯滤波 4、双边滤波 5、引导滤波  手写代码 Opencv代码实现  最后的总结 参考文章         本来打算是分开推导的,但我觉得还是整个合集吧,避免有水文的嫌疑,那么因为学习的需要,会涉及到图像的滤波处理,我汇总

    2024年02月07日
    浏览(48)
  • 基于MATLAB对彩色图像去噪的代码,均值滤波,中值滤波,空域低通滤波。

    本文主要为代码展示,未对所用算法进行较为详细的文字介绍,请读者见谅。如有建议,欢迎私信。   MATLAB调用格式为: J=imnoise(I,type)或者J=imnoise(I,type,parameters)。将类型噪声添加到灰度图像。 其中,I为原始图像,J为有噪图像,参数type和parameters用于确定噪声类型和相应的参

    2024年02月06日
    浏览(50)
  • 基于FPGA的RC滤波器设计实现

    目录 简介: 传递函数 FPGA代码实现 总结 RC滤波器的特性基本情况介绍 RC一阶低通滤波介绍;RC滤波器电路简单,抗干扰性强,有较好的低频性能,并且选用标准的阻容元件易得,所以在工程测试的领域中最经常用到的滤波器是RC滤波器。 这里我们主要认识和介绍低通滤波器。

    2024年02月16日
    浏览(39)
  • OpenCV-AMF算法(自适应中值滤波Adaptive Median Filtering)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处        AMF(Adaptive Median Filter,自适应中值滤波)是一种用于图像处理和信号处理的滤波算法,其目的是在保持图像细节的同时去除噪声。它是基于中值滤波的一种改进

    2024年04月25日
    浏览(32)
  • 【OpenCV-Python】:基于均值、中值、方框、双边和高斯滤波的图像去噪

    ✨博客主页:王乐予🎈 ✨年轻人要:Living for the moment(活在当下)!💪 🏆推荐专栏:【图像处理】【千锤百炼Python】【深度学习】【排序算法】 本节将对经过噪声污染的图像进行去噪,去噪方法包含 均值滤波、中值滤波、方框滤波、双边滤波和高斯滤波 。 实验所用的图

    2024年02月05日
    浏览(67)
  • m基于FPGA的积分梳状CIC滤波器verilog设计

    目录 1.算法描述 2.仿真效果预览 3.verilog核心程序 4.完整FPGA 积分梳状滤波器,是指该滤波器的冲激响应具有如下形式: 其物理框图如图所示: 可见,CIC滤波器是由两部分组成:累积器H1和H2梳状滤波器的级联。        现若假设用N级CIC滤波器来代替,每一级的滤波器系数长度

    2024年02月14日
    浏览(33)
  • 【C++】【图像处理】均值滤波 and 高斯滤波 and 中值滤波(低通滤波)算法解析(以.raw格式的图像为基础进行图像处理、gray levels:256)

     中值滤波: 中值滤波中的MidValueFind函数的实现就是冒泡排序,最后去中间值返回:  Soble算子边缘提取:     总结: 1、均值、高斯滤波和Sobel算子边缘提取的核心,创建卷积核并确定各个点上的权重,然后将边缘灰度级归零(是否边缘归零按业务需求决定),提取非边缘像

    2024年02月05日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包