可编程逻辑
今天给大侠带来FPGA设计中用Verilog HDL实现基本的图像滤波处理仿真,话不多说,上货。 1、用matlab代码,准备好把图片转化成Vivado Simulator识别的格式,即每行一个数据:
代码:
img = imread('E:matlabImages2016-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,' '); 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," "); row = row + 1; end; end end endmodule
4、把输出的txt文件转化成图片Matlab程序:
A=importdata('E:matlabVivadomem2image.txt'); A=A./255; imshow(A);
注意这里的A是double类型的,直接进行imshow会全白,要转化到0-1:A=A./255,或者把double类型转化为整形。
审核编辑:黄飞
全部0条评论
快来发表一下你的评论吧 !