找回密码
 立即注册
搜索
查看: 958|回复: 0

FPGA设计中 Verilog HDL实现基本的图像滤波处理仿真

[复制链接]

271

主题

9

回帖

2万

积分

版主

Rank: 7Rank: 7Rank: 7

积分
23181
发表于 2023-6-7 14:32:27 | 显示全部楼层 |阅读模式
本帖最后由 眼镜一米二 于 2023-6-7 14:42 编辑

叁芯智能科技FPGA就业班06月开班中


      大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。


      今天给大侠带来FPGA设计中用Verilog HDL实现基本的图像滤波处理仿真,话不多说,上货。

1、用matlab代码,准备好把图片转化成Vivado Simulator识别的格式,即每行一个数据:




源码:

img = imread('E:\matlab\Images\2016-09-05-211710.jpg');        
         if size(img,3)==3           
         img = rgb2gray(img);        
         end        
         height = size(img, 1);        
         width = size(img, 2);        
         s = fopen('image2mem.txt','wb'); %opens the output file        
         cnt = 0;        
         for r=1:height               
              for c=1:width                        
                   cnt = cnt + 1;                        
                   grey=img(r,c);                        
                   greyb = dec2bin(grey,8);                        
                   Outbyte =greyb(1:8);



                   if (Outbyte(1:4) == '0000')fprintf(s,'0%X',bin2dec(Outbyte));                        
                   else fprintf(s,'%X',bin2dec(Outbyte));   end                        
                   if (mod(cnt,1) == 0)fprintf(s,'\r\n');   end               
               end        
         end        
         figure,imshow(img);        
         fclose(s);


2、EdgeSobel的Verilog源代码:



源码:
`timescale 1ns/1ps

module EdgeSobel(
           input clk,
           input [7:0] inData,
           input [11:0]x,
           input [11:0]y,
           output [7:0] outData
        );   
        
        parameter pixel_depth=8;
        parameter frame_width=640;
        parameter block_width=3;
        parameter block_height=3;

        parameter shiftRegSize=pixel_depth*((block_height-1)*frame_width+block_width);

        reg[shiftRegSize-1:0] shiftReg;
        wire [block_width*block_height*pixel_depth-1:0] Window;  

        initial begin shiftReg=10264'b0;end
        always@(posedge clk)if((x<640)&&(y<480))shiftReg<={shiftReg,inData};

        genvar i,j;
        generate
        for(i = 0; i < block_height; i = i + 1) begin : array
                for(j = 0; j < block_width; j = j + 1)
                begin : vector
                        assign Window[pixel_depth*(i * block_width + j)+:pixel_depth] =shiftReg[pixel_depth*(i*frame_width+j)+:pixel_depth];
                end
        end
        endgenerate

        wire [7:0] average;
        assign average =
           (Window[7:0]+Window[15:8]+Window[23:16]+
                //Window[31:24]+Window[39:32]+Window[47:40]+
                Window[31:24]+Window[39:32]+Window[47:40]+
                Window[55:48]+Window[63:56]+Window[71:64])/9 ;

        wire signed [pixel_depth+1:0] Gx;
        wire signed [pixel_depth+1:0] Gy;
        wire [pixel_depth+1:0] Gxabs;
        wire [pixel_depth+1:0] Gyabs;
        wire [pixel_depth+1:0] G;

        assign Gx =   shiftReg[pixel_depth*(0*frame_width+2)+:pixel_depth]
                                +2*shiftReg[pixel_depth*(1*frame_width+2)+:pixel_depth]
                                +  shiftReg[pixel_depth*(2*frame_width+2)+:pixel_depth]
                                -  shiftReg[pixel_depth*(0*frame_width+0)+:pixel_depth]
                                -2*shiftReg[pixel_depth*(1*frame_width+0)+:pixel_depth]
                                -  shiftReg[pixel_depth*(2*frame_width+0)+:pixel_depth];
                                
        assign Gy =   shiftReg[pixel_depth*(2*frame_width+0)+:pixel_depth]
                                +2*shiftReg[pixel_depth*(2*frame_width+1)+:pixel_depth]
                                +  shiftReg[pixel_depth*(2*frame_width+2)+:pixel_depth]
                                -  shiftReg[pixel_depth*(0*frame_width+0)+:pixel_depth]
                                -2*shiftReg[pixel_depth*(0*frame_width+1)+:pixel_depth]
                                -  shiftReg[pixel_depth*(0*frame_width+2)+:pixel_depth];   
                                
        assign Gxabs = (Gx>0)?Gx-Gx);
        assign Gyabs = (Gy>0)?Gy-Gy);
        assign G = Gxabs+Gyabs;

        //assign outData = average;    //平滑
        assign outData = G[9:2];     //边缘检测
        
endmodule

3、仿真文件:EdgeSobel_tb.v




源码:
`timescale 1ns / 1ps

module edgesobel_tb;

        reg clk;
        reg [7:0]  inData;
        reg [19:0] cnt;
        reg [9:0] row;
        wire [7:0] outData;
        reg [7:0] image [307199:0];
        integer file_id;
        reg [4:0] frame_cnt;

        initial
        begin
                $readmemh("E:/matlab/Vivado/image2mem.txt", image);
                file_id = $fopen("E:/matlab/Vivado/mem2image.txt","w");
                clk = 0;
                cnt = 0;
                row = 0;
                frame_cnt = 0;
        end

        EdgeSobel u_2
                        (
                        .clk(clk),
                        .x(1),
                        .y(1),
                        .inData(inData),
                        .outData(outData)
                        );

        always #1 clk = ~clk;

        always@(posedge clk)
        begin
                if(cnt == 307200)   
                        begin
                                cnt = 0;
                                row = 0;
                                frame_cnt = frame_cnt + 1;
                        end   
                else
                        inData = image[cnt];
                        cnt = cnt+1;
                        if(frame_cnt==1)
                                begin
                                        $fwrite(file_id, "%d ", outData);
                                        if(((cnt % 640)==0) &&(cnt>0))
                                                begin
                                                        $fwrite(file_id,"\r\n");
                                                        row = row + 1;
                                                end;
                                end
        end
        
endmodule

4、把输出的txt文件转化成图片Matlab程序:

A=importdata('E:\matlab\Vivado\mem2image.txt');

A=A./255;

imshow(A);


注意这里的A是double类型的,直接进行imshow会全白,要转化到0-1:A=A./255,或者把double类型转化为整形。


后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。
大侠们,江湖偌大,继续闯荡,愿一切安好,有缘再见!


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|冀ICP备20011060号-2|叁芯智能

GMT+8, 2024-4-29 06:03 , Processed in 0.043117 second(s), 20 queries .

Powered by Discuz! X3.4

© 2017-2018

快速回复 返回顶部 返回列表