基于FPGA的中值滤波设计————(1)图片数据TXT读写

        书接上回http://t.csdn.cn/Q1zZThttp://t.csdn.cn/Q1zZT       其中讲述的是matlab将彩色图像数据读写到TXT当中。

        这部分主要是关于FPGA设计的内容,为了方便理解所以单独成为一个系列。在本文这一章主要讲解FPGA对图像数据读写。在后面会陆续讲解中值滤波,小伙伴们别急,一口是吃不成大佬的。

一、明确图像存储在txt当中的格式        

        首先我们来复习一下,前面我们不是说到,利用matlab将彩色图像数据以16进制写入到txt当中,且写入的形式如下:

         这里的0x11是图层1的第一个数,往下0x02依次为图层1的第二个数;

        0x2a是图层2的第一个数,往下0x2b依次为图层2的第二个数;

         0x2f是图层3的第一个数,往下0x20依次为图层3的第二个数;

        TXT中数的深度就是图层的大小row*col,数的宽度就是三个像素,每个像素点8bit,总共24bit,例如这里的第一个数112a2f,就是24bit的位宽

二、FPGA读写txt文件

        接下来我们就利用verilog将txt文件里的数据读到FPGA当中,FPGA当中数据处理完后,再将数据写入txt当中。整体的数据流程框图如下:

  主要是通过激励文件的里的函数调用来读写图像数据,然后将数据输入到mid_top(中值滤波顶层模块)进行处理。

1)读txt数据

        为了方便讲解,我就先将我自己的tb(test benches,测试激励)文件读写拆分,直接上代码

`timescale 1ns/1ps
parameter picture_size = 71200 ;
integer fp_r;
reg rst_n;
reg clk;
reg [23:0] data_in;
reg [31:0] count;

initial
begin

    fp_r=$fopen("*/*/*.txt","r");//以读的方式打开*.txt文件
    rst_n=1'b0;
    clk=1'b0;
    #20
    rst_n=1'b1;
    #63000
    $stop;
end
initial
    forever
         #5 clk=!clk;

always@(posedge clk)
begin
     if(!rst_n)
        begin
            data_in<=24'd0;
            count<=0;
        end
     else if(count<=picture_size)
            begin
                $fscanf(fp_r,"%h\n",data_in);//每次读一行
                count<=count+1'b1;
            end
    else
        begin
            $fclose(fp_r)'//关闭已打开的文件
        end
       
end

        先仔细的讲解一下,后面遇到相同的就不做解释了,首先

`timescale 1ns/1ps

        代表的是对仿真时间规定,这里就是单位ns精度ps,比如后面initial部分里面的#20、#5等代表的就是20ns和5ns。

        然后是常量定义:

parameter picture_size = 71200 ;

        这里的picture_size大小可以根据大家自己的图层大小定义,比如我的图层大小就是356*200=71200;定义这个常量就是为了把txt里面的所有图像数据通过计数的方式一个一个读出来。

        接下来就是五个寄存器:

integer fp_r;
reg rst_n;
reg clk;
reg [23:0] data_in;
reg [31:0] count;

        位宽分别为32、1、1、24、32,没错是五个,integer形式的定义也是寄存器只不过是整型的有符号,规定为32位且这个位宽不可更改,而reg定义的是无符号的寄存器,位宽可设置,不设置时默认位1bit。

        然后是运用$fopen函数打开想要读的文件夹:

initial
begin

    fp_r=$fopen("*/*/*.txt","r");//以读的方式打开*.txt文件
    rst_n=1'b0;
    clk=1'b0;
    #20
    rst_n=1'b1;
    #63000
    $stop;
end

        在这里的("*/*/*.txt")大家可以根据自己的TXT文件所在目录和文件名进行更改,且注意斜杠“”“/”和文件目录的斜杠“\”是不一样的。利用$fopen函数把文件以读的方式打开,存储在了fp_r当中。然后定义了复位rst_n、时钟clk的初始值0,#20ns 过后复位rst_n变为1启动程序,再过#63000ns停止激励仿真程序,63000的停止时间也可以修改。

        接着就是时钟脉冲的翻转设置:

initial
    forever
         #5 clk=!clk;

        时钟脉冲初始值在上面设置了是0,然后每隔5ns翻转一次,在0和1之间有周期性的变换,就形成了时钟脉冲。

        最后是利用$fscanf函数通过时钟驱动寄存器输出TXT每一行的24bit数据:

always@(posedge clk)
begin
     if(!rst_n)
        begin
            data_in<=24'd0;
            count<=0;
        end
     else if(count<=picture_size)
            begin
                $fscanf(fp_r,"%h\n",data_in);//每次读一行
                count<=count+1'b1;
            end
    else
        begin
            $fclose(fp_r)'//关闭已打开的文件
        end
       
end

        当计数器count计数到picture_size常量也就是图层大小时候通过$fclose关闭打开的txt文件。这里需要注意的是,读的时候是以"%h\n"也就是16进制的方式读数据,一个时钟读一行,因为我们写进去的是16进制形式,记住写入TXT是什么数据形式(是h还是d等),读的时候也需要更改相应的形式。

        总结一下,上面的一系列代码实现的功能,主要就是将*.txt的图像数据通过一个一个clk时钟周期读入到data_in当中存储和输出data_in就可以通过实例化输出到mid_top当中做中值滤波处理

2)将处理后的数据写入txt

         这部分的写代码就和读数据的代码高度相似了,直接上代码:

`timescale 1ns/1ps
parameter picture_size = 71200 ;
integer fp_w;
reg rst_n;
reg clk;
reg [31:0] count_out;

wire [23:0] data_out;
wire flag;

initial
begin

    fp_w=$fopen("*/*/*.txt","w");//以写的方式打开*.txt文件
    rst_n=1'b0;
    clk=1'b0;
    #20
    rst_n=1'b1;
    #63000
    $stop;
end
initial
    forever
         #5 clk=!clk;

always@(posedge clk)
begin
     if(!rst_n)
        begin
            count_out<=0;
        end
     else if((count_out<=picture_size-1)&flag)
            begin
                $fwrite(fp_w,"%h\n",data_out);//每次写一行
                count_out<=count_out+1'b1;
            end
    else if(count_out==picture_size)
        begin
            $fclose(fp_w)'//关闭已打开的文件
        end
       
end

        讲一下跟读数据不同的地方,第一处就是加入了两个wire型的数据:

wire [23:0] data_out;
wire flag;

        这两个信号就来自mid_top模块,data_out代表是图像处理后的像素数据,flag代表data_out数据的有效性,通俗的说就是告诉别的模块,我这个模块(mid_top)像素中值滤波滤完成了一个像素,你把这个像素拿去做其他处理吧。

        然后第二处就是以写"w"的方式打开一个*.txt,并将它放入fp_w里,如果指定的目录里没有这个txt,它会新建一个。

        最后不同的地方就是always功能块里面的:

always@(posedge clk)
begin
     if(!rst_n)
        begin
            count_out<=0;
        end
     else if((count_out<=picuture_size-1)&flag)
            begin
                $fwrite(fp_w,"%h\n",data_out);//每次写一行
                count_out<=count_out+1'b1;
            end
    else if(count_out==picture_size)
        begin
            $fclose(fp_w)'//关闭已打开的文件
        end
       
end

        意思其实也很简单,当falg信号有效就是为1的时候且count_out计数小于图层大小时,开始利用$fwrite函数将data_out数据一个一个的写入txt当中,当写完了所有像素也就是count_out=picture_size之后,就关闭打开的文件,停止写。

3)仿真测试

来看看实际的仿真结果:

         主要看data_in数据读出是没有问题的跟之前数据存入txt(看本文的第一张图)是一样的,证明我们的操作没有问题,很成功。

        在我的仿真激励中数据的写入TXT需要把仿真往后运行:

        先不分析数据处理的正确性,只看写数据这个操作,我们可以大致看一下数据写出是没问题的,写出生成的TXT如下:

 对了这里的TXT我都是用MATLAB打开看的,所以前面有12345678这些前缀。

三、总结

        基本上将前面的读写方式学会后,图像数据写入就可以通过data_in接到自己想要的模块去使用,想要知道处理后的结果就可以将data_out接出来交给matlab等软件去验证和分析效果。如果需要同时读写,只需要将我上面的代码稍加修改,去掉重复的部分就可以了。

        其实还有其他的方式能将数据输入到FPGA当中,我这里再提及一下这个方案,就是通过之前我有讲到的利用MATLAB生成.mif文件或者.coe文件,然后调用FPGA的rom核,再通过rom读出这些数据,也是可以这样操作的,操作没有什么难度,这里就不深入的探究了。

        每天一点新知识,打工人奥利给!

  • 11
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于FPGA的腐蚀膨胀算法和中值滤波是数字图像处理中的常用算法,可以在图像处理中应用。下面分别介绍这两种算法的基本原理和FPGA实现方法。 1. 腐蚀膨胀算法 腐蚀和膨胀是形态学图像处理中常用的两种操作,可以用来分割图像、提取特征等。腐蚀是指将图像中的物体边缘腐蚀掉,而膨胀则是将物体边缘扩张。FPGA实现腐蚀膨胀算法的方法一般包括以下步骤: (1)图像二值化:将图像转换为二值图像,即将图像中的像素值二值化为0或1。 (2)结构元素选择:选择一个结构元素,通常为矩形或十字形,用于对图像进行腐蚀或膨胀操作。 (3)腐蚀或膨胀操作:对二值图像和结构元素进行腐蚀或膨胀操作,得到处理后的图像。 (4)输出处理结果:将处理后的图像输出。 2. 中值滤波 中值滤波是一种常用的滤波算法,可以用来去除图像中的噪声。其基本原理是将图像中每个像素的灰度值替换为该像素周围一定范围内的像素灰度值的中值。FPGA实现中值滤波算法的方法一般包括以下步骤: (1)图像灰度化:将图像转换为灰度图像。 (2)滤波窗口选择:选择一个滤波窗口,通常为正方形或矩形,用于对图像进行滤波操作。 (3)中值滤波操作:对每个像素及其周围的像素进行排序,取中间的值作为该像素的灰度值,得到处理后的图像。 (4)输出处理结果:将处理后的图像输出。 总之,基于FPGA的腐蚀膨胀算法和中值滤波是数字图像处理中常用的算法,可以在FPGA中实现加速处理,提高图像处理的效率和速度。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值